Browse Source

Fetch widget's secure fields list after rendering widget.

This allows the flexibility for widgets to populate secure fields
list based on rendering process rather than data argument.
ADmad 11 years ago
parent
commit
2e1a61d3d9
2 changed files with 38 additions and 7 deletions
  1. 9 7
      src/View/Helper/FormHelper.php
  2. 29 0
      tests/TestCase/View/Helper/FormHelperTest.php

+ 9 - 7
src/View/Helper/FormHelper.php

@@ -2519,17 +2519,19 @@ class FormHelper extends Helper
      */
     public function widget($name, array $data = [])
     {
+        $secure = null;
+        if (isset($data['secure'])) {
+            $secure = $data['secure'];
+            unset($data['secure']);
+        }
         $widget = $this->_registry->get($name);
-        if (isset($data['secure'], $data['name']) &&
-            $data['secure'] !== self::SECURE_SKIP
-        ) {
+        $out = $widget->render($data, $this->context());
+        if (isset($data['name']) && $secure !== null && $secure !== self::SECURE_SKIP) {
             foreach ($widget->secureFields($data) as $field) {
-                $this->_secure($data['secure'], $this->_secureFieldName($field));
+                $this->_secure($secure, $this->_secureFieldName($field));
             }
         }
-        unset($data['secure']);
-
-        return $widget->render($data, $this->context());
+        return $out;
     }
 
     /**

+ 29 - 0
tests/TestCase/View/Helper/FormHelperTest.php

@@ -263,6 +263,35 @@ class FormHelperTest extends TestCase
     }
 
     /**
+     * Test that secureFields() of widget is called after calling render(),
+     * not before.
+     *
+     * @return void
+     */
+    public function testOrderForRenderingWidgetAndFetchingSecureFields()
+    {
+        $data = [
+            'val' => 1,
+            'name' => 'test'
+        ];
+        $mock = $this->getMock('Cake\View\Widget\WidgetInterface');
+        $this->assertNull($this->Form->addWidget('test', $mock));
+
+        $mock->expects($this->at(0))
+            ->method('render')
+            ->with($data)
+            ->will($this->returnValue('HTML'));
+
+        $mock->expects($this->at(1))
+            ->method('secureFields')
+            ->with($data)
+            ->will($this->returnValue(['test']));
+
+        $result = $this->Form->widget('test', $data + ['secure' => true]);
+        $this->assertEquals('HTML', $result);
+    }
+
+    /**
      * Test that empty string is not added to secure fields list when
      * rendering input widget without name.
      *