Commit | Line | Data |
---|---|---|
11ade432 AE |
1 | <?php |
2 | namespace wcf\data; | |
11ade432 AE |
3 | use wcf\system\event\EventHandler; |
4 | use wcf\system\exception\PermissionDeniedException; | |
4e877829 | 5 | use wcf\system\exception\SystemException; |
429e91b8 | 6 | use wcf\system\exception\UserInputException; |
b6628fdc | 7 | use wcf\system\request\RequestHandler; |
11ade432 | 8 | use wcf\system\WCF; |
857ed85d | 9 | use wcf\util\ArrayUtil; |
217e4987 | 10 | use wcf\util\JSON; |
11ade432 AE |
11 | use wcf\util\StringUtil; |
12 | ||
13 | /** | |
14 | * Default implementation for DatabaseObject-related actions. | |
9f959ced | 15 | * |
11ade432 | 16 | * @author Alexander Ebert |
5d3928e9 | 17 | * @copyright 2001-2020 WoltLab GmbH |
11ade432 | 18 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
e71525e4 | 19 | * @package WoltLabSuite\Core\Data |
11ade432 | 20 | */ |
a427a8c8 | 21 | abstract class AbstractDatabaseObjectAction implements IDatabaseObjectAction, IDeleteAction { |
11ade432 AE |
22 | /** |
23 | * pending action | |
11ade432 AE |
24 | * @var string |
25 | */ | |
26 | protected $action = ''; | |
27 | ||
28 | /** | |
29 | * object editor class name | |
11ade432 AE |
30 | * @var string |
31 | */ | |
32 | protected $className = ''; | |
33 | ||
34 | /** | |
35 | * list of object ids | |
090b71e5 | 36 | * @var int[] |
11ade432 | 37 | */ |
058cbd6a | 38 | protected $objectIDs = []; |
11ade432 AE |
39 | |
40 | /** | |
832371b2 | 41 | * list of object editors |
7a23a706 | 42 | * @var DatabaseObjectEditor[] |
11ade432 | 43 | */ |
058cbd6a | 44 | protected $objects = []; |
11ade432 AE |
45 | |
46 | /** | |
47 | * multi-dimensional array of parameters required by an action | |
2e4589ba | 48 | * @var array |
11ade432 | 49 | */ |
058cbd6a | 50 | protected $parameters = []; |
11ade432 AE |
51 | |
52 | /** | |
53 | * list of permissions required to create objects | |
7a23a706 | 54 | * @var string[] |
11ade432 | 55 | */ |
058cbd6a | 56 | protected $permissionsCreate = []; |
11ade432 AE |
57 | |
58 | /** | |
59 | * list of permissions required to delete objects | |
7a23a706 | 60 | * @var string[] |
11ade432 | 61 | */ |
058cbd6a | 62 | protected $permissionsDelete = []; |
11ade432 AE |
63 | |
64 | /** | |
65 | * list of permissions required to update objects | |
7a23a706 | 66 | * @var string[] |
11ade432 | 67 | */ |
058cbd6a | 68 | protected $permissionsUpdate = []; |
11ade432 | 69 | |
bae8dd1e AE |
70 | /** |
71 | * disallow requests for specified methods if the origin is not the ACP | |
7a23a706 | 72 | * @var string[] |
bae8dd1e | 73 | */ |
058cbd6a | 74 | protected $requireACP = []; |
bae8dd1e | 75 | |
22d94e94 AE |
76 | /** |
77 | * Resets cache if any of the listed actions is invoked | |
7a23a706 | 78 | * @var string[] |
22d94e94 | 79 | */ |
058cbd6a | 80 | protected $resetCache = ['create', 'delete', 'toggle', 'update', 'updatePosition']; |
22d94e94 | 81 | |
11ade432 AE |
82 | /** |
83 | * values returned by executed action | |
11ade432 AE |
84 | * @var mixed |
85 | */ | |
86 | protected $returnValues = null; | |
87 | ||
fca077a6 | 88 | /** |
9f959ced MS |
89 | * allows guest access for all specified methods, by default guest access |
90 | * is completely disabled | |
7a23a706 | 91 | * @var string[] |
fca077a6 | 92 | */ |
058cbd6a | 93 | protected $allowGuestAccess = []; |
fca077a6 | 94 | |
429e91b8 AE |
95 | const TYPE_INTEGER = 1; |
96 | const TYPE_STRING = 2; | |
976d79e3 | 97 | const TYPE_BOOLEAN = 3; |
217e4987 | 98 | const TYPE_JSON = 4; |
429e91b8 | 99 | |
15a48bb3 AE |
100 | const STRUCT_FLAT = 1; |
101 | const STRUCT_ARRAY = 2; | |
102 | ||
11ade432 | 103 | /** |
a90028e5 | 104 | * Initialize a new DatabaseObject-related action. |
9f959ced | 105 | * |
7a23a706 | 106 | * @param mixed[] $objects |
11ade432 AE |
107 | * @param string $action |
108 | * @param array $parameters | |
2b770bdd | 109 | * @throws SystemException |
11ade432 | 110 | */ |
058cbd6a | 111 | public function __construct(array $objects, $action, array $parameters = []) { |
7703d974 MS |
112 | // set class name |
113 | if (empty($this->className)) { | |
114 | $className = get_called_class(); | |
115 | ||
838e315b SG |
116 | if (mb_substr($className, -6) == 'Action') { |
117 | $this->className = mb_substr($className, 0, -6).'Editor'; | |
7703d974 MS |
118 | } |
119 | } | |
120 | ||
058cbd6a MS |
121 | $indexName = call_user_func([$this->className, 'getDatabaseTableIndexName']); |
122 | $baseClass = call_user_func([$this->className, 'getBaseClass']); | |
4e877829 MW |
123 | |
124 | foreach ($objects as $object) { | |
125 | if (is_object($object)) { | |
126 | if ($object instanceof $this->className) { | |
127 | $this->objects[] = $object; | |
128 | } | |
129 | else if ($object instanceof $baseClass) { | |
130 | $this->objects[] = new $this->className($object); | |
131 | } | |
132 | else { | |
133 | throw new SystemException('invalid value of parameter objects given'); | |
134 | } | |
135 | ||
7c9f2241 | 136 | /** @noinspection PhpVariableVariableInspection */ |
4e877829 MW |
137 | $this->objectIDs[] = $object->$indexName; |
138 | } | |
4e877829 | 139 | else { |
f28efd50 | 140 | $this->objectIDs[] = $object; |
4e877829 MW |
141 | } |
142 | } | |
143 | ||
11ade432 AE |
144 | $this->action = $action; |
145 | $this->parameters = $parameters; | |
146 | ||
57757c3e ST |
147 | // initialize further settings |
148 | $this->__init($baseClass, $indexName); | |
149 | ||
11ade432 AE |
150 | // fire event action |
151 | EventHandler::getInstance()->fireAction($this, 'initializeAction'); | |
152 | } | |
153 | ||
57757c3e ST |
154 | /** |
155 | * This function can be overridden in children to perform custom initialization | |
156 | * of a DBOAction before the 'initializeAction' event is fired. | |
6f37a5f5 MS |
157 | * |
158 | * @param string $baseClass | |
159 | * @param string $indexName | |
57757c3e | 160 | */ |
6f37a5f5 MS |
161 | protected function __init($baseClass, $indexName) { |
162 | // does nothing | |
163 | } | |
57757c3e | 164 | |
11ade432 | 165 | /** |
0fcfe5f6 | 166 | * @inheritDoc |
11ade432 AE |
167 | */ |
168 | public function validateAction() { | |
fca077a6 | 169 | // validate if user is logged in |
878d0d80 | 170 | if (!WCF::getUser()->userID && !in_array($this->getActionName(), $this->allowGuestAccess)) { |
f1a3caba | 171 | throw new PermissionDeniedException(); |
fca077a6 | 172 | } |
bae8dd1e AE |
173 | else if (!RequestHandler::getInstance()->isACPRequest() && in_array($this->getActionName(), $this->requireACP)) { |
174 | // attempt to invoke method, but origin is not the ACP | |
175 | throw new PermissionDeniedException(); | |
176 | } | |
fca077a6 | 177 | |
11ade432 AE |
178 | // validate action name |
179 | if (!method_exists($this, $this->getActionName())) { | |
3631f7bd | 180 | throw new SystemException("unknown action '".$this->getActionName()."'"); |
11ade432 AE |
181 | } |
182 | ||
183 | $actionName = 'validate'.StringUtil::firstCharToUpperCase($this->getActionName()); | |
184 | if (!method_exists($this, $actionName)) { | |
3631f7bd | 185 | throw new PermissionDeniedException(); |
11ade432 AE |
186 | } |
187 | ||
084bb213 TD |
188 | // validate action |
189 | $this->{$actionName}(); | |
1e2c1c9c MS |
190 | |
191 | // fire event action | |
192 | EventHandler::getInstance()->fireAction($this, 'validateAction'); | |
11ade432 AE |
193 | } |
194 | ||
195 | /** | |
0fcfe5f6 | 196 | * @inheritDoc |
11ade432 AE |
197 | */ |
198 | public function executeAction() { | |
199 | // execute action | |
51772f85 MW |
200 | if (!method_exists($this, $this->getActionName())) { |
201 | throw new SystemException("call to undefined function '".$this->getActionName()."'"); | |
351d836a MS |
202 | } |
203 | ||
084bb213 | 204 | $this->returnValues = $this->{$this->getActionName()}(); |
11ade432 AE |
205 | |
206 | // reset cache | |
22d94e94 AE |
207 | if (in_array($this->getActionName(), $this->resetCache)) { |
208 | $this->resetCache(); | |
11ade432 AE |
209 | } |
210 | ||
211 | // fire event action | |
212 | EventHandler::getInstance()->fireAction($this, 'finalizeAction'); | |
213 | ||
214 | return $this->getReturnValues(); | |
215 | } | |
216 | ||
22d94e94 AE |
217 | /** |
218 | * Resets cache of database object. | |
219 | */ | |
220 | protected function resetCache() { | |
157054c9 | 221 | if (is_subclass_of($this->className, IEditableCachedObject::class)) { |
058cbd6a | 222 | call_user_func([$this->className, 'resetCache']); |
22d94e94 AE |
223 | } |
224 | } | |
225 | ||
11ade432 | 226 | /** |
0fcfe5f6 | 227 | * @inheritDoc |
11ade432 AE |
228 | */ |
229 | public function getActionName() { | |
230 | return $this->action; | |
231 | } | |
232 | ||
233 | /** | |
0fcfe5f6 | 234 | * @inheritDoc |
11ade432 AE |
235 | */ |
236 | public function getObjectIDs() { | |
237 | return $this->objectIDs; | |
238 | } | |
239 | ||
e9aeabca MW |
240 | /** |
241 | * Sets the database objects. | |
242 | * | |
7a23a706 | 243 | * @param DatabaseObject[] $objects |
e9aeabca MW |
244 | */ |
245 | public function setObjects(array $objects) { | |
246 | $this->objects = $objects; | |
78e2cd62 MK |
247 | |
248 | // update object IDs | |
058cbd6a | 249 | $this->objectIDs = []; |
4a130a51 | 250 | foreach ($this->getObjects() as $object) { |
78e2cd62 MK |
251 | $this->objectIDs[] = $object->getObjectID(); |
252 | } | |
e9aeabca MW |
253 | } |
254 | ||
11ade432 | 255 | /** |
0fcfe5f6 | 256 | * @inheritDoc |
11ade432 AE |
257 | */ |
258 | public function getParameters() { | |
259 | return $this->parameters; | |
260 | } | |
261 | ||
262 | /** | |
0fcfe5f6 | 263 | * @inheritDoc |
11ade432 AE |
264 | */ |
265 | public function getReturnValues() { | |
058cbd6a | 266 | return [ |
a8f8312d | 267 | 'actionName' => $this->action, |
11ade432 AE |
268 | 'objectIDs' => $this->getObjectIDs(), |
269 | 'returnValues' => $this->returnValues | |
058cbd6a | 270 | ]; |
11ade432 AE |
271 | } |
272 | ||
273 | /** | |
274 | * Validates permissions and parameters. | |
275 | */ | |
276 | public function validateCreate() { | |
277 | // validate permissions | |
15fa2802 | 278 | if (is_array($this->permissionsCreate) && !empty($this->permissionsCreate)) { |
3631f7bd | 279 | WCF::getSession()->checkPermissions($this->permissionsCreate); |
11ade432 AE |
280 | } |
281 | else { | |
3631f7bd | 282 | throw new PermissionDeniedException(); |
11ade432 AE |
283 | } |
284 | } | |
285 | ||
286 | /** | |
0fcfe5f6 | 287 | * @inheritDoc |
11ade432 AE |
288 | */ |
289 | public function validateDelete() { | |
290 | // validate permissions | |
15fa2802 | 291 | if (is_array($this->permissionsDelete) && !empty($this->permissionsDelete)) { |
3631f7bd | 292 | WCF::getSession()->checkPermissions($this->permissionsDelete); |
11ade432 AE |
293 | } |
294 | else { | |
3631f7bd | 295 | throw new PermissionDeniedException(); |
11ade432 AE |
296 | } |
297 | ||
046f3d7b | 298 | // read objects |
15fa2802 | 299 | if (empty($this->objects)) { |
e9aeabca | 300 | $this->readObjects(); |
15fa2802 MS |
301 | |
302 | if (empty($this->objects)) { | |
3631f7bd | 303 | throw new UserInputException('objectIDs'); |
15fa2802 | 304 | } |
11ade432 AE |
305 | } |
306 | } | |
307 | ||
308 | /** | |
309 | * Validates permissions and parameters. | |
310 | */ | |
311 | public function validateUpdate() { | |
312 | // validate permissions | |
15fa2802 | 313 | if (is_array($this->permissionsUpdate) && !empty($this->permissionsUpdate)) { |
3631f7bd | 314 | WCF::getSession()->checkPermissions($this->permissionsUpdate); |
11ade432 AE |
315 | } |
316 | else { | |
3631f7bd | 317 | throw new PermissionDeniedException(); |
11ade432 AE |
318 | } |
319 | ||
046f3d7b | 320 | // read objects |
15fa2802 | 321 | if (empty($this->objects)) { |
e9aeabca | 322 | $this->readObjects(); |
351d836a | 323 | |
15fa2802 | 324 | if (empty($this->objects)) { |
3631f7bd | 325 | throw new UserInputException('objectIDs'); |
15fa2802 | 326 | } |
11ade432 AE |
327 | } |
328 | } | |
329 | ||
330 | /** | |
832371b2 | 331 | * Creates new database object. |
351d836a | 332 | * |
4e25add7 | 333 | * @return DatabaseObject |
11ade432 AE |
334 | */ |
335 | public function create() { | |
058cbd6a | 336 | return call_user_func([$this->className, 'create'], $this->parameters['data']); |
11ade432 AE |
337 | } |
338 | ||
339 | /** | |
0fcfe5f6 | 340 | * @inheritDoc |
11ade432 AE |
341 | */ |
342 | public function delete() { | |
15fa2802 | 343 | if (empty($this->objects)) { |
11ade432 AE |
344 | $this->readObjects(); |
345 | } | |
346 | ||
11ade432 | 347 | // get ids |
058cbd6a | 348 | $objectIDs = []; |
4a130a51 | 349 | foreach ($this->getObjects() as $object) { |
91a5aa24 | 350 | $objectIDs[] = $object->getObjectID(); |
11ade432 AE |
351 | } |
352 | ||
353 | // execute action | |
058cbd6a | 354 | return call_user_func([$this->className, 'deleteAll'], $objectIDs); |
11ade432 AE |
355 | } |
356 | ||
357 | /** | |
358 | * Updates data. | |
359 | */ | |
360 | public function update() { | |
15fa2802 | 361 | if (empty($this->objects)) { |
11ade432 AE |
362 | $this->readObjects(); |
363 | } | |
364 | ||
78143bc8 MS |
365 | if (isset($this->parameters['data'])) { |
366 | foreach ($this->getObjects() as $object) { | |
367 | $object->update($this->parameters['data']); | |
046f3d7b | 368 | } |
11ade432 | 369 | } |
575350ba | 370 | |
78143bc8 MS |
371 | if (isset($this->parameters['counters'])) { |
372 | foreach ($this->getObjects() as $object) { | |
373 | $object->updateCounters($this->parameters['counters']); | |
575350ba MS |
374 | } |
375 | } | |
11ade432 AE |
376 | } |
377 | ||
378 | /** | |
379 | * Reads data by data id. | |
380 | */ | |
381 | protected function readObjects() { | |
15fa2802 | 382 | if (empty($this->objectIDs)) { |
11ade432 AE |
383 | return; |
384 | } | |
385 | ||
386 | // get base class | |
058cbd6a | 387 | $baseClass = call_user_func([$this->className, 'getBaseClass']); |
11ade432 AE |
388 | |
389 | // get db information | |
058cbd6a MS |
390 | $tableName = call_user_func([$this->className, 'getDatabaseTableName']); |
391 | $indexName = call_user_func([$this->className, 'getDatabaseTableIndexName']); | |
11ade432 AE |
392 | |
393 | // get objects | |
394 | $sql = "SELECT * | |
395 | FROM ".$tableName." | |
396 | WHERE ".$indexName." IN (".str_repeat('?,', count($this->objectIDs) - 1)."?)"; | |
397 | $statement = WCF::getDB()->prepareStatement($sql); | |
398 | $statement->execute($this->objectIDs); | |
399 | while ($object = $statement->fetchObject($baseClass)) { | |
400 | $this->objects[] = new $this->className($object); | |
401 | } | |
402 | } | |
764fe46c | 403 | |
429e91b8 | 404 | /** |
e2355457 | 405 | * Returns a single object and throws a UserInputException if no or more than one object is given. |
429e91b8 | 406 | * |
2b770bdd MS |
407 | * @return DatabaseObject |
408 | * @throws UserInputException | |
429e91b8 AE |
409 | */ |
410 | protected function getSingleObject() { | |
411 | if (empty($this->objects)) { | |
412 | $this->readObjects(); | |
413 | } | |
414 | ||
415 | if (count($this->objects) != 1) { | |
416 | throw new UserInputException('objectIDs'); | |
417 | } | |
418 | ||
419 | reset($this->objects); | |
420 | return current($this->objects); | |
421 | } | |
422 | ||
423 | /** | |
424 | * Reads an integer value and validates it. | |
425 | * | |
426 | * @param string $variableName | |
1524f8c0 | 427 | * @param bool $allowEmpty |
429e91b8 AE |
428 | * @param string $arrayIndex |
429 | */ | |
61582f5f | 430 | protected function readInteger($variableName, $allowEmpty = false, $arrayIndex = '') { |
15a48bb3 AE |
431 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_INTEGER, self::STRUCT_FLAT); |
432 | } | |
433 | ||
434 | /** | |
435 | * Reads an integer array and validates it. | |
436 | * | |
437 | * @param string $variableName | |
1524f8c0 | 438 | * @param bool $allowEmpty |
15a48bb3 | 439 | * @param string $arrayIndex |
e71525e4 | 440 | * @since 3.0 |
15a48bb3 AE |
441 | */ |
442 | protected function readIntegerArray($variableName, $allowEmpty = false, $arrayIndex = '') { | |
443 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_INTEGER, self::STRUCT_ARRAY); | |
429e91b8 AE |
444 | } |
445 | ||
446 | /** | |
447 | * Reads a string value and validates it. | |
448 | * | |
449 | * @param string $variableName | |
1524f8c0 | 450 | * @param bool $allowEmpty |
429e91b8 AE |
451 | * @param string $arrayIndex |
452 | */ | |
453 | protected function readString($variableName, $allowEmpty = false, $arrayIndex = '') { | |
15a48bb3 | 454 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_STRING, self::STRUCT_FLAT); |
429e91b8 AE |
455 | } |
456 | ||
1c83c647 AE |
457 | /** |
458 | * Reads a string array and validates it. | |
459 | * | |
460 | * @param string $variableName | |
1524f8c0 | 461 | * @param bool $allowEmpty |
1c83c647 | 462 | * @param string $arrayIndex |
e71525e4 | 463 | * @since 3.0 |
1c83c647 AE |
464 | */ |
465 | protected function readStringArray($variableName, $allowEmpty = false, $arrayIndex = '') { | |
466 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_STRING, self::STRUCT_ARRAY); | |
467 | } | |
468 | ||
8795c633 MK |
469 | /** |
470 | * Reads a boolean value and validates it. | |
471 | * | |
472 | * @param string $variableName | |
1524f8c0 | 473 | * @param bool $allowEmpty |
8795c633 | 474 | * @param string $arrayIndex |
8795c633 | 475 | */ |
976d79e3 | 476 | protected function readBoolean($variableName, $allowEmpty = false, $arrayIndex = '') { |
15a48bb3 | 477 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_BOOLEAN, self::STRUCT_FLAT); |
429e91b8 AE |
478 | } |
479 | ||
217e4987 AE |
480 | /** |
481 | * Reads a json-encoded value and validates it. | |
482 | * | |
483 | * @param string $variableName | |
1524f8c0 | 484 | * @param bool $allowEmpty |
217e4987 AE |
485 | * @param string $arrayIndex |
486 | */ | |
487 | protected function readJSON($variableName, $allowEmpty = false, $arrayIndex = '') { | |
15a48bb3 | 488 | $this->readValue($variableName, $allowEmpty, $arrayIndex, self::TYPE_JSON, self::STRUCT_FLAT); |
217e4987 AE |
489 | } |
490 | ||
429e91b8 AE |
491 | /** |
492 | * Reads a value and validates it. If you set $allowEmpty to true, no exception will | |
090b71e5 | 493 | * be thrown if the variable evaluates to 0 (int) or '' (string). Furthermore the |
429e91b8 AE |
494 | * variable will be always created with a sane value if it does not exist. |
495 | * | |
496 | * @param string $variableName | |
1524f8c0 | 497 | * @param bool $allowEmpty |
429e91b8 | 498 | * @param string $arrayIndex |
090b71e5 MS |
499 | * @param int $type |
500 | * @param int $structure | |
2b770bdd MS |
501 | * @throws SystemException |
502 | * @throws UserInputException | |
429e91b8 | 503 | */ |
15a48bb3 | 504 | protected function readValue($variableName, $allowEmpty, $arrayIndex, $type, $structure) { |
429e91b8 AE |
505 | if ($arrayIndex) { |
506 | if (!isset($this->parameters[$arrayIndex])) { | |
66b49e55 AE |
507 | if ($allowEmpty) { |
508 | // Implicitly create the structure to permit implicitly defined values. | |
509 | $this->parameters[$arrayIndex] = []; | |
510 | } | |
511 | else { | |
512 | throw new SystemException("Corrupt parameters, index '" . $arrayIndex . "' is missing"); | |
513 | } | |
429e91b8 AE |
514 | } |
515 | ||
57d62a68 | 516 | $target =& $this->parameters[$arrayIndex]; |
429e91b8 AE |
517 | } |
518 | else { | |
519 | $target =& $this->parameters; | |
520 | } | |
521 | ||
522 | switch ($type) { | |
523 | case self::TYPE_INTEGER: | |
524 | if (!isset($target[$variableName])) { | |
525 | if ($allowEmpty) { | |
058cbd6a | 526 | $target[$variableName] = ($structure === self::STRUCT_FLAT) ? 0 : []; |
429e91b8 AE |
527 | } |
528 | else { | |
529 | throw new UserInputException($variableName); | |
530 | } | |
531 | } | |
532 | else { | |
15a48bb3 AE |
533 | if ($structure === self::STRUCT_FLAT) { |
534 | $target[$variableName] = intval($target[$variableName]); | |
535 | if (!$allowEmpty && !$target[$variableName]) { | |
536 | throw new UserInputException($variableName); | |
537 | } | |
538 | } | |
539 | else { | |
540 | $target[$variableName] = ArrayUtil::toIntegerArray($target[$variableName]); | |
541 | if (!is_array($target[$variableName])) { | |
542 | throw new UserInputException($variableName); | |
543 | } | |
544 | ||
545 | for ($i = 0, $length = count($target[$variableName]); $i < $length; $i++) { | |
546 | if ($target[$variableName][$i] === 0) { | |
547 | throw new UserInputException($variableName); | |
548 | } | |
549 | } | |
429e91b8 AE |
550 | } |
551 | } | |
552 | break; | |
553 | ||
554 | case self::TYPE_STRING: | |
555 | if (!isset($target[$variableName])) { | |
556 | if ($allowEmpty) { | |
058cbd6a | 557 | $target[$variableName] = ($structure === self::STRUCT_FLAT) ? '' : []; |
429e91b8 AE |
558 | } |
559 | else { | |
560 | throw new UserInputException($variableName); | |
561 | } | |
562 | } | |
563 | else { | |
1c83c647 AE |
564 | if ($structure === self::STRUCT_FLAT) { |
565 | $target[$variableName] = StringUtil::trim($target[$variableName]); | |
0db33547 | 566 | if (!$allowEmpty && $target[$variableName] === '') { |
1c83c647 AE |
567 | throw new UserInputException($variableName); |
568 | } | |
569 | } | |
570 | else { | |
571 | $target[$variableName] = ArrayUtil::trim($target[$variableName]); | |
572 | if (!is_array($target[$variableName])) { | |
573 | throw new UserInputException($variableName); | |
574 | } | |
56eb7314 | 575 | |
1c83c647 | 576 | for ($i = 0, $length = count($target[$variableName]); $i < $length; $i++) { |
0db33547 | 577 | if ($target[$variableName][$i] === '') { |
1c83c647 AE |
578 | throw new UserInputException($variableName); |
579 | } | |
580 | } | |
429e91b8 AE |
581 | } |
582 | } | |
583 | break; | |
8795c633 | 584 | |
976d79e3 | 585 | case self::TYPE_BOOLEAN: |
8795c633 MK |
586 | if (!isset($target[$variableName])) { |
587 | if ($allowEmpty) { | |
588 | $target[$variableName] = false; | |
589 | } | |
590 | else { | |
591 | throw new UserInputException($variableName); | |
592 | } | |
593 | } | |
594 | else { | |
976d79e3 AE |
595 | if (is_numeric($target[$variableName])) { |
596 | $target[$variableName] = (bool) $target[$variableName]; | |
921e346a MK |
597 | } |
598 | else { | |
976d79e3 | 599 | $target[$variableName] = $target[$variableName] != 'false'; |
6c611ea7 | 600 | } |
8795c633 MK |
601 | } |
602 | break; | |
217e4987 AE |
603 | |
604 | case self::TYPE_JSON: | |
605 | if (!isset($target[$variableName])) { | |
606 | if ($allowEmpty) { | |
058cbd6a | 607 | $target[$variableName] = []; |
217e4987 AE |
608 | } |
609 | else { | |
610 | throw new UserInputException($variableName); | |
611 | } | |
612 | } | |
613 | else { | |
614 | try { | |
615 | $target[$variableName] = JSON::decode($target[$variableName]); | |
616 | } | |
617 | catch (SystemException $e) { | |
618 | throw new UserInputException($variableName); | |
619 | } | |
620 | ||
621 | if (!$allowEmpty && empty($target[$variableName])) { | |
622 | throw new UserInputException($variableName); | |
623 | } | |
624 | } | |
625 | break; | |
429e91b8 | 626 | } |
429e91b8 AE |
627 | } |
628 | ||
764fe46c AE |
629 | /** |
630 | * Returns object class name. | |
631 | * | |
632 | * @return string | |
633 | */ | |
634 | public function getClassName() { | |
635 | return $this->className; | |
636 | } | |
637 | ||
638 | /** | |
639 | * Returns a list of currently loaded objects. | |
640 | * | |
7a23a706 | 641 | * @return DatabaseObjectEditor[] |
764fe46c AE |
642 | */ |
643 | public function getObjects() { | |
644 | return $this->objects; | |
645 | } | |
11ade432 | 646 | } |