Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
30.67% covered (danger)
30.67%
23 / 75
12.50% covered (danger)
12.50%
1 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
HTMLCheckField
31.08% covered (danger)
31.08%
23 / 74
12.50% covered (danger)
12.50%
1 / 8
212.55
0.00% covered (danger)
0.00%
0 / 1
 getInputHTML
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
30
 getInputOOUI
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 getInputCodex
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
4
 getLabel
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 getLabelAlignOOUI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 needsLabel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDefault
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 loadDataFromRequest
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace MediaWiki\HTMLForm\Field;
4
5use MediaWiki\Html\Html;
6use MediaWiki\HTMLForm\HTMLForm;
7use MediaWiki\HTMLForm\HTMLFormField;
8use MediaWiki\HTMLForm\OOUIHTMLForm;
9use MediaWiki\HTMLForm\VFormHTMLForm;
10use MediaWiki\Request\WebRequest;
11use Xml;
12
13/**
14 * A checkbox field
15 *
16 * @stable to extend
17 */
18class HTMLCheckField extends HTMLFormField {
19
20    /**
21     * @inheritDoc
22     * @stable to override
23     */
24    public function getInputHTML( $value ) {
25        if ( !empty( $this->mParams['invert'] ) ) {
26            $value = !$value;
27        }
28
29        $attr = $this->getTooltipAndAccessKey();
30        $attr['id'] = $this->mID;
31
32        $attr += $this->getAttributes( [ 'disabled', 'tabindex' ] );
33
34        if ( $this->mClass !== '' ) {
35            $attr['class'] = $this->mClass;
36        }
37
38        $attrLabel = [ 'for' => $this->mID ];
39        if ( isset( $attr['title'] ) ) {
40            // propagate tooltip to label
41            $attrLabel['title'] = $attr['title'];
42        }
43
44        $isVForm = $this->mParent instanceof VFormHTMLForm;
45
46        $chkDivider = "\u{00A0}";
47        $chkLabel = Xml::check( $this->mName, $value, $attr ) .
48            $chkDivider .
49            Html::rawElement( 'label', $attrLabel, $this->mLabel );
50
51        if ( $isVForm ) {
52            $chkLabelClass = 'mw-ui-checkbox';
53            $chkLabel = Html::rawElement(
54                'div',
55                [ 'class' => $chkLabelClass ],
56                $chkLabel
57            );
58        }
59
60        return $chkLabel;
61    }
62
63    /**
64     * Get the OOUI version of this field.
65     * @stable to override
66     * @since 1.26
67     * @param string $value
68     * @return \OOUI\CheckboxInputWidget The checkbox widget.
69     */
70    public function getInputOOUI( $value ) {
71        if ( !empty( $this->mParams['invert'] ) ) {
72            $value = !$value;
73        }
74
75        $attr = $this->getTooltipAndAccessKeyOOUI();
76        $attr['id'] = $this->mID;
77        $attr['name'] = $this->mName;
78
79        $attr += \OOUI\Element::configFromHtmlAttributes(
80            $this->getAttributes( [ 'disabled', 'tabindex' ] )
81        );
82
83        if ( $this->mClass !== '' ) {
84            $attr['classes'] = [ $this->mClass ];
85        }
86
87        $attr['selected'] = $value;
88        $attr['value'] = '1'; // Nasty hack, but needed to make this work
89
90        return new \OOUI\CheckboxInputWidget( $attr );
91    }
92
93    public function getInputCodex( $value, $hasErrors ) {
94        if ( !empty( $this->mParams['invert'] ) ) {
95            $value = !$value;
96        }
97
98        // Attributes for the <input> element.
99        $attribs = $this->getTooltipAndAccessKey();
100        $attribs['id'] = $this->mID;
101        $attribs += $this->getAttributes( [ 'disabled', 'tabindex' ] );
102
103        // The Xml class doesn't support an array of classes, so we have to provide a string.
104        $inputClass = $this->mClass ?? '';
105        $attribs['class'] = $inputClass . ' cdx-checkbox__input';
106
107        // Attributes for the <label> element.
108        $labelAttribs = [ 'for' => $this->mID ];
109        $labelAttribs['class'] = [ 'cdx-checkbox__label' ];
110
111        // Attributes for the wrapper <div>.
112        $wrapperAttribs = [ 'class' => [ 'cdx-checkbox' ] ];
113        if ( $hasErrors ) {
114            $wrapperAttribs['class'][] = 'cdx-checkbox--status-error';
115        }
116        if ( isset( $attribs['title'] ) ) {
117            // Propagate tooltip to the entire component (including the label).
118            $wrapperAttribs['title'] = $attribs['title'];
119        }
120
121        // Construct the component.
122        $checkIcon = "<span class=\"cdx-checkbox__icon\">\u{00A0}</span>";
123        $innerContent = Xml::check( $this->mName, $value, $attribs ) .
124            $checkIcon .
125            Html::rawElement( 'label', $labelAttribs, $this->mLabel );
126        return Html::rawElement(
127            'div',
128            $wrapperAttribs,
129            $innerContent
130        );
131    }
132
133    /**
134     * For a checkbox, the label goes on the right hand side, and is
135     * added in getInputHTML(), rather than HTMLFormField::getRow()
136     *
137     * ...unless OOUI is being used, in which case we actually return
138     * the label here.
139     *
140     * @stable to override
141     * @return string
142     */
143    public function getLabel() {
144        if ( $this->mParent instanceof OOUIHTMLForm ) {
145            return $this->mLabel ?? '';
146        } elseif (
147            $this->mParent instanceof HTMLForm &&
148            $this->mParent->getDisplayFormat() === 'div'
149        ) {
150            return '';
151        } else {
152            return "\u{00A0}";
153        }
154    }
155
156    /**
157     * Get label alignment when generating field for OOUI.
158     * @stable to override
159     * @return string 'left', 'right', 'top' or 'inline'
160     */
161    protected function getLabelAlignOOUI() {
162        return 'inline';
163    }
164
165    /**
166     * checkboxes don't need a label.
167     * @stable to override
168     * @return bool
169     */
170    protected function needsLabel() {
171        return false;
172    }
173
174    /**
175     * @return bool
176     */
177    public function getDefault() {
178        return (bool)$this->mDefault;
179    }
180
181    /**
182     * @stable to override
183     * @param WebRequest $request
184     *
185     * @return bool
186     */
187    public function loadDataFromRequest( $request ) {
188        $invert = isset( $this->mParams['invert'] ) && $this->mParams['invert'];
189
190        // Fetch the value in either one of the two following case:
191        // - we have a valid submit attempt (form was just submitted)
192        // - we have a value (an URL manually built by the user, or GET form with no wpFormIdentifier)
193        if ( $this->isSubmitAttempt( $request ) || $request->getCheck( $this->mName ) ) {
194            return $invert
195                ? !$request->getBool( $this->mName )
196                : $request->getBool( $this->mName );
197        } else {
198            return $this->getDefault();
199        }
200    }
201}
202
203/** @deprecated class alias since 1.42 */
204class_alias( HTMLCheckField::class, 'HTMLCheckField' );