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