Sfoglia il codice sorgente

ZF-9397
Fixed project specific provider loading functionality

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@23200 44c647ce-9c0f-0410-b52a-842ac1e357ba

ralph 15 anni fa
parent
commit
380a925ea9

+ 14 - 4
library/Zend/Tool/Framework/Provider/Repository.php

@@ -160,7 +160,12 @@ class Zend_Tool_Framework_Provider_Repository
     {
 
         // process all providers in the unprocessedProviders array
-        foreach ($this->_unprocessedProviders as $providerName => $provider) {
+        //foreach ($this->_unprocessedProviders as $providerName => $provider) {
+        reset($this->_unprocessedProviders);
+        while ($this->_unprocessedProviders) {
+            
+            $providerName = key($this->_unprocessedProviders);
+            $provider = array_shift($this->_unprocessedProviders);
 
             // create a signature for the provided provider
             $providerSignature = new Zend_Tool_Framework_Provider_Signature($provider);
@@ -178,8 +183,10 @@ class Zend_Tool_Framework_Provider_Repository
             $this->_providerSignatures[$providerName] = $providerSignature;
             $this->_providers[$providerName]          = $providerSignature->getProvider();
 
-            // remove from unprocessed array
-            unset($this->_unprocessedProviders[$providerName]);
+            if ($provider instanceof Zend_Tool_Framework_Provider_Initializable) {
+                $provider->initialize();
+            }
+
         }
 
     }
@@ -255,7 +262,10 @@ class Zend_Tool_Framework_Provider_Repository
     protected function _parseName(Zend_Tool_Framework_Provider_Interface $provider)
     {
         $className = get_class($provider);
-        $providerName = substr($className, strrpos($className, '_')+1);
+        $providerName = $className;
+        if (strpos($providerName, '_') !== false) {
+            $providerName = substr($providerName, strrpos($providerName, '_')+1);
+        }
         if (substr($providerName, -8) == 'Provider') {
             $providerName = substr($providerName, 0, strlen($providerName)-8);
         }

+ 4 - 1
library/Zend/Tool/Framework/Provider/Signature.php

@@ -239,7 +239,10 @@ class Zend_Tool_Framework_Provider_Signature implements Zend_Tool_Framework_Regi
 
         if ($this->_name == null) {
             $className = get_class($this->_provider);
-            $name = substr($className, strrpos($className, '_')+1);
+            $name = $className;
+            if (strpos($name, '_')) {
+                $name = substr($name, strrpos($name, '_')+1);
+            }
             $name = preg_replace('#(Provider|Manifest)$#', '', $name);
             $this->_name = $name;
         }

+ 9 - 19
library/Zend/Tool/Project/Context/System/ProjectProvidersDirectory.php

@@ -66,32 +66,22 @@ class Zend_Tool_Project_Context_System_ProjectProvidersDirectory
     {
         return 'ProjectProvidersDirectory';
     }
-
-    /**
-     * init()
-     *
-     * @return Zend_Tool_Project_Context_System_ProjectProvidersDirectory
-     */
-    public function init()
+    
+    public function loadProviders(Zend_Tool_Framework_Registry_Interface $registry)
     {
-        parent::init();
-
         if (file_exists($this->getPath())) {
 
+            $providerRepository = $registry->getProviderRepository();
+            
             foreach (new DirectoryIterator($this->getPath()) as $item) {
-                if ($item->isFile()) {
-                    $loadableFiles[] = $item->getPathname();
+                if ($item->isFile() && (($suffixStart = strpos($item->getFilename(), 'Provider.php')) !== false)) {
+                    $className = substr($item->getFilename(), 0, $suffixStart+8);
+                    // $loadableFiles[$className] = $item->getPathname();
+                    include_once $item->getPathname();
+                    $providerRepository->addProvider(new $className());
                 }
             }
-
-            if ($loadableFiles) {
-
-                // @todo process and add the files to the system for usage.
-
-            }
         }
-
-        return $this;
     }
 
 }

+ 60 - 25
library/Zend/Tool/Project/Provider/Abstract.php

@@ -45,13 +45,17 @@ require_once 'Zend/Tool/Project/Profile/FileParser/Xml.php';
  */
 require_once 'Zend/Tool/Framework/Registry.php';
 
+require_once 'Zend/Tool/Framework/Provider/Initializable.php';
+
 /**
  * @category   Zend
  * @package    Zend_Tool
  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  * @license    http://framework.zend.com/license/new-bsd     New BSD License
  */
-abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_Provider_Abstract
+abstract class Zend_Tool_Project_Provider_Abstract
+    extends Zend_Tool_Framework_Provider_Abstract
+    implements Zend_Tool_Framework_Provider_Initializable
 {
 
     const NO_PROFILE_THROW_EXCEPTION = true;
@@ -69,16 +73,12 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
      */
     protected $_loadedProfile = null;
 
-    /**
-     * constructor
-     *
-     * YOU SHOULD NOT OVERRIDE THIS, unless you know what you are doing
-     *
-     */
-    public function __construct()
+    public function initialize()
     {
         // initialize the ZF Contexts (only once per php request)
         if (!self::$_isInitialized) {
+            
+            // load all base contexts ONCE
             $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance();
             $contextRegistry->addContextsFromDirectory(
                 dirname(dirname(__FILE__)) . '/Context/Zf/', 'Zend_Tool_Project_Context_Zf_'
@@ -86,6 +86,16 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
             $contextRegistry->addContextsFromDirectory(
                 dirname(dirname(__FILE__)) . '/Context/Filesystem/', 'Zend_Tool_Project_Context_Filesystem_'
             );
+            
+            // determine if there are project specfic providers ONCE
+            $profilePath = $this->_findProfileDirectory();
+            if ($this->_hasProjectProviderDirectory($profilePath . DIRECTORY_SEPARATOR . '.zfproject.xml')) {
+                $profile = $this->_loadProfile();
+                // project providers directory resource
+                $ppd = $profile->search('ProjectProvidersDirectory');
+                $ppd->loadProviders($this->_registry);
+            }
+            
             self::$_isInitialized = true;
         }
 
@@ -115,6 +125,25 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
      */
     protected function _loadProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION, $projectDirectory = null, $searchParentDirectories = true)
     {
+        $foundPath = $this->_findProfileDirectory($projectDirectory, $searchParentDirectories);
+
+        if ($foundPath == false) {
+            if ($loadProfileFlag == self::NO_PROFILE_THROW_EXCEPTION) {
+                throw new Zend_Tool_Project_Provider_Exception('A project profile was not found.');
+            } else {
+                return false;
+            }
+        }
+        
+        $profile = new Zend_Tool_Project_Profile();
+        $profile->setAttribute('projectDirectory', $foundPath);
+        $profile->loadFromFile();
+        $this->_loadedProfile = $profile;
+        return $profile;
+    }
+    
+    protected function _findProfileDirectory($projectDirectory = null, $searchParentDirectories = true)
+    {
         // use the cwd if no directory was provided
         if ($projectDirectory == null) {
             $projectDirectory = getcwd();
@@ -134,13 +163,10 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
 
             $profile->setAttribute('projectDirectory', $projectDirectoryAssembled);
             if ($profile->isLoadableFromFile()) {
-                chdir($projectDirectoryAssembled);
-
-                $profile->loadFromFile();
-                $this->_loadedProfile = $profile;
-                break;
+                unset($profile);
+                return $projectDirectoryAssembled;
             }
-
+            
             // break after first run if we are not to check upper directories
             if ($searchParentDirectories == false) {
                 break;
@@ -148,18 +174,10 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
 
             array_pop($parentDirectoriesArray);
         }
-
-        if ($this->_loadedProfile == null) {
-            if ($loadProfileFlag == self::NO_PROFILE_THROW_EXCEPTION) {
-                throw new Zend_Tool_Project_Provider_Exception('A project profile was not found.');
-            } elseif ($loadProfileFlag == self::NO_PROFILE_RETURN_FALSE) {
-                return false;
-            }
-        }
-
-        return $profile;
+        
+        return false;
     }
-
+    
     /**
      * Load the project profile from the current working directory, if not throw exception
      *
@@ -223,6 +241,23 @@ abstract class Zend_Tool_Project_Provider_Abstract extends Zend_Tool_Framework_P
         return $engine->getContent($context, $methodName, $parameters);
     }
 
+    protected function _hasProjectProviderDirectory($pathToProfileFile)
+    {
+        // do some static analysis of the file so that we cna determin whether or not to incure
+        // the cost of loading the profile before the system is fully bootstrapped
+        
+        $contents = file_get_contents($pathToProfileFile);
+        if (strstr($contents, '<projectProvidersDirectory') === false) {
+            return false;
+        }
+        
+        if (strstr($contents, '<projectProvidersDirectory enabled="false"')) {
+            return false;
+        }
+        
+        return true;
+    }
+    
     /**
      * _loadContextClassesIntoRegistry() - This is called by the constructor
      * so that child providers can provide a list of contexts to load into the