Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
CheckboxBuilder
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 11
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setInputId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setName
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setLabel
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setValue
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setChecked
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setDisabled
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setInline
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setInputAttributes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setWrapperAttributes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 build
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * CheckboxBuilder.php
4 *
5 * This file is part of the Codex design system, the official design system
6 * for Wikimedia projects. It provides the `Checkbox` class, a builder for constructing
7 * checkbox components using the Codex design system.
8 *
9 * A Checkbox is a binary input that can appear by itself or in a multiselect group.
10 * Checkboxes can be selected, unselected, or in an indeterminate state.
11 *
12 * @category Builder
13 * @package  Codex\Builder
14 * @since    0.1.0
15 * @author   Doğu Abaris <abaris@null.net>
16 * @license  https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
17 * @link     https://doc.wikimedia.org/codex/main/ Codex Documentation
18 */
19
20namespace Wikimedia\Codex\Builder;
21
22use InvalidArgumentException;
23use Wikimedia\Codex\Component\Checkbox;
24use Wikimedia\Codex\Component\Label;
25use Wikimedia\Codex\Renderer\CheckboxRenderer;
26
27/**
28 * CheckboxBuilder
29 *
30 * This class implements the builder pattern to construct instances of Checkbox.
31 * It provides a fluent interface for setting various properties and building the
32 * final immutable object with predefined configurations and immutability.
33 *
34 * @category Builder
35 * @package  Codex\Builder
36 * @since    0.1.0
37 * @author   Doğu Abaris <abaris@null.net>
38 * @license  https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
39 * @link     https://doc.wikimedia.org/codex/main/ Codex Documentation
40 */
41class CheckboxBuilder {
42
43    /**
44     * The ID for the checkbox input.
45     */
46    protected string $inputId = '';
47
48    /**
49     * The name attribute for the checkbox input.
50     */
51    protected string $name = '';
52
53    /**
54     * The label object for the checkbox.
55     */
56    protected ?Label $label = null;
57
58    /**
59     * The value associated with the checkbox input.
60     */
61    protected string $value = '';
62
63    /**
64     * Indicates if the checkbox is selected by default.
65     */
66    protected bool $checked = false;
67
68    /**
69     * Indicates if the checkbox is disabled.
70     */
71    protected bool $disabled = false;
72
73    /**
74     * Indicates if the checkbox should be displayed inline.
75     */
76    protected bool $inline = false;
77
78    /**
79     * Additional HTML attributes for the input.
80     */
81    private array $inputAttributes = [];
82
83    /**
84     * Additional attributes for the wrapper element.
85     */
86    private array $wrapperAttributes = [];
87
88    /**
89     * The renderer instance used to render the checkbox.
90     */
91    protected CheckboxRenderer $renderer;
92
93    /**
94     * Constructor for the CheckboxBuilder class.
95     *
96     * @param CheckboxRenderer $renderer The renderer to use for rendering the checkbox.
97     */
98    public function __construct( CheckboxRenderer $renderer ) {
99        $this->renderer = $renderer;
100    }
101
102    /**
103     * Set the ID for the checkbox input.
104     *
105     * The ID is a unique identifier for the checkbox input element. It is used to associate the input
106     * with its corresponding label and for any JavaScript or CSS targeting.
107     *
108     * @since 0.1.0
109     * @param string $inputId The ID for the checkbox input.
110     * @return $this Returns the Checkbox instance for method chaining.
111     */
112    public function setInputId( string $inputId ): self {
113        $this->inputId = $inputId;
114
115        return $this;
116    }
117
118    /**
119     * Set the name for the checkbox input.
120     *
121     * The name attribute is used to identify form data after the form is submitted. It is crucial when
122     * handling multiple checkboxes as part of a group or when submitting form data via POST or GET requests.
123     *
124     * @since 0.1.0
125     * @param string $name The name attribute for the checkbox input.
126     * @return $this Returns the Checkbox instance for method chaining.
127     */
128    public function setName( string $name ): self {
129        $this->name = $name;
130
131        return $this;
132    }
133
134    /**
135     * Set the label for the checkbox input.
136     *
137     * This method accepts a Label object which provides a descriptive label for the checkbox.
138     *
139     * @since 0.1.0
140     * @param Label $label The Label object for the checkbox.
141     * @return $this Returns the Checkbox instance for method chaining.
142     */
143    public function setLabel( Label $label ): self {
144        $this->label = $label;
145
146        return $this;
147    }
148
149    /**
150     * Set the value for the checkbox input.
151     *
152     * The value is the data that is submitted when the checkbox is checked and the form is submitted.
153     * This is particularly important when dealing with groups of checkboxes where each needs a distinct value.
154     *
155     * @since 0.1.0
156     * @param string $value The value for the checkbox input.
157     * @return $this Returns the Checkbox instance for method chaining.
158     */
159    public function setValue( string $value ): self {
160        $this->value = $value;
161
162        return $this;
163    }
164
165    /**
166     * Set whether the checkbox should be checked.
167     *
168     * This method determines whether the checkbox is selected by default. If set to `true`,
169     * the checkbox will be rendered in a checked state, otherwise, it will be unchecked.
170     *
171     * @since 0.1.0
172     * @param bool $checked Whether the checkbox should be checked.
173     * @return $this Returns the Checkbox instance for method chaining.
174     */
175    public function setChecked( bool $checked ): self {
176        $this->checked = $checked;
177
178        return $this;
179    }
180
181    /**
182     * Set whether the checkbox should be disabled.
183     *
184     * This method determines whether the checkbox is disabled, preventing user interaction.
185     * A disabled checkbox cannot be checked or unchecked by the user and is typically styled to appear inactive.
186     *
187     * @since 0.1.0
188     * @param bool $disabled Whether the checkbox should be disabled.
189     * @return $this Returns the Checkbox instance for method chaining.
190     */
191    public function setDisabled( bool $disabled ): self {
192        $this->disabled = $disabled;
193
194        return $this;
195    }
196
197    /**
198     * Set whether the checkbox should display inline.
199     *
200     * This method determines whether the checkbox and its label should be displayed inline with other elements.
201     * Inline checkboxes are typically used when multiple checkboxes need to appear on the same line.
202     *
203     * @since 0.1.0
204     * @param bool $inline Indicates whether the checkbox should be displayed inline.
205     * @return $this Returns the Checkbox instance for method chaining.
206     */
207    public function setInline( bool $inline ): self {
208        $this->inline = $inline;
209
210        return $this;
211    }
212
213    /**
214     * Set additional HTML attributes for the root checkbox input.
215     *
216     * This method allows custom HTML attributes to be added to the checkbox element, such as `id`, `data-*`, `aria-*`,
217     * or any other valid attributes. These attributes can be used to integrate the checkbox with JavaScript, enhance
218     * accessibility, or provide additional metadata.
219     *
220     * The values of these attributes are automatically escaped to prevent XSS vulnerabilities.
221     *
222     * @since 0.1.0
223     * @param array $inputAttributes An associative array of HTML attributes for the input element.
224     * @return $this Returns the Checkbox instance for method chaining.
225     */
226    public function setInputAttributes( array $inputAttributes ): self {
227        foreach ( $inputAttributes as $key => $value ) {
228            $this->inputAttributes[$key] = $value;
229        }
230
231        return $this;
232    }
233
234    /**
235     * Set additional HTML attributes for the outer wrapper element.
236     *
237     * This method allows custom HTML attributes to be added to the outer wrapper element,
238     * enhancing its behavior or styling.
239     *
240     * Example usage:
241     *
242     *     $textInput->setWrapperAttributes(['id' => 'custom-wrapper']);
243     *
244     * @since 0.1.0
245     * @param array $wrapperAttributes An associative array of HTML attributes for the wrapper element.
246     * @return $this Returns the Checkbox instance for method chaining.
247     */
248    public function setWrapperAttributes( array $wrapperAttributes ): self {
249        foreach ( $wrapperAttributes as $key => $value ) {
250            $this->wrapperAttributes[$key] = $value;
251        }
252
253        return $this;
254    }
255
256    /**
257     * Build and return the Checkbox component object.
258     * This method constructs the immutable Checkbox object with all the properties set via the builder.
259     *
260     * @since 0.1.0
261     * @return Checkbox The constructed Checkbox.
262     */
263    public function build(): Checkbox {
264        if ( !$this->inputId ) {
265            throw new InvalidArgumentException( "The 'id' is required for Checkbox." );
266        }
267        if ( !$this->label ) {
268            throw new InvalidArgumentException( "The 'label' is required for Checkbox." );
269        }
270
271        return new Checkbox(
272            $this->inputId,
273            $this->name,
274            $this->label,
275            $this->value,
276            $this->checked,
277            $this->disabled,
278            $this->inline,
279            $this->inputAttributes,
280            $this->wrapperAttributes,
281            $this->renderer,
282        );
283    }
284}