ZF-6484: Resource Autoloader does not take any namespace prefix

Description

It's not possible to set a namespace prefix like "Foo_Bar" to the class Zend_Loader_Autoloader_Resource. The class checks the namespace too restrictive.

The problem is that array_shift only returns the first part. So my namespace must be "Foo".

Line: 142

 
if (!empty($namespaceTopLevel)) {
    $namespace = array_shift($segments);
    if ($namespace != $this->getNamespace()) {
         // wrong prefix? we're done
         return false;
    }
}

Comments

Assigning to Matthew.

I have encoutred the same problem following you can find a prosition of solution which replace the portion of code quote in issue description :

    if (!empty($namespaceTopLevel)) {
        if (strpos($class, $namespaceTopLevel) !== 0) {
            // wrong prefix? we're done
            return false;
        }
        $namespace = substr($class, strlen($namespaceTopLevel)+1);
        $segments = explode('_', $namespace);
        $namespace = $namespaceTopLevel;
    }

Can you demonstrate what your use case is for this? I'm not entirely convinced it makes sense for us to support this, particularly since you can override the resource autoloader yourself and override the appropriate method to drop in the functionality you desire.

I'm writing an CMS application with a plugin system. Each plugin should have an own namespace. The CMS plugin loader iterates over all plugins and registrates the namespace during runtime. All plugins have a namespace prefix "Plugin_". So i have i.E. a namespace like "Plugin_Frontend_Twitter". I overwritten the resource loader with my own Loader (Inmon_Cms_Loader_Autoloader_Resource) extended by Zend_Loader_Autoloader_Resource. So i have currently no problem. I think it's ok so. For ZF2 i have to port the CMS to the new plugin system with native PHP namespaces. So you can close the ticket IMHO.

Hi guys,

had the same issue. I'm currently writing an implementation of ZF for TYPO3-extensions and there the "module" classes (for ZF they are modules; for TYPO3 plugins) are prefixed Tx_MyExt_...

I registered these modules with the Zend_Application_Module_Autoloader and everything worked fine except that getClassPath returned to early because it checked the toplevel namespace to be 'Tx' while the real one was Tx_ZfextSample_. My hack was then:


<?php
class ZfExt_Application_Module_Autoloader extends Zend_Application_Module_Autoloader
{
    /**
     * Overriding the parent method because it behaves wrong when using
     * prefixed namespaces.
     * 
     * $loader = new Zend_Loader_Autoloader_Resource(array(
     *     'namespace' => 'Tx_MyExt',
     *     'basePath'  => '/path/to/tx_myextension/plugin/',
     * ))
     * 
     * The class names in there are f.i. Tx_MyExt_Model_DbTable_Pages
     * Problem:
     * Parent method detects 'Tx' to be it's namespace and not 'Tx_MyExt'
     * Hacked that here.
     * 
     * @param string $class
     * @return string|boolean False if not matched other wise the correct path
     */
    public function getClassPath($class)
    {
        $namespace = $this->getNamespace();
        if (strpos($class, $namespace) !== 0)
        {
            return false;
        }
        $this->_namespace = null;
        $classPath = parent::getClassPath($class);
        $this->setNamespace($namespace);
        return $classPath;
    }
}

Cheers, Christian

I've been trying to configure a per-module autoloader in a post-router plugin (after the module has been calculated) so I can have per-module forms, models etc. and consider the following format for the module namespace to be the 'correct' one: appNameSpace_moduleName. However, as has already bean mentioned, the getClassPath method in the 'module' autoloader assumes that the namespace for an autoloader does not contain the '' char. Instead of exploding the class path on the '' char and then comparing with the namespace, the following patch checks and correctly adjusts for any namespace before then continuing as normal by building the file path of a class based only on splitting on '_' chars after the namespace prefix.


--- Loader/Autoloader/Resource.php  2010-10-29 16:27:36.000000000 +0100
+++ Loader/Autoloader/Resource.new.php  2010-10-29 17:01:22.000000000 +0100
@@ -139,16 +139,24 @@
      */
     public function getClassPath($class)
     {
-        $segments          = explode('_', $class);
         $namespaceTopLevel = $this->getNamespace();
         $namespace         = '';
 
         if (!empty($namespaceTopLevel)) {
-            $namespace = array_shift($segments);
-            if ($namespace != $namespaceTopLevel) {
-                // wrong prefix? we're done
+            if (strncmp($class, $namespaceTopLevel, strlen($namespaceTopLevel)) != 0) {
+                // wrong namespace
                 return false;
+            } else {
+                $segments = explode('_', substr($class, strlen($namespaceTopLevel)));
+                $namespace = $namespaceTopLevel;
             }
+        } else {
+            $segments = explode('_', $class);
+        }
+        
+
+        if($segments[0] == '') {
+            array_shift($segments);
         }
 
         if (count($segments) < 2) {

Seems like this is already resolved in ZF-11219?

Fixed with ZF-11219 for version 1.11.2.