Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
FRGenericSubmitForm
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 16
756
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 initialize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUser
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getState
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 ready
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 doBuildOnReady
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 trySet
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 doCheckTargetGiven
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doCheckTarget
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 checkTarget
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 checkParameters
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 doCheckParameters
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 preload
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 doPreloadParameters
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 submit
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 doSubmit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3use MediaWiki\User\User;
4
5/**
6 * Class containing generic form business logic
7 * Note: edit tokens are the responsibility of the caller
8 * Usage: (a) set ALL form params before doing anything else
9 *        (b) call ready() when all params are set
10 *        (c) call preload() OR submit() as needed
11 */
12abstract class FRGenericSubmitForm {
13    # Notify functions when we are submitting
14    protected const FOR_SUBMISSION = 1;
15
16    /* Internal form state */
17
18    # Params not given yet
19    protected const FORM_UNREADY = 0;
20    # Params given and ready to submit
21    protected const FORM_READY = 1;
22    # Params pre-loaded (likely from replica DB)
23    protected const FORM_PRELOADED = 2;
24    # Form submitted
25    protected const FORM_SUBMITTED = 3;
26
27    /** @var int Form state (disallows bad operations) */
28    private $state = self::FORM_UNREADY;
29
30    /** @var User User performing the action */
31    protected $user;
32
33    /**
34     * @param User $user
35     */
36    final public function __construct( User $user ) {
37        $this->user = $user;
38        $this->initialize();
39    }
40
41    /**
42     * Initialize any parameters on construction
43     * @return void
44     */
45    protected function initialize() {
46    }
47
48    /**
49     * Get the submitting user
50     * @return User
51     */
52    final public function getUser() {
53        return $this->user;
54    }
55
56    /**
57     * Get the internal form state
58     * @return int
59     */
60    final protected function getState() {
61        return $this->state;
62    }
63
64    /**
65     * Signal that inputs are all given (via accessors)
66     * @return true|string true on success, error string on target failure
67     */
68    final public function ready() {
69        if ( $this->state != self::FORM_UNREADY ) {
70            throw new LogicException( __CLASS__ . " ready() already called.\n" );
71        }
72
73        $this->state = self::FORM_READY;
74        $status = $this->doCheckTargetGiven();
75        if ( $status !== true ) {
76            return $status; // bad target
77        }
78
79        $this->doBuildOnReady();
80        return true;
81    }
82
83    /**
84     * Load any objects after ready() called
85     * NOTE: do not do any DB hits here, just build objects
86     */
87    protected function doBuildOnReady() {
88    }
89
90    /**
91     * Set a member field to a value if the fields are unlocked
92     * @param mixed &$field Field of this form
93     * @param mixed $value Value to set the field to
94     * @return void
95     */
96    final protected function trySet( &$field, $value ) {
97        if ( $this->state != self::FORM_UNREADY ) {
98            throw new LogicException( __CLASS__ . " fields cannot be set anymore.\n" );
99        } else {
100            $field = $value; // still allowing input
101        }
102    }
103
104    /**
105     * Check that a target is given (e.g. from GET/POST request)
106     * NOTE: do not do any DB hits here, just check if there is a target
107     * @return true|string true on success, error string on failure
108     */
109    protected function doCheckTargetGiven() {
110        return true;
111    }
112
113    /**
114     * Check that the target is valid (e.g. from GET/POST request)
115     * @param int $flags FOR_SUBMISSION (set on submit)
116     * @return true|string true on success, error string on failure
117     */
118    protected function doCheckTarget( $flags = 0 ) {
119        return true;
120    }
121
122    /**
123     * Check that a target is and it is valid (e.g. from GET/POST request)
124     * NOTE: do not do any DB hits here, just check if there is a target
125     * @return true|string true on success, error string on failure
126     */
127    final public function checkTarget() {
128        if ( $this->state != self::FORM_READY ) {
129            throw new LogicException( __CLASS__ . " input fields not set yet.\n" );
130        }
131        $status = $this->doCheckTargetGiven();
132        if ( $status !== true ) {
133            return $status; // bad target
134        }
135        return $this->doCheckTarget();
136    }
137
138    /**
139     * Validate and clean up target/parameters (e.g. from POST request)
140     * @return true|string true on success, error string on failure
141     */
142    private function checkParameters() {
143        $status = $this->doCheckTarget( self::FOR_SUBMISSION );
144        if ( $status !== true ) {
145            return $status; // bad target
146        }
147        return $this->doCheckParameters();
148    }
149
150    /**
151     * Verify and clean up parameters (e.g. from POST request)
152     * @return true|string true on success, error string on failure
153     */
154    protected function doCheckParameters() {
155        return true;
156    }
157
158    /**
159     * Preload existing params for the target from the DB (e.g. for GET request)
160     * NOTE: do not call this and then submit()
161     * @return true|string true on success, error string on failure
162     */
163    final public function preload() {
164        if ( $this->state != self::FORM_READY ) {
165            throw new LogicException( __CLASS__ . " input fields not set yet.\n" );
166        }
167        $status = $this->checkTarget();
168        if ( $status !== true ) {
169            return $status; // bad target
170        }
171        $this->doPreloadParameters();
172        $this->state = self::FORM_PRELOADED;
173        return true;
174    }
175
176    /**
177     * Preload existing params for the target from the DB (e.g. for GET request)
178     */
179    protected function doPreloadParameters() {
180    }
181
182    /**
183     * Submit the form parameters for the page config to the DB
184     * @return true|string true on success, error string on failure
185     */
186    final public function submit() {
187        if ( $this->state != self::FORM_READY ) {
188            throw new LogicException( __CLASS__ . " input fields preloaded or not set yet.\n" );
189        }
190        $status = $this->checkParameters();
191        if ( $status !== true ) {
192            return $status; // cannot submit - broken target or params
193        }
194        $status = $this->doSubmit();
195        if ( $status !== true ) {
196            return $status; // cannot submit
197        }
198        $this->state = self::FORM_SUBMITTED;
199        return true;
200    }
201
202    /**
203     * Submit the form parameters for the page config to the DB
204     * @return true|string true on success, error string on failure
205     */
206    protected function doSubmit() {
207        return true;
208    }
209}