Browse Source

Merge pull request #12157 from cakephp/3.7-modellesss-form-data

Enhancement: Add methods go get/set modelless form data.
Mark Story 7 years ago
parent
commit
47d51c3a03

+ 40 - 0
src/Form/Form.php

@@ -20,6 +20,7 @@ use Cake\Event\EventDispatcherTrait;
 use Cake\Event\EventListenerInterface;
 use Cake\Event\EventManager;
 use Cake\Form\Schema;
+use Cake\Utility\Hash;
 use Cake\Validation\Validator;
 use Cake\Validation\ValidatorAwareInterface;
 use Cake\Validation\ValidatorAwareTrait;
@@ -90,6 +91,14 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
     protected $_validator;
 
     /**
+     * Form's data.
+     *
+     * @var array
+     * @since 3.7.0
+     */
+    protected $_data = [];
+
+    /**
      * Constructor
      *
      * @param \Cake\Event\EventManager|null $eventManager The event manager.
@@ -305,6 +314,37 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
     }
 
     /**
+     * Get field data.
+     *
+     * @param string|null $field The field name or null to get data array with
+     *   all fields.
+     * @return mixed
+     * @since 3.7.0
+     */
+    public function getData($field = null)
+    {
+        if ($field === null) {
+            return $this->_data;
+        }
+
+        return Hash::get($this->_data, $field);
+    }
+
+    /**
+     * Set form data.
+     *
+     * @param array $data Data array.
+     * @return $this
+     * @since 3.7.0
+     */
+    public function setData(array $data)
+    {
+        $this->_data = $data;
+
+        return $this;
+    }
+
+    /**
      * Get the printable version of a Form instance.
      *
      * @return array

+ 5 - 0
src/View/Form/FormContext.php

@@ -94,6 +94,11 @@ class FormContext implements ContextInterface
             return $val;
         }
 
+        $val = $this->_form->getData($field);
+        if ($val !== null) {
+            return $val;
+        }
+
         if ($options['default'] !== null || !$options['schemaDefault']) {
             return $options['default'];
         }

+ 17 - 0
tests/TestCase/Form/FormTest.php

@@ -234,6 +234,22 @@ class FormTest extends TestCase
     }
 
     /**
+     * Test setting and getting form data.
+     *
+     * @return void
+     */
+    public function testDataSetGet()
+    {
+        $form = new Form();
+        $expected = ['title' => 'title', 'is_published' => true];
+        $form->setData(['title' => 'title', 'is_published' => true]);
+
+        $this->assertSame($expected, $form->getData());
+        $this->assertEquals('title', $form->getData('title'));
+        $this->assertNull($form->getData('non-existent'));
+    }
+
+    /**
      * test __debugInfo
      *
      * @return void
@@ -245,5 +261,6 @@ class FormTest extends TestCase
         $this->assertArrayHasKey('_schema', $result);
         $this->assertArrayHasKey('_errors', $result);
         $this->assertArrayHasKey('_validator', $result);
+        $this->assertArrayHasKey('_data', $result);
     }
 }

+ 21 - 0
tests/TestCase/View/Form/FormContextTest.php

@@ -94,6 +94,27 @@ class FormContextTest extends TestCase
     }
 
     /**
+     * Test reading values from form data.
+     */
+    public function testValPresentInForm()
+    {
+        $form = new Form();
+        $form->setData(['title' => 'set title']);
+
+        $context = new FormContext($this->request, ['entity' => $form]);
+
+        $this->assertEquals('set title', $context->val('title'));
+        $this->assertNull($context->val('Articles.body'));
+
+        $this->request = $this->request->withParsedBody([
+            'title' => 'New title',
+        ]);
+        $context = new FormContext($this->request, ['entity' => $form]);
+
+        $this->assertEquals('New title', $context->val('title'));
+    }
+
+    /**
      * Test getting values when the request and defaults are missing.
      *
      * @return void