Rework form data processors to allow data processing in both directions
authorMatthias Schmidt <gravatronics@live.com>
Thu, 25 Jul 2019 16:29:27 +0000 (18:29 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Thu, 25 Jul 2019 16:29:27 +0000 (18:29 +0200)
i.e. processing form data to be used by a DBOAction and processing object data to be used as form field values.

Close #2988

38 files changed:
wcfsetup/install/files/lib/acp/form/LanguageItemAddForm.class.php
wcfsetup/install/files/lib/data/DatabaseObject.class.php
wcfsetup/install/files/lib/data/IStorableObject.class.php
wcfsetup/install/files/lib/system/form/builder/FormDocument.class.php
wcfsetup/install/files/lib/system/form/builder/container/FormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/IFormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/wysiwyg/WysiwygFormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/wysiwyg/WysiwygPollFormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/data/FormDataHandler.class.php
wcfsetup/install/files/lib/system/form/builder/data/IFormDataHandler.class.php
wcfsetup/install/files/lib/system/form/builder/data/processor/AbstractFormDataProcessor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/data/processor/CustomFormDataProcessor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/data/processor/DefaultFormDataProcessor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/data/processor/IFormDataProcessor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/data/processor/VoidFormDataProcessor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/field/AbstractFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/IFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/ItemListFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/TI18nFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/TMultipleFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/UploadFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/acl/AclFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/acl/simple/SimpleAclFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/data/processor/CustomFormFieldDataProcessor.class.php [deleted file]
wcfsetup/install/files/lib/system/form/builder/field/data/processor/DefaultFormFieldDataProcessor.class.php [deleted file]
wcfsetup/install/files/lib/system/form/builder/field/data/processor/IFormFieldDataProcessor.class.php [deleted file]
wcfsetup/install/files/lib/system/form/builder/field/data/processor/VoidFormFieldDataProcessor.class.php [deleted file]
wcfsetup/install/files/lib/system/form/builder/field/label/LabelFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/tag/TagFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/wysiwyg/WysiwygAttachmentFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/wysiwyg/WysiwygFormField.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/BBCodePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/MediaProviderPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/OptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/SmileyPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/TemplateListenerPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php

index 0dd7bb8dcbb1f79cf14b66878f31ecdc517b2591..1c27e4548357387422dddf2b93717012d833da25 100644 (file)
@@ -5,8 +5,8 @@ use wcf\data\language\item\LanguageItemAction;
 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;
@@ -166,10 +166,10 @@ class LanguageItemAddForm extends AbstractFormBuilderForm {
                
                // `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;
                                
index 99e9056411877b1951936b8fe985e5a68721d22c..021e279770c7cfdaa53087f47fde7d1f08479796 100644 (file)
@@ -116,8 +116,7 @@ abstract class DatabaseObject implements IIDObject, IStorableObject {
        }
        
        /**
-        * @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;
index 5f1767215f12df45b9759dc8558aa9183b89e1ed..875a6518f88de178c97967d673cdfa08689a87fd 100644 (file)
@@ -31,7 +31,6 @@ interface IStorableObject {
        /**
         * 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();
index 48555ada6afaedd8c4f7259f6af5614ff9b9af18..509b33939332c5e811128cf232de59332653929a 100644 (file)
@@ -6,7 +6,7 @@ use wcf\system\form\builder\button\IFormButton;
 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;
@@ -338,7 +338,7 @@ class FormDocument implements IFormDocument {
                        throw new \BadMethodCallException("Getting data is only possible after calling 'readValues()'.");
                }
                
-               return $this->getDataHandler()->getData($this);
+               return $this->getDataHandler()->getFormData($this);
        }
        
        /**
@@ -347,7 +347,7 @@ class FormDocument implements IFormDocument {
        public function getDataHandler() {
                if ($this->dataHandler === null) {
                        $this->dataHandler = new FormDataHandler();
-                       $this->dataHandler->add(new DefaultFormFieldDataProcessor());
+                       $this->dataHandler->addProcessor(new DefaultFormDataProcessor());
                }
                
                return $this->dataHandler;
@@ -535,13 +535,15 @@ class FormDocument implements IFormDocument {
                        $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,
@@ -550,11 +552,11 @@ class FormDocument implements IFormDocument {
                                                }
                                        }
                                        else {
-                                               $node->loadValueFromObject($object);
+                                               $node->loadValue($data, $object);
                                        }
                                }
                                else if ($node instanceof IFormContainer) {
-                                       $node->loadValuesFromObject($object);
+                                       $node->loadValues($data, $object);
                                }
                        }
                }
index 35fd43f87ab06f3171a3cbc27c4f3d78358c7d87..c2653d5e748974cb0330d132af12e68d2874635c 100644 (file)
@@ -50,7 +50,7 @@ class FormContainer implements IFormContainer {
        /**
         * @inheritDoc
         */
-       public function loadValuesFromObject(IStorableObject $object) {
+       public function loadValues(array $data, IStorableObject $object) {
                // does nothing
                
                return $this;
index 5e80f09ddf975467270204402bb18085aa7c769f..fb3cb77a62e5986f4bf4061940f14f20b55b9547 100644 (file)
@@ -16,14 +16,15 @@ use wcf\system\form\builder\IFormParentNode;
  */
 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);
 }
index 403fb940838a0c16bc42810b01001041c48b2147..179df2d2d13aa14eab0b18eddcd79e42e0c11718 100644 (file)
@@ -342,8 +342,8 @@ class WysiwygFormContainer extends FormContainer implements IMaximumLengthFormFi
        /**
         * @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
@@ -357,7 +357,7 @@ class WysiwygFormContainer extends FormContainer implements IMaximumLengthFormFi
                        );
                }
                
-               return parent::loadValuesFromObject($object);
+               return parent::loadValues($data, $object);
        }
        
        /**
index 4e56278f56631b691d0ffc2187ed58248914e146..250ebd60275c305731818b60e354c5251b030366 100644 (file)
@@ -4,8 +4,8 @@ use wcf\data\IPollContainer;
 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;
@@ -226,9 +226,9 @@ class WysiwygPollFormContainer extends FormContainer implements IObjectTypeFormN
        /**
         * @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;
                        }
@@ -247,7 +247,7 @@ class WysiwygPollFormContainer extends FormContainer implements IObjectTypeFormN
                        $this->getSortByVotesField()->value($this->poll->sortByVotes);
                }
                
-               return parent::loadValuesFromObject($object);
+               return parent::loadValues($data, $object);
        }
        
        /**
@@ -259,7 +259,7 @@ class WysiwygPollFormContainer extends FormContainer implements IObjectTypeFormN
                $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;
                        }
index 1cddc67f20ccf6e9b39a41edf1c6e5a57cb0d578..5fd0a23d81708f4a55114d04d77cbefdb1c9de44 100644 (file)
@@ -1,6 +1,8 @@
 <?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;
 
 /**
@@ -16,14 +18,14 @@ 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;
@@ -32,12 +34,43 @@ class FormDataHandler implements IFormDataHandler {
        /**
         * @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;
+       }
 }
index 752a35a598174a9b9b6178b979d953bcdf3584a3..9d72f73e81ad33f26e584f2bfe8fc005058f5650 100644 (file)
@@ -1,6 +1,7 @@
 <?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;
 
 /**
@@ -18,10 +19,11 @@ interface IFormDataHandler {
         * 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
@@ -30,5 +32,15 @@ interface IFormDataHandler {
         * @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);
 }
diff --git a/wcfsetup/install/files/lib/system/form/builder/data/processor/AbstractFormDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/data/processor/AbstractFormDataProcessor.class.php
new file mode 100644 (file)
index 0000000..6e24e87
--- /dev/null
@@ -0,0 +1,31 @@
+<?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;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/form/builder/data/processor/CustomFormDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/data/processor/CustomFormDataProcessor.class.php
new file mode 100644 (file)
index 0000000..04599e9
--- /dev/null
@@ -0,0 +1,146 @@
+<?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;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/form/builder/data/processor/DefaultFormDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/data/processor/DefaultFormDataProcessor.class.php
new file mode 100644 (file)
index 0000000..7cccbe8
--- /dev/null
@@ -0,0 +1,49 @@
+<?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();
+                       }
+               }
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/form/builder/data/processor/IFormDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/data/processor/IFormDataProcessor.class.php
new file mode 100644 (file)
index 0000000..21964b2
--- /dev/null
@@ -0,0 +1,37 @@
+<?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);
+}
diff --git a/wcfsetup/install/files/lib/system/form/builder/data/processor/VoidFormDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/data/processor/VoidFormDataProcessor.class.php
new file mode 100644 (file)
index 0000000..1a3b0ad
--- /dev/null
@@ -0,0 +1,53 @@
+<?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;
+       }
+}
index a1b10e21eb327364c2c7aca38e8850f21caa3602..1f016034b59b64dc16bf01d24fdfac93c84328c0 100644 (file)
@@ -177,9 +177,9 @@ abstract class AbstractFormField implements IFormField {
        /**
         * @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;
index fd6617162896d8d5d7103b56de8a0d7f34296a12..0521237759c0689365feef75e152ac6da06d6766 100644 (file)
@@ -108,12 +108,16 @@ interface IFormField extends IFormChildNode, IFormElement {
        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
index a98eede6c7d164bb1272105ff9edbaf4d6a61913..e04e6e784be43387bd98c62bd0353d27fae7c71d 100644 (file)
@@ -1,6 +1,6 @@
 <?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;
@@ -114,7 +114,7 @@ class ItemListFormField extends AbstractFormField implements IAutoFocusFormField
                
                // 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();
                                }
index 6d26b67d4449f09c6e192265e5d9cd92ecbbd76b..601920bb96e8f48de152c19c915d1b08dfad5960 100644 (file)
@@ -1,8 +1,8 @@
 <?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;
@@ -249,9 +249,9 @@ trait TI18nFormField {
        /**
         * @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
@@ -286,7 +286,7 @@ trait TI18nFormField {
                        
                        /** @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();
                                }
index a18365fc7cb1a8c9dec945c62775d392c7151b0d..a3f334f3dd7ee1128b54810913174706a0dd83ab 100644 (file)
@@ -1,6 +1,6 @@
 <?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;
 
 /**
@@ -154,7 +154,7 @@ trait TMultipleFormField {
                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();
                                }
index 41f8012f23cead168bd81d0fa9a72957c49b4d67..e1aa5d987a75902960410b1ef1fe4526411b394d 100644 (file)
@@ -4,7 +4,7 @@ use wcf\data\IStorableObject;
 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;
 
@@ -172,7 +172,7 @@ class UploadFormField extends AbstractFormField {
         * 
         * @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']);
@@ -183,7 +183,7 @@ class UploadFormField extends AbstractFormField {
                        $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() . "'";
                }
                
@@ -259,7 +259,7 @@ class UploadFormField extends AbstractFormField {
                        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);
                        
index d2d88bf9df58a7db4f945f82b1fd6d56db73b6b7..61fb25ef7809651740d642f1d9c2212ec492b4c2 100644 (file)
@@ -2,8 +2,8 @@
 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;
@@ -115,7 +115,7 @@ class AclFormField extends AbstractFormField implements IObjectTypeFormNode {
        /**
         * @inheritDoc
         */
-       public function loadValueFromObject(IStorableObject $object) {
+       public function loadValue(array $data, IStorableObject $object) {
                $this->objectID = $object->{$object::getDatabaseTableIndexName()};
                
                if ($this->objectID === null) {
@@ -131,7 +131,7 @@ class AclFormField extends AbstractFormField implements IObjectTypeFormNode {
        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;
index f97835938510905372b3c37742e59953e531d8a1..871aba2bbc823077c3b05d2bacb3cb28e8dc3dc8 100644 (file)
@@ -1,8 +1,8 @@
 <?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;
 
 /**
@@ -52,7 +52,7 @@ class SimpleAclFormField extends AbstractFormField {
        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();
                        }
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/data/processor/CustomFormFieldDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/field/data/processor/CustomFormFieldDataProcessor.class.php
deleted file mode 100644 (file)
index ab4cff4..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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;
-       }
-}
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/data/processor/DefaultFormFieldDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/field/data/processor/DefaultFormFieldDataProcessor.class.php
deleted file mode 100644 (file)
index 70b027f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<?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();
-                       }
-               }
-       }
-}
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/data/processor/IFormFieldDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/field/data/processor/IFormFieldDataProcessor.class.php
deleted file mode 100644 (file)
index f011d9f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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);
-}
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/data/processor/VoidFormFieldDataProcessor.class.php b/wcfsetup/install/files/lib/system/form/builder/field/data/processor/VoidFormFieldDataProcessor.class.php
deleted file mode 100644 (file)
index 802d10f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?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;
-       }
-}
index c9392315f238443dfe9545b1621cda59882e0689..f1ba60d6d2653b4ef6d0762bdb8777edb8628d33 100644 (file)
@@ -3,8 +3,8 @@ namespace wcf\system\form\builder\field\label;
 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;
@@ -96,9 +96,9 @@ class LabelFormField extends AbstractFormField implements 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] = [];
@@ -127,7 +127,7 @@ class LabelFormField extends AbstractFormField implements IObjectTypeFormNode {
        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
index 7cb5323b0b8a72aec89842f1b8a1d1767450bf3d..b622bb30e5d11e928f433c35c01da3222d22b23c 100644 (file)
@@ -1,9 +1,9 @@
 <?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;
@@ -63,7 +63,7 @@ class TagFormField extends AbstractFormField implements IObjectTypeFormNode {
        /**
         * @inheritDoc
         */
-       public function loadValueFromObject(IStorableObject $object) {
+       public function loadValue(array $data, IStorableObject $object) {
                $objectID = $object->{$object::getDatabaseTableIndexName()};
                
                if ($objectID === null) {
@@ -77,9 +77,8 @@ class TagFormField extends AbstractFormField implements IObjectTypeFormNode {
                $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);
@@ -98,7 +97,7 @@ class TagFormField extends AbstractFormField implements IObjectTypeFormNode {
        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();
                        }
index 4666c088080836db459185a3065f9e318047f4c4..b607e32e89a3bbd25b7440641bad06c5a96cbb1e 100644 (file)
@@ -1,8 +1,8 @@
 <?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;
@@ -117,7 +117,7 @@ class WysiwygAttachmentFormField extends AbstractFormField {
        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();
                        }
index b305d5afc2396e89471081f18bc0f3c368d486fc..75503ce1cee6414dfc4788ea5f2cd2172c9358a6 100644 (file)
@@ -2,8 +2,8 @@
 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;
@@ -184,7 +184,7 @@ class WysiwygFormField extends AbstractFormField implements IMaximumLengthFormFi
        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;
                        }
index 37573696f8ae4511ac9a491c7ac24562e53358ce..4a96e29b7c99dd2fd198b05fec525226a2c7d874 100644 (file)
@@ -10,8 +10,8 @@ use wcf\system\devtools\pip\IIdempotentPackageInstallationPlugin;
 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;
@@ -675,7 +675,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag
                                ]);
                                
                                // 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']);
                                        }
index 089684f1577e094926fe4b1e74e86a1bdbd0a3a2..8330bd2586ecf4c7c862ff9e6a7db2e1b545e1e0 100644 (file)
@@ -12,10 +12,10 @@ use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
 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;
@@ -488,7 +488,7 @@ class BBCodePackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                );
                
                // 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'));
        }
        
        /**
index 52f18d41f7efe742023ee6df6679e6158ebb85a6..a255e35ffbc3f6af90d865f6f1b425152914de84 100644 (file)
@@ -7,8 +7,8 @@ use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 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;
@@ -189,7 +189,7 @@ class MediaProviderPackageInstallationPlugin extends AbstractXMLPackageInstallat
                                }))
                ]);
                
-               $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']));
                        
index 03ad87e38ddf163acbad8e1f844b017a7afa68e1..64b7265dce7b832cb82cd33b5e2aff312adcf743 100644 (file)
@@ -8,8 +8,8 @@ use wcf\data\package\Package;
 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;
@@ -222,7 +222,7 @@ class OptionPackageInstallationPlugin extends AbstractOptionPackageInstallationP
                                ]);
                                
                                // 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']);
                                        }
index 0f0f796b2f5e5df02eb284831e92f803b42ad873..e21378230e3536783a3ecbdaa6ac137b1370c237 100644 (file)
@@ -6,7 +6,7 @@ use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 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;
@@ -216,7 +216,7 @@ class SmileyPackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                ]);
                
                // 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;
index 669a2b4b9abbbc2d363568aed5485ada971dd0d2..01e2813f4c100929dc1adee11c90a8810bc3ca47 100644 (file)
@@ -11,16 +11,16 @@ use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 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;
@@ -374,7 +374,7 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                ]);
                
                // 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;
index 641398619dbbb3985530ca7f02d8768b9a233789..1f727a1de4c9248567ade4383d47dc1ea0bbb60b 100644 (file)
@@ -10,9 +10,9 @@ use wcf\data\user\option\UserOptionEditor;
 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;
@@ -320,7 +320,7 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat
                        ]);
                        
                        // 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']);
                                }