Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 50 |
|
0.00% |
0 / 16 |
CRAP | |
0.00% |
0 / 1 |
FRGenericSubmitForm | |
0.00% |
0 / 50 |
|
0.00% |
0 / 16 |
756 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
initialize | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUser | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getState | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
ready | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
doBuildOnReady | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
trySet | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
doCheckTargetGiven | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
doCheckTarget | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkTarget | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
checkParameters | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
doCheckParameters | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
preload | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
doPreloadParameters | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
submit | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
doSubmit | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | use 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 | */ |
12 | abstract 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 | } |