Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.50% covered (warning)
87.50%
70 / 80
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
HTMLButtonField
88.61% covered (warning)
88.61%
70 / 79
42.86% covered (danger)
42.86%
3 / 7
21.65
0.00% covered (danger)
0.00%
0 / 1
 __construct
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
10.37
 getInputHTML
88.24% covered (warning)
88.24%
15 / 17
0.00% covered (danger)
0.00%
0 / 1
4.03
 getInputOOUI
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
2
 getInputCodex
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
2
 buildCodexComponent
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
 needsLabel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\HTMLForm\Field;
4
5use MediaWiki\Html\Html;
6use MediaWiki\HTMLForm\HTMLFormField;
7use MediaWiki\HTMLForm\VFormHTMLForm;
8use MediaWiki\Message\Message;
9
10/**
11 * Adds a generic button inline to the form. Does not do anything, you must add
12 * click handling code in JavaScript. Use a HTMLSubmitField if you merely
13 * wish to add a submit button to a form.
14 *
15 * Additional recognized configuration parameters include:
16 * - flags: OOUI flags for the button, see OOUI\FlaggedElement
17 * - buttonlabel-message: Message to use for the button display text, instead
18 *   of the value from 'default'. Overrides 'buttonlabel' and 'buttonlabel-raw'.
19 * - buttonlabel: Text to display for the button display text, instead
20 *   of the value from 'default'. Overrides 'buttonlabel-raw'.
21 * - buttonlabel-raw: HTMLto display for the button display text, instead
22 *   of the value from 'default'.
23 * - formnovalidate: Set to true if clicking this button should suppress
24 *   client-side form validation. Used in HTMLFormFieldCloner for add/remove
25 *   buttons.
26 *
27 * @stable to extend
28 * @since 1.22
29 */
30class HTMLButtonField extends HTMLFormField {
31    /** @var string */
32    protected $buttonType = 'button';
33    /** @var string|null */
34    protected $buttonLabel = null;
35
36    /** @var array Flags to add to OOUI Button widget */
37    protected $mFlags = [];
38
39    /** @var bool */
40    protected $mFormnovalidate = false;
41
42    /**
43     * @stable to call
44     * @inheritDoc
45     */
46    public function __construct( $info ) {
47        $info['nodata'] = true;
48
49        $this->setShowEmptyLabel( false );
50
51        parent::__construct( $info );
52
53        if ( isset( $info['flags'] ) ) {
54            $this->mFlags = $info['flags'];
55        }
56
57        if ( isset( $info['formnovalidate'] ) ) {
58            $this->mFormnovalidate = $info['formnovalidate'];
59        }
60
61        # Generate the label from a message, if possible
62        if ( isset( $info['buttonlabel-message'] ) ) {
63            $this->buttonLabel = $this->getMessage( $info['buttonlabel-message'] )->parse();
64        } elseif ( isset( $info['buttonlabel'] ) ) {
65            if ( $info['buttonlabel'] === '&#160;' || $info['buttonlabel'] === "\u{00A0}" ) {
66                // Apparently some things set &nbsp directly and in an odd format
67                $this->buttonLabel = "\u{00A0}";
68            } else {
69                $this->buttonLabel = htmlspecialchars( $info['buttonlabel'] );
70            }
71        } elseif ( isset( $info['buttonlabel-raw'] ) ) {
72            $this->buttonLabel = $info['buttonlabel-raw'];
73        }
74    }
75
76    public function getInputHTML( $value ) {
77        $flags = '';
78        $prefix = 'mw-htmlform-';
79        if ( $this->mParent instanceof VFormHTMLForm ) {
80            $prefix = 'mw-ui-';
81            // add mw-ui-button separately, so the descriptor doesn't need to set it
82            $flags .= ' ' . $prefix . 'button';
83        }
84        foreach ( $this->mFlags as $flag ) {
85            $flags .= ' ' . $prefix . $flag;
86        }
87        $attr = [
88            'class' => 'mw-htmlform-submit ' . $this->mClass . $flags,
89            'id' => $this->mID,
90            'type' => $this->buttonType,
91            'name' => $this->mName,
92            'value' => $this->getDefault(),
93            'formnovalidate' => $this->mFormnovalidate,
94        ] + $this->getAttributes( [ 'disabled', 'tabindex' ] );
95
96        return Html::rawElement( 'button', $attr,
97            $this->buttonLabel ?: htmlspecialchars( $this->getDefault() ) );
98    }
99
100    /**
101     * Get the OOUI widget for this field.
102     * @stable to override
103     * @param string $value
104     * @return \OOUI\ButtonInputWidget
105     */
106    public function getInputOOUI( $value ) {
107        return new \OOUI\ButtonInputWidget( [
108            'name' => $this->mName,
109            'value' => $this->getDefault(),
110            'label' => $this->buttonLabel
111                ? new \OOUI\HtmlSnippet( $this->buttonLabel )
112                : $this->getDefault(),
113            'type' => $this->buttonType,
114            'classes' => [ 'mw-htmlform-submit', $this->mClass ],
115            'id' => $this->mID,
116            'flags' => $this->mFlags,
117        ] + \OOUI\Element::configFromHtmlAttributes(
118            $this->getAttributes( [ 'disabled', 'tabindex' ] )
119        ) );
120    }
121
122    public function getInputCodex( $value, $hasErrors ) {
123        $flags = $this->mFlags;
124        $buttonLabel = $this->buttonLabel ?: htmlspecialchars( $this->getDefault() );
125        $buttonClasses = [ 'mw-htmlform-submit', 'cdx-button', $this->mClass ];
126        $buttonAttribs = [
127            'class' => $buttonClasses,
128            'id' => $this->mID,
129            'type' => $this->buttonType,
130            'name' => $this->mName,
131            'value' => $this->getDefault(),
132            'formnovalidate' => $this->mFormnovalidate,
133        ] + $this->getAttributes( [ 'disabled', 'tabindex' ] );
134
135        return static::buildCodexComponent(
136            $flags,
137            $buttonLabel,
138            $buttonAttribs
139        );
140    }
141
142    /**
143     * Build the markup of the Codex component
144     *
145     * @param array $flags The button's flag classes.
146     * @param string $buttonLabel The button's label attribute.
147     * @param array $attribs The button's list of attributes.
148     * @return string Raw HTML.
149     */
150    public static function buildCodexComponent(
151        $flags,
152        $buttonLabel,
153        $attribs
154    ) {
155        $flagClasses = [];
156        $flagClassMap = [
157            'progressive' => 'cdx-button--action-progressive',
158            'destructive' => 'cdx-button--action-destructive',
159            'primary' => 'cdx-button--weight-primary',
160            'quiet' => 'cdx-button--weight-quiet',
161        ];
162
163        foreach ( $flags as $flag ) {
164            if ( isset( $flagClassMap[$flag] ) ) {
165                $flagClasses[] = $flagClassMap[$flag];
166            }
167        }
168
169        $buttonClassesAndFlags = array_merge( $attribs[ 'class' ], $flagClasses );
170        $attribs['class'] = $buttonClassesAndFlags;
171
172        $buttonHtml = Html::rawElement(
173            'button', $attribs, $buttonLabel
174        );
175
176        return $buttonHtml;
177    }
178
179    /**
180     * @inheritDoc
181     * @stable to override
182     */
183    protected function needsLabel() {
184        return false;
185    }
186
187    /**
188     * Button cannot be invalid
189     * @stable to override
190     *
191     * @param string $value
192     * @param array $alldata
193     *
194     * @return bool|string|Message
195     */
196    public function validate( $value, $alldata ) {
197        return true;
198    }
199}
200
201/** @deprecated class alias since 1.42 */
202class_alias( HTMLButtonField::class, 'HTMLButtonField' );