Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
FormAction
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 8
132
0.00% covered (danger)
0.00%
0 / 1
 getFormFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 preText
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 postText
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 usesOOUI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getForm
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
12
 onSubmit
n/a
0 / 0
n/a
0 / 0
0
 onSuccess
n/a
0 / 0
n/a
0 / 0
0
 show
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Base classes for actions done on pages.
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 * @ingroup Actions
8 */
9
10namespace MediaWiki\Actions;
11
12use MediaWiki\HTMLForm\HTMLForm;
13use MediaWiki\Status\Status;
14
15/**
16 * An action which shows a form and does something based on the input from the form
17 *
18 * @stable to extend
19 *
20 * @ingroup Actions
21 */
22abstract class FormAction extends Action {
23
24    /**
25     * Get an HTMLForm descriptor array
26     * @stable to override
27     * @return array
28     */
29    protected function getFormFields() {
30        // Default to an empty form with just a submit button
31        return [];
32    }
33
34    /**
35     * Add pre- or post-text to the form
36     * @stable to override
37     * @return string HTML which will be sent to $form->addPreHtml()
38     */
39    protected function preText() {
40        return '';
41    }
42
43    /**
44     * @stable to override
45     * @return string
46     */
47    protected function postText() {
48        return '';
49    }
50
51    /**
52     * Play with the HTMLForm if you need to more substantially
53     * @stable to override
54     * @param HTMLForm $form
55     */
56    protected function alterForm( HTMLForm $form ) {
57    }
58
59    /**
60     * Whether the form should use OOUI
61     * @stable to override
62     * @return bool
63     */
64    protected function usesOOUI() {
65        return false;
66    }
67
68    /**
69     * Get the HTMLForm to control behavior
70     * @stable to override
71     * @return HTMLForm
72     */
73    protected function getForm() {
74        $this->fields = $this->getFormFields();
75
76        // Give hooks a chance to alter the form, adding extra fields or text etc
77        $this->getHookRunner()->onActionModifyFormFields(
78            $this->getName(),
79            $this->fields,
80            $this->getArticle()
81        );
82
83        if ( $this->usesOOUI() ) {
84            $form = HTMLForm::factory( 'ooui', $this->fields, $this->getContext(), $this->getName() );
85        } else {
86            $form = new HTMLForm( $this->fields, $this->getContext(), $this->getName() );
87        }
88        $form->setSubmitCallback( $this->onSubmit( ... ) );
89
90        $title = $this->getTitle();
91        $form->setAction( $title->getLocalURL( [ 'action' => $this->getName() ] ) );
92        // Retain query parameters (uselang etc)
93        $params = array_diff_key(
94            $this->getRequest()->getQueryValues(),
95            [ 'action' => null, 'title' => null ]
96        );
97        if ( $params ) {
98            $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) );
99        }
100
101        $form->addPreHtml( $this->preText() );
102        $form->addPostHtml( $this->postText() );
103        $this->alterForm( $form );
104
105        // Give hooks a chance to alter the form, adding extra fields or text etc
106        $this->getHookRunner()->onActionBeforeFormDisplay(
107            $this->getName(),
108            $form,
109            $this->getArticle()
110        );
111
112        return $form;
113    }
114
115    /**
116     * Process the form on POST submission.
117     *
118     * If you don't want to do anything with the form, just return false here.
119     *
120     * This method will be passed to the HTMLForm as a submit callback (see
121     * HTMLForm::setSubmitCallback) and must return as documented for HTMLForm::trySubmit.
122     *
123     * @see HTMLForm::setSubmitCallback()
124     * @see HTMLForm::trySubmit()
125     * @param array $data
126     * @return bool|string|array|Status Must return as documented for HTMLForm::trySubmit
127     */
128    abstract public function onSubmit( $data );
129
130    /**
131     * Do something exciting on successful processing of the form.  This might be to show
132     * a confirmation message (watch, rollback, etc) or to redirect somewhere else (edit,
133     * protect, etc).
134     */
135    abstract public function onSuccess();
136
137    /**
138     * The basic pattern for actions is to display some sort of HTMLForm UI, maybe with
139     * some stuff underneath (history etc); to do some processing on submission of that
140     * form (delete, protect, etc) and to do something exciting on 'success', be that
141     * display something new or redirect to somewhere.  Some actions have more exotic
142     * behavior, but that's what subclassing is for :D
143     * @stable to override
144     */
145    public function show() {
146        $this->setHeaders();
147
148        // This will throw exceptions if there's a problem
149        $this->checkCanExecute( $this->getUser() );
150
151        $form = $this->getForm();
152        if ( $form->show() ) {
153            $this->onSuccess();
154        }
155    }
156
157    /**
158     * @stable to override
159     * @return bool
160     */
161    public function doesWrites() {
162        return true;
163    }
164}
165
166/** @deprecated class alias since 1.44 */
167class_alias( FormAction::class, 'FormAction' );