ab4cff40ec6663b6ce8c596a60d98207c23a6efd
[GitHub/WoltLab/WCF.git] /
1 <?php
2 namespace wcf\system\form\builder\field\data\processor;
3 use wcf\system\form\builder\IFormDocument;
4
5 /**
6 * Field data processor implementation that supports a custom processor callable.
7 *
8 * @author Matthias Schmidt
9 * @copyright 2001-2019 WoltLab GmbH
10 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
11 * @package WoltLabSuite\Core\System\Form\Builder\Field\Data\Processor
12 * @since 5.2
13 */
14 class CustomFormFieldDataProcessor implements IFormFieldDataProcessor {
15 /**
16 * processor id primarily used for error messages
17 * @var string
18 */
19 protected $id;
20
21 /**
22 * callable processing the data
23 * @var callable
24 */
25 protected $processor;
26
27 /**
28 * Initializes a new CustomFormFieldDataProcessor object.
29 *
30 * @param string $id processor id primarily used for error messages, does not have to be unique
31 * @param callable $processor processor callable
32 *
33 * @throws \InvalidArgumentException if either id or processor callable are invalid
34 */
35 public function __construct($id, callable $processor) {
36 if (preg_match('~^[a-z][A-z0-9-]*$~', $id) !== 1) {
37 throw new \InvalidArgumentException("Invalid id '{$id}' given.");
38 }
39
40 $this->id = $id;
41
42 // validate processor function
43 $parameters = (new \ReflectionFunction($processor))->getParameters();
44 if (count($parameters) !== 2) {
45 throw new \InvalidArgumentException(
46 "The processor function must expect two parameters, instead " . count($parameters) .
47 " parameter" . (count($parameters) !== 1 ? 's' : '') . " are expected."
48 );
49 }
50
51 /** @var \ReflectionClass $parameterClass */
52 $parameterClass = $parameters[0]->getClass();
53 if ($parameterClass === null || ($parameterClass->getName() !== IFormDocument::class && !is_subclass_of($parameterClass->getName(), IFormDocument::class))) {
54 throw new \InvalidArgumentException(
55 "The processor function's first parameter must be an instance of '" . IFormDocument::class . "', instead " .
56 ($parameterClass === null ? 'any' : "'" . $parameterClass->getName() . "'") . " parameter is expected."
57 );
58 }
59 if (!$parameters[1]->isArray()) {
60 throw new \InvalidArgumentException("The processor function's second parameter must be an array.");
61 }
62
63 $this->processor = $processor;
64 }
65
66 /**
67 * @inheritDoc
68 */
69 public function __invoke(IFormDocument $document, array $parameters) {
70 $parameters = call_user_func($this->processor, $document, $parameters);
71
72 if (!is_array($parameters)) {
73 throw new \UnexpectedValueException("Field data processor '{$this->id}' does not return an array.");
74 }
75
76 return $parameters;
77 }
78 }