Add `IFormDocument::build()` and `IFormNode::populate()`
authorMatthias Schmidt <gravatronics@live.com>
Wed, 3 Jan 2018 11:51:17 +0000 (12:51 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Wed, 3 Jan 2018 11:54:26 +0000 (12:54 +0100)
See #2509

wcfsetup/install/files/lib/acp/form/DevtoolsFormBuilderTestForm.class.php
wcfsetup/install/files/lib/system/form/builder/FormDocument.class.php
wcfsetup/install/files/lib/system/form/builder/IFormDocument.class.php
wcfsetup/install/files/lib/system/form/builder/IFormNode.class.php
wcfsetup/install/files/lib/system/form/builder/TFormNode.class.php

index 0b8cb6c60cb5c2ba9d11f4398dce2b36623c2ab9..bd7cc5fd387b6ba4fb04798d0d145f0e21f84643 100644 (file)
@@ -108,6 +108,8 @@ class DevtoolsFormBuilderTestForm extends AbstractForm {
                                ])
                ]);
                
+               $this->form->build();
+               
                $this->form->getDataHandler()->add(new CustomFormFieldDataProcessor('isDisabledToString', function(IFormDocument $document, array $parameters) {
                        unset($parameters['data']['isDisabled']);
                        
index 2f71220efda99c5aff35204c42435b19e3a6000b..5773b6cd8d5b6b4846d2d3c040cb33727e427855 100644 (file)
@@ -50,6 +50,12 @@ class FormDocument implements IFormDocument {
         */
        protected $enctype = '';
        
+       /**
+        * is `true` if form document has already been built and is `false` otherwise
+        * @var bool
+        */
+       protected $isBuilt = false;
+       
        /**
         * @inheritDoc
         */
@@ -63,6 +69,24 @@ class FormDocument implements IFormDocument {
                return $this;
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function build() {
+               if ($this->isBuilt) {
+                       throw new \BadMethodCallException("Form document has already been built.");
+               }
+               
+               /** @var IFormNode $node */
+               foreach ($this->getIterator() as $node) {
+                       $node->populate();
+               }
+               
+               $this->isBuilt = true;
+               
+               return $this;
+       }
+       
        /**
         * @inheritDoc
         */
index db7e88a514d8baf56468d17eb9a48c6130956327..79717b77fb654ade2090bc0b5875a10b8eceea67 100644 (file)
@@ -22,6 +22,19 @@ interface IFormDocument extends IFormParentNode {
         */
        public function action($action);
        
+       /**
+        * Is called once after all nodes have been added to this document.
+        * 
+        * This method is intended to trigger `TODO` to allow nodes to perform actions that
+        * require the whole document having finished constructing itself and every parent-
+        * -child relationship being established.
+        * 
+        * @return      static                          this document
+        * 
+        * @throws      \BadMethodCallException         if this document has already been built
+        */
+       public function build();
+       
        /**
         * Returns the `action` property of the HTML `form` element.
         * 
index c90771f47be6d08f2b28cdb175dba6328408b32b..5d17d781ece5e2d103f074880dd9d4ea09f097de 100644 (file)
@@ -136,6 +136,18 @@ interface IFormNode {
         */
        public function id($id);
        
+       /**
+        * Is called once after all nodes have been added to the document this node belongs to.
+        * 
+        * This method enables this node to perform actions that require the whole document having
+        * finished constructing itself and every parent-child relationship being established.
+        * 
+        * @return      static                          this node
+        * 
+        * @throws      \BadMethodCallException         if this node has already been populated
+        */
+       public function populate();
+       
        /**
         * Removes the given CSS class and returns this node.
         * 
@@ -169,18 +181,18 @@ interface IFormNode {
        
        /**
         * Checks if the given attribute name class a string and a valid attribute name.
-        *
+        * 
         * @param       mixed           $name           checked argument name
-        *
+        * 
         * @throws      \InvalidArgumentException       if the given attribute name is no string or otherwise invalid
         */
        public static function validateAttribute($name);
        
        /**
         * Checks if the given parameter class a string and a valid node class.
-        *
+        * 
         * @param       mixed           $class          checked class
-        *
+        * 
         * @throws      \InvalidArgumentException       if the given id is no string or otherwise invalid
         */
        public static function validateClass($class);
index 6672a36e64f9103953931c9b43c1259203db72e0..c399dc1b2db3a3085ed75ff68b5eeb6369ca59e1 100644 (file)
@@ -29,6 +29,12 @@ trait TFormNode {
         */
        protected $__id;
        
+       /**
+        * is `true` if node has already been populated and is `false` otherwise 
+        * @var bool
+        */
+       protected $isPopulated = false;
+       
        /**
         * list of attribute names that may not be set using `attribute()`
         * @var string[]
@@ -209,6 +215,27 @@ trait TFormNode {
                return $this;
        }
        
+       /**
+        * Is called once after all nodes have been added to the document this node belongs to.
+        * 
+        * This method enables this node to perform actions that require the whole document having
+        * finished constructing itself and every parent-child relationship being established.
+        * 
+        * @return      static                          this node
+        * 
+        * @throws      \BadMethodCallException         if this node has already been populated
+        */
+       public function populate() {
+               if ($this->isPopulated) {
+                       throw new \BadMethodCallException('Node has already been populated');
+               }
+               
+               $this->isPopulated = true;
+               
+               return $this;
+       }
+       
+       
        /**
         * Removes the given CSS class and returns this node.
         *