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