Browse Source

Fix ZF-12173: Zend_Form and Zend_Form_Element prefix paths are not prefix agnostic (namespaces). Patch by Antonio J García Lagar.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@24848 44c647ce-9c0f-0410-b52a-842ac1e357ba
rob 13 years ago
parent
commit
7f747d0807

+ 3 - 2
library/Zend/Form.php

@@ -495,12 +495,13 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
                 $loader->addPrefixPath($prefix, $path);
                 return $this;
             case null:
-                $prefix = rtrim($prefix, '_');
+                $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
+                $prefix = rtrim($prefix, $nsSeparator);
                 $path   = rtrim($path, DIRECTORY_SEPARATOR);
                 foreach (array(self::DECORATOR, self::ELEMENT) as $type) {
                     $cType        = ucfirst(strtolower($type));
                     $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
-                    $pluginPrefix = $prefix . '_' . $cType;
+                    $pluginPrefix = $prefix . $nsSeparator . $cType;
                     $loader       = $this->getPluginLoader($type);
                     $loader->addPrefixPath($pluginPrefix, $pluginPath);
                 }

+ 3 - 2
library/Zend/Form/Element.php

@@ -1071,12 +1071,13 @@ class Zend_Form_Element implements Zend_Validate_Interface
                 $loader->addPrefixPath($prefix, $path);
                 return $this;
             case null:
-                $prefix = rtrim($prefix, '_');
+                $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
+                $prefix = rtrim($prefix, $nsSeparator);
                 $path   = rtrim($path, DIRECTORY_SEPARATOR);
                 foreach (array(self::DECORATOR, self::FILTER, self::VALIDATE) as $type) {
                     $cType        = ucfirst(strtolower($type));
                     $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
-                    $pluginPrefix = $prefix . '_' . $cType;
+                    $pluginPrefix = $prefix . $nsSeparator . $cType;
                     $loader       = $this->getPluginLoader($type);
                     $loader->addPrefixPath($pluginPrefix, $pluginPath);
                 }

+ 2 - 1
library/Zend/Form/Element/Captcha.php

@@ -232,7 +232,8 @@ class Zend_Form_Element_Captcha extends Zend_Form_Element_Xhtml
         switch ($type) {
             case null:
                 $loader = $this->getPluginLoader(self::CAPTCHA);
-                $cPrefix = rtrim($prefix, '_') . '_Captcha';
+                $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
+                $cPrefix = rtrim($prefix, $nsSeparator) . $nsSeparator . 'Captcha';
                 $cPath   = rtrim($path, '/\\') . '/Captcha';
                 $loader->addPrefixPath($cPrefix, $cPath);
                 return parent::addPrefixPath($prefix, $path);

+ 2 - 1
library/Zend/Form/Element/File.php

@@ -150,7 +150,8 @@ class Zend_Form_Element_File extends Zend_Form_Element_Xhtml
         }
 
         if (empty($type)) {
-            $pluginPrefix = rtrim($prefix, '_') . '_Transfer_Adapter';
+            $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
+            $pluginPrefix = rtrim($prefix, $nsSeparator) . $nsSeparator . 'Transfer' . $nsSeparator . 'Adapter';
             $pluginPath   = rtrim($path, DIRECTORY_SEPARATOR) . '/Transfer/Adapter/';
             $loader       = $this->getPluginLoader(self::TRANSFER_ADAPTER);
             $loader->addPrefixPath($pluginPrefix, $pluginPath);

+ 2 - 6
library/Zend/Loader/PluginLoader.php

@@ -127,12 +127,8 @@ class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
             return $prefix;
         }
 
-        $last = strlen($prefix) - 1;
-        if ($prefix{$last} == '\\') {
-            return $prefix;
-        }
-
-        return rtrim($prefix, '_') . '_';
+        $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
+        return rtrim($prefix, $nsSeparator) . $nsSeparator;
     }
 
     /**

+ 30 - 0
tests/Zend/Form/Element/CaptchaTest.php

@@ -410,6 +410,36 @@ class Zend_Form_Element_CaptchaTest extends PHPUnit_Framework_TestCase
             var_export($decorators, true)
         );
     }
+    
+    /**
+     * @group ZF-12173
+     */
+    public function testShouldAllowAddingCaptchaPrefixPathWithBackslash()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->markTestSkipped(__CLASS__ . '::' . __METHOD__ . ' requires PHP 5.3.0 or greater');
+            return;
+        }
+        $this->element->addPrefixPath('My\Captcha', 'My/Captcha/', 'captcha');
+        $loader = $this->element->getPluginLoader('captcha');
+        $paths  = $loader->getPaths('My\Captcha');
+        $this->assertTrue(is_array($paths));
+    }
+    
+    /**
+     * @group ZF-12173
+     */
+    public function testAddingCaptchaPrefixPathWithBackslash()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->markTestSkipped(__CLASS__ . '::' . __METHOD__ . ' requires PHP 5.3.0 or greater');
+            return;
+        }
+        $this->element->addPrefixPath('My\\', 'My/');
+        $loader = $this->element->getPluginLoader('captcha');
+        $paths  = $loader->getPaths('My\Captcha');
+        $this->assertTrue(is_array($paths));
+    }
 }
 
 /**

+ 15 - 0
tests/Zend/Form/Element/FileTest.php

@@ -491,6 +491,21 @@ class Zend_Form_Element_FileTest extends PHPUnit_Framework_TestCase
     {
         $this->assertSame($this->element, $this->element->loadDefaultDecorators());
     }
+    
+    /**
+     * @group ZF-12173
+     */
+    public function testElementShouldAllowAdapterWithBackslahes()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->markTestSkipped(__CLASS__ . '::' . __METHOD__ . ' requires PHP 5.3.0 or greater');
+            return;
+        }
+        $this->element->addPrefixPath('Zend\Form\Element\FileTest\Adapter', dirname(__FILE__) . '/_files/TransferAdapter', 'transfer_adapter');
+        $this->element->setTransferAdapter('Bar');
+        $test = $this->element->getTransferAdapter();
+        $this->assertTrue($test instanceof \Zend\Form\Element\FileTest\Adapter\Bar);
+    }
 }
 
 class Zend_Form_Element_FileTest_MockAdapter extends Zend_File_Transfer_Adapter_Abstract

+ 30 - 0
tests/Zend/Form/ElementTest.php

@@ -2202,6 +2202,36 @@ class Zend_Form_ElementTest extends PHPUnit_Framework_TestCase
         $validator = $username->getValidator('regex');
         $this->assertTrue($validator->zfBreakChainOnFailure);
     }
+    
+    /**
+     * @group ZF-12173
+     */
+    public function testCanAddPluginLoaderPrefixPathsWithBackslashes()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->markTestSkipped(__CLASS__ . '::' . __METHOD__ . ' requires PHP 5.3.0 or greater');
+            return;
+        }
+        $validatorLoader = new Zend_Loader_PluginLoader();
+        $filterLoader    = new Zend_Loader_PluginLoader();
+        $decoratorLoader = new Zend_Loader_PluginLoader();
+        $this->element->setPluginLoader($validatorLoader, 'validate')
+                      ->setPluginLoader($filterLoader, 'filter')
+                      ->setPluginLoader($decoratorLoader, 'decorator')
+                      ->addPrefixPath('Zf\Foo', 'Zf/Foo');
+
+        $paths = $filterLoader->getPaths('Zf\Foo\Filter');
+        $this->assertTrue(is_array($paths));
+        $this->assertContains('Filter', $paths[0]);
+
+        $paths = $validatorLoader->getPaths('Zf\Foo\Validate');
+        $this->assertTrue(is_array($paths));
+        $this->assertContains('Validate', $paths[0]);
+
+        $paths = $decoratorLoader->getPaths('Zf\Foo\Decorator');
+        $this->assertTrue(is_array($paths), var_export($paths, 1));
+        $this->assertContains('Decorator', $paths[0]);
+    }
 }
 
 class Zend_Form_ElementTest_Decorator extends Zend_Form_Decorator_Abstract

+ 20 - 0
tests/Zend/Form/FormTest.php

@@ -4534,6 +4534,26 @@ class Zend_Form_FormTest extends PHPUnit_Framework_TestCase
             'SubForm element received wrong validator'
         );        
     }
+
+    /**
+     * @group ZF-12173
+     */
+    public function testAddingPrefixPathsWithBackslashWillLoadNamespacedPlugins()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            $this->markTestSkipped(__CLASS__ . '::' . __METHOD__ . ' requires PHP 5.3.0 or greater');
+            return;
+        }
+        $form = new Zend_Form();
+        $form->addPrefixPath('Zf\Foo', 'Zf/Foo');
+        foreach (array('element', 'decorator') as $type) {
+            $loader = $form->getPluginLoader($type);
+            $paths = $loader->getPaths('Zf\Foo\\' . ucfirst($type));
+            $this->assertTrue(is_array($paths), "Failed for type $type: " . var_export($paths, 1));
+            $this->assertFalse(empty($paths));
+            $this->assertContains('Foo', $paths[0]);
+        }
+    }
 }
 
 class Zend_Form_FormTest_DisplayGroup extends Zend_Form_DisplayGroup