i.e. processing form data to be used by a DBOAction and processing object data to be used as form field values.
Close #2988
use wcf\data\language\item\LanguageItemList;
use wcf\form\AbstractFormBuilderForm;
use wcf\system\form\builder\container\FormContainer;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
-use wcf\system\form\builder\field\data\processor\VoidFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
+use wcf\system\form\builder\data\processor\VoidFormDataProcessor;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\MultilineTextFormField;
use wcf\system\form\builder\field\RadioButtonFormField;
// `languageCategoryIDMode` is an internal field not meant to be
// treated as real data
- $this->form->getDataHandler()->add(new VoidFormFieldDataProcessor('languageCategoryIDMode'));
+ $this->form->getDataHandler()->addProcessor(new VoidFormDataProcessor('languageCategoryIDMode'));
- $this->form->getDataHandler()->add(
- new CustomFormFieldDataProcessor('languageItemOriginIsSystem', function(IFormDocument $document, array $parameters) {
+ $this->form->getDataHandler()->addProcessor(
+ new CustomFormDataProcessor('languageItemOriginIsSystem', function(IFormDocument $document, array $parameters) {
$parameters['data']['languageItemOriginIsSystem'] = 0;
$parameters['data']['isCustomLanguageItem'] = 1;
}
/**
- * @deprecated This method was introduced for a function in AJAXProxy that is deprecated.
- * @see \wcf\data\IStorableObject::getData()
+ * @inheritDoc
*/
public function getData() {
return $this->data;
/**
* Returns the value of all object data variables.
*
- * @deprecated This method was introduced for a function in AJAXProxy that is deprecated.
* @return mixed[]
*/
public function getData();
use wcf\system\form\builder\container\IFormContainer;
use wcf\system\form\builder\data\FormDataHandler;
use wcf\system\form\builder\data\IFormDataHandler;
-use wcf\system\form\builder\field\data\processor\DefaultFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\DefaultFormDataProcessor;
use wcf\system\form\builder\field\IFileFormField;
use wcf\system\form\builder\field\IFormField;
use wcf\system\WCF;
throw new \BadMethodCallException("Getting data is only possible after calling 'readValues()'.");
}
- return $this->getDataHandler()->getData($this);
+ return $this->getDataHandler()->getFormData($this);
}
/**
public function getDataHandler() {
if ($this->dataHandler === null) {
$this->dataHandler = new FormDataHandler();
- $this->dataHandler->add(new DefaultFormFieldDataProcessor());
+ $this->dataHandler->addProcessor(new DefaultFormDataProcessor());
}
return $this->dataHandler;
$this->formMode(self::FORM_MODE_UPDATE);
}
+ $data = $this->getDataHandler()->getObjectData($this, $object);
+
/** @var IFormNode $node */
foreach ($this->getIterator() as $node) {
if ($node->isAvailable()) {
if ($node instanceof IFormField) {
if ($node->getObjectProperty() !== $node->getId()) {
try {
- $node->loadValueFromObject($object);
+ $node->loadValue($data, $object);
}
catch (\InvalidArgumentException $e) {
// if an object property is explicitly set,
}
}
else {
- $node->loadValueFromObject($object);
+ $node->loadValue($data, $object);
}
}
else if ($node instanceof IFormContainer) {
- $node->loadValuesFromObject($object);
+ $node->loadValues($data, $object);
}
}
}
/**
* @inheritDoc
*/
- public function loadValuesFromObject(IStorableObject $object) {
+ public function loadValues(array $data, IStorableObject $object) {
// does nothing
return $this;
*/
interface IFormContainer extends IFormChildNode, IFormElement, IFormParentNode {
/**
- * This method is called by `IFormDocument::loadValuesFromObject()` to inform the container
- * that object data is loaded.
+ * This method is called by `IFormDocument::loadValue()` to inform the container that object
+ * data is being loaded.
*
- * This method is *not* intended to generally call `IFormField::loadValueFromObject()` on
- * its form field children as these methods are already called by `IFormDocument::loadValuesFromObject()`.
- *
- * @param IStorableObject $object object used to load field values
+ * This method is *not* intended to generally call `IFormField::loadValue()` on its form field
+ * children as these methods are already called by `IFormDocument::loadValuesFromObject()`.
+ *
+ * @param array $data data from which the values are extracted
+ * @param IStorableObject $object object the data belongs to
* @return static this container
*/
- public function loadValuesFromObject(IStorableObject $object);
+ public function loadValues(array $data, IStorableObject $object);
}
/**
* @inheritDoc
*/
- public function loadValuesFromObject(IStorableObject $object) {
- $this->objectId = $object->getObjectID();
+ public function loadValues(array $data, IStorableObject $object) {
+ $this->objectId = $object->{$object::getDatabaseTableIndexName()};
if ($this->attachmentData !== null) {
// updated attachment handler with object id
);
}
- return parent::loadValuesFromObject($object);
+ return parent::loadValues($data, $object);
}
/**
use wcf\data\IStorableObject;
use wcf\data\poll\Poll;
use wcf\system\form\builder\container\FormContainer;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\BooleanFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\DateFormField;
use wcf\system\form\builder\field\IntegerFormField;
use wcf\system\form\builder\field\poll\PollOptionsFormField;
/**
* @inheritDoc
*/
- public function loadValuesFromObject(IStorableObject $object) {
- if ($object instanceof IPollContainer && $object->getPollID() !== null) {
- $this->poll = new Poll($object->getPollID());
+ public function loadValues(array $data, IStorableObject $object) {
+ if ($data instanceof IPollContainer && $data->getPollID() !== null) {
+ $this->poll = new Poll($data->getPollID());
if (!$this->poll->pollID) {
$this->poll = null;
}
$this->getSortByVotesField()->value($this->poll->sortByVotes);
}
- return parent::loadValuesFromObject($object);
+ return parent::loadValues($data, $object);
}
/**
$id = $this->wysiwygId . 'Poll';
// add data handler to group poll data into a sub-array of parameters
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor($id, function(IFormDocument $document, array $parameters) use($id) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor($id, function(IFormDocument $document, array $parameters) use($id) {
if (!$this->isAvailable()) {
return $parameters;
}
<?php
namespace wcf\system\form\builder\data;
-use wcf\system\form\builder\field\data\processor\IFormFieldDataProcessor;
+use wcf\data\IStorableObject;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
+use wcf\system\form\builder\data\processor\IFormDataProcessor;
use wcf\system\form\builder\IFormDocument;
/**
class FormDataHandler implements IFormDataHandler {
/**
* field data processors
- * @var IFormFieldDataProcessor[]
+ * @var IFormDataProcessor[]
*/
protected $processors = [];
/**
* @inheritDoc
*/
- public function add(IFormFieldDataProcessor $processor) {
+ public function addProcessor(IFormDataProcessor $processor) {
$this->processors[] = $processor;
return $this;
/**
* @inheritDoc
*/
- public function getData(IFormDocument $document) {
+ public function getFormData(IFormDocument $document) {
$parameters = [];
foreach ($this->processors as $processor) {
- $parameters = $processor($document, $parameters);
+ $parameters = $processor->processFormData($document, $parameters);
+
+ if (!is_array($parameters)) {
+ if ($processor instanceof CustomFormDataProcessor) {
+ throw new \UnexpectedValueException("Custom data processor '{$processor->getId()}' does not return an array when processing form data.");
+ }
+ else {
+ throw new \UnexpectedValueException("Data processor '" . get_class($processor) . "' does not return an array when processing form data.");
+ }
+ }
}
return $parameters;
}
+
+ /**
+ * @inheritDoc
+ */
+ public function getObjectData(IFormDocument $document, IStorableObject $object) {
+ $data = $object->getData();
+ $objectId = $object->{$object::getDatabaseTableIndexName()};
+ foreach ($this->processors as $processor) {
+ $data = $processor->processObjectData($document, $data, $objectId);
+
+ if (!is_array($data)) {
+ if ($processor instanceof CustomFormDataProcessor) {
+ throw new \UnexpectedValueException("Custom data processor '{$processor->getId()}' does not return an array when processing object data.");
+ }
+ else {
+ throw new \UnexpectedValueException("Data processor '" . get_class($processor) . "' does not return an array when processing object data.");
+ }
+ }
+ }
+
+ return $data;
+ }
}
<?php
namespace wcf\system\form\builder\data;
-use wcf\system\form\builder\field\data\processor\IFormFieldDataProcessor;
+use wcf\data\IStorableObject;
+use wcf\system\form\builder\data\processor\IFormDataProcessor;
use wcf\system\form\builder\IFormDocument;
/**
* Adds the given field data processor to this data handler and returns
* this data handler.
*
- * @param IFormFieldDataProcessor $processor added field data processor
+ * @param IFormDataProcessor $processor added field data processor
+ *
* @return static this data handler
*/
- public function add(IFormFieldDataProcessor $processor);
+ public function addProcessor(IFormDataProcessor $processor);
/**
* Returns the data from the given form that is passed as the parameters
* @param IFormDocument $document processed form document
* @return array data passed to database object action
*/
- public function getData(IFormDocument $document);
+ public function getFormData(IFormDocument $document);
+
+ /**
+ * Returns the processed data of the given object that will be used to set the form fields'
+ * value.
+ *
+ * @param IFormDocument $document form document whose form field values will be set
+ * @param IStorableObject $object object from which the data is extracted
+ * @return array processed object data
+ */
+ public function getObjectData(IFormDocument $document, IStorableObject $object);
}
--- /dev/null
+<?php
+namespace wcf\system\form\builder\data\processor;
+use wcf\system\form\builder\IFormDocument;
+
+/**
+ * Abstract implementation of a form field data processor that provides default implementations
+ * of the required methods.
+ *
+ * Instead of implementing `IFormFieldDataProcessor` directly, this abstract class should be extended.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Form\Builder\Data\Processor
+ * @since 5.2
+ */
+abstract class AbstractFormDataProcessor implements IFormDataProcessor {
+ /**
+ * @inheritDoc
+ */
+ public function processFormData(IFormDocument $document, array $parameters) {
+ return $parameters;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function processObjectData(IFormDocument $document, array $data, $objectId = null) {
+ return $data;
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\form\builder\data\processor;
+use wcf\system\form\builder\IFormDocument;
+
+/**
+ * Field data processor implementation that supports a custom processor callable.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Form\Builder\Data\Processor
+ * @since 5.2
+ */
+class CustomFormDataProcessor extends AbstractFormDataProcessor {
+ /**
+ * callable processing the form data
+ * @var callable
+ */
+ protected $formDataProcessor;
+
+ /**
+ * processor id primarily used for error messages
+ * @var string
+ */
+ protected $id;
+
+ /**
+ * callable processing the object data
+ * @var callable
+ */
+ protected $objectDataProcessor;
+
+ /**
+ * Initializes a new CustomFormFieldDataProcessor object.
+ *
+ * @param string $id processor id primarily used for error messages, does not have to be unique
+ * @param callable $formDataProcessor form data processor callable
+ * @param callable $objectDataProcessor object data processor callable
+ *
+ * @throws \InvalidArgumentException if either id or processor callable are invalid
+ */
+ public function __construct($id, callable $formDataProcessor = null, callable $objectDataProcessor = null) {
+ if (preg_match('~^[a-z][A-z0-9-]*$~', $id) !== 1) {
+ throw new \InvalidArgumentException("Invalid id '{$id}' given.");
+ }
+
+ $this->id = $id;
+
+ if ($formDataProcessor === null && $objectDataProcessor === null) {
+ throw new \InvalidArgumentException("No processors given.");
+ }
+
+ // validate form data processor function
+ if ($formDataProcessor !== null) {
+ $parameters = (new \ReflectionFunction($formDataProcessor))->getParameters();
+ if (count($parameters) !== 2) {
+ throw new \InvalidArgumentException(
+ "The form data processor function must expect two parameters, instead " . count($parameters) .
+ " parameter" . (count($parameters) !== 1 ? 's' : '') . " are expected."
+ );
+ }
+
+ /** @var \ReflectionClass $parameterClass */
+ $parameterClass = $parameters[0]->getClass();
+ if ($parameterClass === null || ($parameterClass->getName() !== IFormDocument::class && !is_subclass_of($parameterClass->getName(), IFormDocument::class))) {
+ throw new \InvalidArgumentException(
+ "The form data processor function's first parameter must be an instance of '" . IFormDocument::class . "', instead " .
+ ($parameterClass === null ? 'any' : "'" . $parameterClass->getName() . "'") . " parameter is expected."
+ );
+ }
+ if (!$parameters[1]->isArray()) {
+ throw new \InvalidArgumentException("The form data processor function's second parameter must be an array.");
+ }
+
+ $this->formDataProcessor = $formDataProcessor;
+ }
+
+ // validate object data processor function
+ if ($objectDataProcessor !== null) {
+ $parameters = (new \ReflectionFunction($objectDataProcessor))->getParameters();
+ if (count($parameters) !== 3) {
+ throw new \InvalidArgumentException(
+ "The object data processor function must expect three parameters, instead " . count($parameters) .
+ " parameter" . (count($parameters) !== 1 ? 's' : '') . " are expected."
+ );
+ }
+
+ /** @var \ReflectionClass $parameterClass */
+ $parameterClass = $parameters[0]->getClass();
+ if ($parameterClass === null || ($parameterClass->getName() !== IFormDocument::class && !is_subclass_of($parameterClass->getName(), IFormDocument::class))) {
+ throw new \InvalidArgumentException(
+ "The object data processor function's first parameter must be an instance of '" . IFormDocument::class . "', instead " .
+ ($parameterClass === null ? 'any' : "'" . $parameterClass->getName() . "'") . " parameter is expected."
+ );
+ }
+ if (!$parameters[1]->isArray()) {
+ throw new \InvalidArgumentException("The object data processor function's second parameter must be an array.");
+ }
+
+ $this->objectDataProcessor = $objectDataProcessor;
+ }
+ }
+
+ /**
+ * Returns the id of the data processor (which is primarily used for error messages).
+ *
+ * @return string
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function processFormData(IFormDocument $document, array $parameters) {
+ if ($this->formDataProcessor === null) {
+ return parent::processFormData($document, $parameters);
+ }
+
+ $parameters = call_user_func($this->formDataProcessor, $document, $parameters);
+
+ if (!is_array($parameters)) {
+ throw new \UnexpectedValueException("Field data processor '{$this->id}' does not return an array.");
+ }
+
+ return $parameters;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function processObjectData(IFormDocument $document, array $data, $objectId = null) {
+ if ($this->objectDataProcessor === null) {
+ return parent::processObjectData($document, $data, $objectId);
+ }
+
+ $data = call_user_func($this->objectDataProcessor, $document, $data, $objectId);
+
+ if (!is_array($data)) {
+ throw new \UnexpectedValueException("Field data processor '{$this->id}' does not return an array.");
+ }
+
+ return $data;
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\form\builder\data\processor;
+use wcf\system\form\builder\field\IFormField;
+use wcf\system\form\builder\IFormDocument;
+use wcf\system\form\builder\IFormNode;
+use wcf\system\form\builder\IFormParentNode;
+
+/**
+ * Default field data processor that maps the form fields to entries in
+ * the `data` sub-array with the field ids as array keys and field values
+ * as array values.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Form\Builder\Data\Processor
+ * @since 5.2
+ */
+class DefaultFormDataProcessor extends AbstractFormDataProcessor {
+ /**
+ * @inheritDoc
+ */
+ public function processFormData(IFormDocument $document, array $parameters) {
+ $parameters['data'] = [];
+
+ $this->getData($document, $parameters['data']);
+
+ return $parameters;
+ }
+
+ /**
+ * Fetches all data from the given node and stores it in the given array.
+ *
+ * @param IFormNode $node node whose data will be fetched
+ * @param array $data data storage
+ */
+ protected function getData(IFormNode $node, array &$data) {
+ if ($node->isAvailable() && $node->checkDependencies()) {
+ if ($node instanceof IFormParentNode) {
+ foreach ($node as $childNode) {
+ $this->getData($childNode, $data);
+ }
+ }
+ else if ($node instanceof IFormField && $node->isAvailable() && $node->hasSaveValue()) {
+ $data[$node->getObjectProperty()] = $node->getSaveValue();
+ }
+ }
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\form\builder\data\processor;
+use wcf\system\form\builder\IFormDocument;
+
+/**
+ * Represents a data processor for forms that can be used to process certain form field values
+ * before they are stored in database and process these values back again when an object is edited
+ * the the form field values need to be set.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Form\Builder\Data\Processor
+ * @since 5.2
+ */
+interface IFormDataProcessor {
+ /**
+ * Processes the given parameters array and returns the processed version of it that will be
+ * passed to the constructor of a database object action.
+ *
+ * @param IFormDocument $document documents whose field data is processed
+ * @param array $parameters parameters before processing
+ * @return array parameters after processing
+ */
+ public function processFormData(IFormDocument $document, array $parameters);
+
+ /**
+ * Processes the given object data and returns the processed version of it that will be used
+ * to set the form field values.
+ *
+ * @param IFormDocument $document documents whose field values will be set using the processed data
+ * @param array $data data before processing
+ * @param null|integer $objectId id of the object the data belongs to
+ * @return array data after processing
+ */
+ public function processObjectData(IFormDocument $document, array $data, $objectId = null);
+}
--- /dev/null
+<?php
+namespace wcf\system\form\builder\data\processor;
+use wcf\system\form\builder\IFormDocument;
+
+/**
+ * Field data processor implementation that voids a certain data property.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Form\Builder\Data\Processor
+ * @since 5.2
+ */
+class VoidFormDataProcessor extends AbstractFormDataProcessor {
+ /**
+ * is `true` if the property is stored in the `data` array
+ * @var bool
+ */
+ protected $isDataProperty;
+
+ /**
+ * name of the voided property
+ * @var string
+ */
+ protected $property;
+
+ /**
+ * Initializes a new CustomFormFieldDataProcessor object.
+ *
+ * @param string $property name of the voided property
+ * @param bool $isDataProperty is `true` if the property is stored in the `data` array
+ */
+ public function __construct($property, $isDataProperty = true) {
+ $this->property = $property;
+ $this->isDataProperty = $isDataProperty;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function processFormData(IFormDocument $document, array $parameters) {
+ if ($this->isDataProperty) {
+ if (isset($parameters['data'][$this->property])) {
+ unset($parameters['data'][$this->property]);
+ }
+ }
+ else if (isset($parameters[$this->property])) {
+ unset($parameters[$this->property]);
+ }
+
+ return $parameters;
+ }
+}
/**
* @inheritDoc
*/
- public function loadValueFromObject(IStorableObject $object) {
- if (isset($object->{$this->getObjectProperty()})) {
- $this->value($object->{$this->getObjectProperty()});
+ public function loadValue(array $data, IStorableObject $object) {
+ if (isset($data[$this->getObjectProperty()])) {
+ $this->value($data[$this->getObjectProperty()]);
}
return $this;
public function isRequired();
/**
- * Loads the field value from the given object and returns this field.
+ * Loads the field value from the given data and returns this field.
*
- * @param IStorableObject $object object used to load field value
+ * It is important to extract the value from the `$data` array instead of getting it directly
+ * from the object as the entries of `$data` have been processed by the data processors.
+ *
+ * @param array $data data from which the value is extracted
+ * @param IStorableObject $object object the data belongs to
* @return static this field
*/
- public function loadValueFromObject(IStorableObject $object);
+ public function loadValue(array $data, IStorableObject $object);
/**
* Sets the name of the object property this field represents. If an empty
<?php
namespace wcf\system\form\builder\field;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\validation\FormFieldValidationError;
use wcf\system\form\builder\IFormDocument;
use wcf\util\ArrayUtil;
// an array should be passed as a parameter outside of the `data` array
if ($this->getSaveValueType() === self::SAVE_VALUE_TYPE_ARRAY) {
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('itemList', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('itemList', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies() && is_array($this->getValue())) {
$parameters[$this->getObjectProperty()] = $this->getValue();
}
<?php
namespace wcf\system\form\builder\field;
-use wcf\data\language\item\LanguageItemList;
use wcf\data\IStorableObject;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\data\language\item\LanguageItemList;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\validation\FormFieldValidationError;
use wcf\system\form\builder\IFormDocument;
use wcf\system\form\builder\IFormNode;
/**
* @inheritDoc
*/
- public function loadValueFromObject(IStorableObject $object) {
- if (isset($object->{$this->getId()})) {
- $value = $object->{$this->getId()};
+ public function loadValueFromObject(array $data, IStorableObject $object) {
+ if (isset($data[$this->getObjectProperty()])) {
+ $value = $data[$this->getObjectProperty()];
if ($this->isI18n()) {
// do not use `I18nHandler::setOptions()` because then `I18nHandler` only
/** @var IFormDocument $document */
$document = $this->getDocument();
- $document->getDataHandler()->add(new CustomFormFieldDataProcessor('i18n', function(IFormDocument $document, array $parameters) {
+ $document->getDataHandler()->addProcessor(new CustomFormDataProcessor('i18n', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies() && $this->hasI18nValues()) {
$parameters[$this->getObjectProperty() . '_i18n'] = $this->getValue();
}
<?php
namespace wcf\system\form\builder\field;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\IFormDocument;
/**
parent::populate();
if ($this->allowsMultiple()) {
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('multiple', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->add(new CustomFormDataProcessor('multiple', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies() && !empty($this->getValue())) {
$parameters[$this->getObjectProperty()] = $this->getValue();
}
use wcf\system\file\upload\UploadField;
use wcf\system\file\upload\UploadFile;
use wcf\system\file\upload\UploadHandler;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\validation\FormFieldValidationError;
use wcf\system\form\builder\IFormDocument;
*
* @throws \InvalidArgumentException if the getter for the value provides invalid values
*/
- public function loadValueFromObject(IStorableObject $object) {
+ public function loadValue(array $data, IStorableObject $object) {
// first check, whether an getter for the field exists
if (method_exists($object, 'get'. ucfirst($this->getObjectProperty()) . 'UploadFileLocations')) {
$value = call_user_func([$object, 'get'. ucfirst($this->getObjectProperty()) . 'UploadFileLocations']);
$method = "method '" . get_class($object) . "::get" . ucfirst($this->getObjectProperty()) . "()'";
}
else {
- $value = $object->{$this->getObjectProperty()};
+ $value = $data[$this->getObjectProperty()];
$method = "variable '" . get_class($object) . "::$" . $this->getObjectProperty() . "'";
}
UploadHandler::getInstance()->registerFilesByField($this->getPrefixedId(), $this->values);
}
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('upload', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('upload', function(IFormDocument $document, array $parameters) {
$parameters[$this->getObjectProperty()] = $this->getValue();
$parameters[$this->getObjectProperty() . '_removedFiles'] = $this->getRemovedFiles(true);
namespace wcf\system\form\builder\field\acl;
use wcf\data\IStorableObject;
use wcf\system\acl\ACLHandler;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\IFormDocument;
use wcf\system\form\builder\IObjectTypeFormNode;
use wcf\system\form\builder\TObjectTypeFormNode;
/**
* @inheritDoc
*/
- public function loadValueFromObject(IStorableObject $object) {
+ public function loadValue(array $data, IStorableObject $object) {
$this->objectID = $object->{$object::getDatabaseTableIndexName()};
if ($this->objectID === null) {
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('acl', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('acl', function(IFormDocument $document, array $parameters) {
$parameters[$this->getObjectProperty() . '_aclObjectTypeID'] = $this->getObjectType()->objectTypeID;
return $parameters;
<?php
namespace wcf\system\form\builder\field\acl\simple;
use wcf\system\acl\simple\SimpleAclHandler;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\IFormDocument;
/**
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('i18n', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('i18n', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies() && is_array($this->getValue()) && !empty($this->getValue())) {
$parameters[$this->getObjectProperty()] = $this->getValue();
}
+++ /dev/null
-<?php
-namespace wcf\system\form\builder\field\data\processor;
-use wcf\system\form\builder\IFormDocument;
-
-/**
- * Field data processor implementation that supports a custom processor callable.
- *
- * @author Matthias Schmidt
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Form\Builder\Field\Data\Processor
- * @since 5.2
- */
-class CustomFormFieldDataProcessor implements IFormFieldDataProcessor {
- /**
- * processor id primarily used for error messages
- * @var string
- */
- protected $id;
-
- /**
- * callable processing the data
- * @var callable
- */
- protected $processor;
-
- /**
- * Initializes a new CustomFormFieldDataProcessor object.
- *
- * @param string $id processor id primarily used for error messages, does not have to be unique
- * @param callable $processor processor callable
- *
- * @throws \InvalidArgumentException if either id or processor callable are invalid
- */
- public function __construct($id, callable $processor) {
- if (preg_match('~^[a-z][A-z0-9-]*$~', $id) !== 1) {
- throw new \InvalidArgumentException("Invalid id '{$id}' given.");
- }
-
- $this->id = $id;
-
- // validate processor function
- $parameters = (new \ReflectionFunction($processor))->getParameters();
- if (count($parameters) !== 2) {
- throw new \InvalidArgumentException(
- "The processor function must expect two parameters, instead " . count($parameters) .
- " parameter" . (count($parameters) !== 1 ? 's' : '') . " are expected."
- );
- }
-
- /** @var \ReflectionClass $parameterClass */
- $parameterClass = $parameters[0]->getClass();
- if ($parameterClass === null || ($parameterClass->getName() !== IFormDocument::class && !is_subclass_of($parameterClass->getName(), IFormDocument::class))) {
- throw new \InvalidArgumentException(
- "The processor function's first parameter must be an instance of '" . IFormDocument::class . "', instead " .
- ($parameterClass === null ? 'any' : "'" . $parameterClass->getName() . "'") . " parameter is expected."
- );
- }
- if (!$parameters[1]->isArray()) {
- throw new \InvalidArgumentException("The processor function's second parameter must be an array.");
- }
-
- $this->processor = $processor;
- }
-
- /**
- * @inheritDoc
- */
- public function __invoke(IFormDocument $document, array $parameters) {
- $parameters = call_user_func($this->processor, $document, $parameters);
-
- if (!is_array($parameters)) {
- throw new \UnexpectedValueException("Field data processor '{$this->id}' does not return an array.");
- }
-
- return $parameters;
- }
-}
+++ /dev/null
-<?php
-namespace wcf\system\form\builder\field\data\processor;
-use wcf\system\form\builder\field\IFormField;
-use wcf\system\form\builder\IFormDocument;
-use wcf\system\form\builder\IFormNode;
-use wcf\system\form\builder\IFormParentNode;
-
-/**
- * Default field data processor that maps the form fields to entries in
- * the `data` sub-array with the field ids as array keys and field values
- * as array values.
- *
- * @author Matthias Schmidt
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Form\Builder\Field\Data\Processor
- * @since 5.2
- */
-class DefaultFormFieldDataProcessor implements IFormFieldDataProcessor {
- /**
- * @inheritDoc
- */
- public function __invoke(IFormDocument $document, array $parameters) {
- $parameters['data'] = [];
-
- $this->getData($document, $parameters['data']);
-
- return $parameters;
- }
-
- /**
- * Fetches all data from the given node and stores it in the given array.
- *
- * @param IFormNode $node node whose data will be fetched
- * @param array $data data storage
- */
- protected function getData(IFormNode $node, array &$data) {
- if ($node->isAvailable() && $node->checkDependencies()) {
- if ($node instanceof IFormParentNode) {
- foreach ($node as $childNode) {
- $this->getData($childNode, $data);
- }
- }
- else if ($node instanceof IFormField && $node->isAvailable() && $node->hasSaveValue()) {
- $data[$node->getObjectProperty()] = $node->getSaveValue();
- }
- }
- }
-}
+++ /dev/null
-<?php
-namespace wcf\system\form\builder\field\data\processor;
-use wcf\system\form\builder\IFormDocument;
-
-/**
- * Represents a data processor for form fields that populates or manipulates the
- * parameters array passed to the constructor of a database object action.
- *
- * @author Matthias Schmidt
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Form\Builder\Field\Data\Processor
- * @since 5.2
- */
-interface IFormFieldDataProcessor {
- /**
- * Processes the given parameters array and returns the processed version of it.
- *
- * @param IFormDocument $document documents whose field data is processed
- * @param array $parameters parameters before processing
- * @return array parameters after processing
- */
- public function __invoke(IFormDocument $document, array $parameters);
-}
+++ /dev/null
-<?php
-namespace wcf\system\form\builder\field\data\processor;
-use wcf\system\form\builder\IFormDocument;
-
-/**
- * Field data processor implementation that voids a certain data property.
- *
- * @author Matthias Schmidt
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Form\Builder\Field\Data\Processor
- * @since 5.2
- */
-class VoidFormFieldDataProcessor implements IFormFieldDataProcessor {
- /**
- * is `true` if the property is stored in the `data` array
- * @var bool
- */
- protected $isDataProperty;
-
- /**
- * name of the voided property
- * @var string
- */
- protected $property;
-
- /**
- * Initializes a new CustomFormFieldDataProcessor object.
- *
- * @param string $property name of the voided property
- * @param bool $isDataProperty is `true` if the property is stored in the `data` array
- */
- public function __construct($property, $isDataProperty = true) {
- $this->property = $property;
- $this->isDataProperty = $isDataProperty;
- }
-
- /**
- * @inheritDoc
- */
- public function __invoke(IFormDocument $document, array $parameters) {
- if ($this->isDataProperty) {
- if (isset($parameters['data'][$this->property])) {
- unset($parameters['data'][$this->property]);
- }
- }
- else if (isset($parameters[$this->property])) {
- unset($parameters[$this->property]);
- }
-
- return $parameters;
- }
-}
use wcf\data\IStorableObject;
use wcf\data\label\group\ViewableLabelGroup;
use wcf\data\label\Label;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\validation\FormFieldValidationError;
use wcf\system\form\builder\IFormDocument;
use wcf\system\form\builder\IObjectTypeFormNode;
/**
* @inheritDoc
*/
- public function loadValueFromObject(IStorableObject $object) {
+ public function loadValue(array $data, IStorableObject $object) {
$objectTypeID = $this->getObjectType()->objectTypeID;
- $objectID = $object->getObjectID();
+ $objectID = $object->{$object::getDatabaseTableIndexName()};
if (!isset(static::$loadedLabels[$objectTypeID])) {
static::$loadedLabels[$objectTypeID] = [];
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('label', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('label', function(IFormDocument $document, array $parameters) {
$value = $this->getValue();
// `-1` and `0` are special values that are irrlevent for saving
<?php
namespace wcf\system\form\builder\field\tag;
-use wcf\data\tag\Tag;
use wcf\data\IStorableObject;
+use wcf\data\tag\Tag;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\TDefaultIdFormField;
use wcf\system\form\builder\IFormDocument;
use wcf\system\form\builder\IObjectTypeFormNode;
/**
* @inheritDoc
*/
- public function loadValueFromObject(IStorableObject $object) {
+ public function loadValue(array $data, IStorableObject $object) {
$objectID = $object->{$object::getDatabaseTableIndexName()};
if ($objectID === null) {
$languageIDs = [];
/** @noinspection PhpUndefinedFieldInspection */
- $objectLanguageId = $object->languageID;
- if ($objectLanguageId !== null) {
- $languageIDs[] = $objectLanguageId;
+ if (isset($data['languageID'])) {
+ $languageIDs[] = $data['languageID'];
}
$tags = TagEngine::getInstance()->getObjectTags($this->getObjectType()->objectType, $objectID, $languageIDs);
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('acl', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('acl', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies() && $this->getValue() !== null && !empty($this->getValue())) {
$parameters[$this->getObjectProperty()] = $this->getValue();
}
<?php
namespace wcf\system\form\builder\field\wysiwyg;
use wcf\system\attachment\AttachmentHandler;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\IFormDocument;
use wcf\system\form\builder\TWysiwygFormNode;
use wcf\system\WCF;
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor($this->getId(), function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor($this->getId(), function(IFormDocument $document, array $parameters) {
if ($this->getAttachmentHandler() !== null) {
$parameters[$this->getWysiwygId() . '_attachmentHandler'] = $this->getAttachmentHandler();
}
namespace wcf\system\form\builder\field\wysiwyg;
use wcf\data\IMessageQuoteAction;
use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\AbstractFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\IMaximumLengthFormField;
use wcf\system\form\builder\field\IMinimumLengthFormField;
use wcf\system\form\builder\field\TMaximumLengthFormField;
public function populate() {
parent::populate();
- $this->getDocument()->getDataHandler()->add(new CustomFormFieldDataProcessor('wysiwyg', function(IFormDocument $document, array $parameters) {
+ $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('wysiwyg', function(IFormDocument $document, array $parameters) {
if ($this->checkDependencies()) {
$parameters[$this->getObjectProperty() . '_htmlInputProcessor'] = $this->htmlInputProcessor;
}
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
use wcf\system\exception\SystemException;
use wcf\system\form\builder\container\IFormContainer;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\BooleanFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\IntegerFormField;
use wcf\system\form\builder\field\MultilineTextFormField;
]);
// ensure proper normalization of default value and enable options
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('enableOptions', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('enableOptions', function(IFormDocument $document, array $parameters) {
if (isset($parameters['data']['enableoptions'])) {
$parameters['data']['enableoptions'] = StringUtil::unifyNewlines($parameters['data']['enableoptions']);
}
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
use wcf\system\exception\SystemException;
use wcf\system\form\builder\container\FormContainer;
+use wcf\system\form\builder\data\processor\VoidFormDataProcessor;
use wcf\system\form\builder\field\bbcode\BBCodeAttributesFormField;
use wcf\system\form\builder\field\BooleanFormField;
use wcf\system\form\builder\field\ClassNameFormField;
-use wcf\system\form\builder\field\data\processor\VoidFormFieldDataProcessor;
use wcf\system\form\builder\field\dependency\NonEmptyFormFieldDependency;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\IconFormField;
);
// discard the `iconType` value as it is only used to distinguish the two icon input fields
- $form->getDataHandler()->add(new VoidFormFieldDataProcessor('iconType'));
+ $form->getDataHandler()->addProcessor(new VoidFormDataProcessor('iconType'));
}
/**
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
use wcf\system\form\builder\container\FormContainer;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\ClassNameFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\MultilineTextFormField;
use wcf\system\form\builder\field\TextFormField;
use wcf\system\form\builder\field\TitleFormField;
}))
]);
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('unifyNewlines', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('unifyNewlines', function(IFormDocument $document, array $parameters) {
$parameters['data']['regex'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['regex']));
$parameters['data']['html'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['html']));
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\exception\SystemException;
use wcf\system\form\builder\container\IFormContainer;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\BooleanFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\dependency\NonEmptyFormFieldDependency;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\MultilineTextFormField;
]);
// ensure proper normalization of select options
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('selectOptions', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('selectOptions', function(IFormDocument $document, array $parameters) {
if (isset($parameters['data']['selectoptions'])) {
$parameters['data']['selectoptions'] = StringUtil::unifyNewlines($parameters['data']['selectoptions']);
}
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
use wcf\system\form\builder\container\FormContainer;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\IntegerFormField;
use wcf\system\form\builder\field\ItemListFormField;
use wcf\system\form\builder\field\TextFormField;
]);
// ensure proper normalization of template code
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('templateCode', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('templateCode', function(IFormDocument $document, array $parameters) {
$parameters['data']['aliases'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['aliases']));
return $parameters;
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
use wcf\system\form\builder\container\FormContainer;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\IntegerFormField;
+use wcf\system\form\builder\field\MultilineTextFormField;
use wcf\system\form\builder\field\option\OptionFormField;
+use wcf\system\form\builder\field\SingleSelectionFormField;
+use wcf\system\form\builder\field\TextFormField;
use wcf\system\form\builder\field\user\group\option\UserGroupOptionFormField;
use wcf\system\form\builder\field\validation\FormFieldValidationError;
use wcf\system\form\builder\field\validation\FormFieldValidator;
-use wcf\system\form\builder\field\MultilineTextFormField;
-use wcf\system\form\builder\field\SingleSelectionFormField;
-use wcf\system\form\builder\field\TextFormField;
use wcf\system\form\builder\IFormDocument;
use wcf\system\WCF;
use wcf\util\StringUtil;
]);
// ensure proper normalization of template code
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('templateCode', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('templateCode', function(IFormDocument $document, array $parameters) {
$parameters['data']['templatecode'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['templatecode']));
return $parameters;
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\exception\SystemException;
use wcf\system\form\builder\container\IFormContainer;
+use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
use wcf\system\form\builder\field\BooleanFormField;
use wcf\system\form\builder\field\ClassNameFormField;
-use wcf\system\form\builder\field\data\processor\CustomFormFieldDataProcessor;
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
use wcf\system\form\builder\field\MultilineTextFormField;
use wcf\system\form\builder\field\SingleSelectionFormField;
]);
// ensure proper normalization of select options
- $form->getDataHandler()->add(new CustomFormFieldDataProcessor('selectOptions', function(IFormDocument $document, array $parameters) {
+ $form->getDataHandler()->addProcessor(new CustomFormDataProcessor('selectOptions', function(IFormDocument $document, array $parameters) {
if (isset($parameters['data']['selectoptions'])) {
$parameters['data']['selectoptions'] = StringUtil::unifyNewlines($parameters['data']['selectoptions']);
}