Browse Source

Fix double encoding in postLink() URLs.

URLs with query string parameters should not be double encoded. Follow
the same pattern as create() does for creating form URLs.

Refs #6413
Mark Story 11 years ago
parent
commit
d730ea59db
2 changed files with 33 additions and 4 deletions
  1. 8 4
      src/View/Helper/FormHelper.php
  2. 25 0
      tests/TestCase/View/Helper/FormHelperTest.php

+ 8 - 4
src/View/Helper/FormHelper.php

@@ -1654,7 +1654,6 @@ class FormHelper extends Helper
 
         $formName = str_replace('.', '', uniqid('post_', true));
         $formOptions = [
-            'action' => $this->Url->build($url),
             'name' => $formName,
             'style' => 'display:none;',
             'method' => 'post',
@@ -1663,11 +1662,16 @@ class FormHelper extends Helper
             $formOptions['target'] = $options['target'];
             unset($options['target']);
         }
+        $templater = $this->templater();
 
         $this->_lastAction($url);
+        $action = $templater->formatAttributes([
+            'action' => $this->Url->build($url),
+            'escape' => false
+        ]);
 
-        $out = $this->formatTemplate('formStart', [
-            'attrs' => $this->templater()->formatAttributes($formOptions)
+        $out = $templater->format('formStart', [
+            'attrs' => $templater->formatAttributes($formOptions) . $action
         ]);
         $out .= $this->hidden('_method', ['value' => $requestMethod]);
         $out .= $this->_csrfField();
@@ -1681,7 +1685,7 @@ class FormHelper extends Helper
             unset($options['data']);
         }
         $out .= $this->secure($fields);
-        $out .= $this->formatTemplate('formEnd', []);
+        $out .= $templater->format('formEnd', []);
 
         if ($options['block']) {
             if ($options['block'] === true) {

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

@@ -6321,6 +6321,31 @@ class FormHelperTest extends TestCase
     }
 
     /**
+     * test postLink() with query string args.
+     *
+     * @return void
+     */
+    public function testPostLinkWithQuery()
+    {
+        $result = $this->Form->postLink(
+            'Delete',
+            ['controller' => 'posts', 'action' => 'delete', 1, '?' => ['a' => 'b', 'c' => 'd']
+        ]);
+        $expected = [
+            'form' => [
+                'method' => 'post', 'action' => '/posts/delete/1?a=b&c=d',
+                'name' => 'preg:/post_\w+/', 'style' => 'display:none;'
+            ],
+            'input' => ['type' => 'hidden', 'name' => '_method', 'value' => 'POST'],
+            '/form',
+            'a' => ['href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'],
+            'Delete',
+            '/a'
+        ];
+        $this->assertHtml($expected, $result);
+    }
+
+    /**
      * Test postLink with additional data.
      *
      * @return void