web/lib/Zend/Tool/Project/Provider/Abstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Tool
       
    17  * @subpackage Framework
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Abstract.php 23202 2010-10-21 15:08:15Z ralph $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Tool_Project_Profile
       
    25  */
       
    26 require_once 'Zend/Tool/Project/Profile.php';
       
    27 
       
    28 /**
       
    29  * @see Zend_Tool_Framework_Provider_Abstract
       
    30  */
       
    31 require_once 'Zend/Tool/Framework/Provider/Abstract.php';
       
    32 
       
    33 /**
       
    34  * @see Zend_Tool_Project_Context_Repository
       
    35  */
       
    36 require_once 'Zend/Tool/Project/Context/Repository.php';
       
    37 
       
    38 /**
       
    39  * @see Zend_Tool_Project_Profile_FileParser_Xml
       
    40  */
       
    41 require_once 'Zend/Tool/Project/Profile/FileParser/Xml.php';
       
    42 
       
    43 /**
       
    44  * @see Zend_Tool_Framework_Registry
       
    45  */
       
    46 require_once 'Zend/Tool/Framework/Registry.php';
       
    47 
       
    48 require_once 'Zend/Tool/Framework/Provider/Initializable.php';
       
    49 
       
    50 /**
       
    51  * @category   Zend
       
    52  * @package    Zend_Tool
       
    53  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    54  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    55  */
       
    56 abstract class Zend_Tool_Project_Provider_Abstract
       
    57     extends Zend_Tool_Framework_Provider_Abstract
       
    58     implements Zend_Tool_Framework_Provider_Initializable
       
    59 {
       
    60 
       
    61     const NO_PROFILE_THROW_EXCEPTION = true;
       
    62     const NO_PROFILE_RETURN_FALSE    = false;
       
    63 
       
    64     /**
       
    65      * @var bool
       
    66      */
       
    67     protected static $_isInitialized = false;
       
    68 
       
    69     protected $_projectPath = null;
       
    70 
       
    71     /**
       
    72      * @var Zend_Tool_Project_Profile
       
    73      */
       
    74     protected $_loadedProfile = null;
       
    75 
       
    76     public function initialize()
       
    77     {
       
    78         // initialize the ZF Contexts (only once per php request)
       
    79         if (!self::$_isInitialized) {
       
    80             
       
    81             // load all base contexts ONCE
       
    82             $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance();
       
    83             $contextRegistry->addContextsFromDirectory(
       
    84                 dirname(dirname(__FILE__)) . '/Context/Zf/', 'Zend_Tool_Project_Context_Zf_'
       
    85             );
       
    86             $contextRegistry->addContextsFromDirectory(
       
    87                 dirname(dirname(__FILE__)) . '/Context/Filesystem/', 'Zend_Tool_Project_Context_Filesystem_'
       
    88             );
       
    89             
       
    90             // determine if there are project specfic providers ONCE
       
    91             $profilePath = $this->_findProfileDirectory();
       
    92             if ($this->_hasProjectProviderDirectory($profilePath . DIRECTORY_SEPARATOR . '.zfproject.xml')) {
       
    93                 $profile = $this->_loadProfile();
       
    94                 // project providers directory resource
       
    95                 $ppd = $profile->search('ProjectProvidersDirectory');
       
    96                 $ppd->loadProviders($this->_registry);
       
    97             }
       
    98             
       
    99             self::$_isInitialized = true;
       
   100         }
       
   101 
       
   102         // load up the extending providers required context classes
       
   103         if ($contextClasses = $this->getContextClasses()) {
       
   104             $this->_loadContextClassesIntoRegistry($contextClasses);
       
   105         }
       
   106 
       
   107     }
       
   108 
       
   109     public function getContextClasses()
       
   110     {
       
   111         return array();
       
   112     }
       
   113 
       
   114     /**
       
   115      * _getProject is designed to find if there is project file in the context of where
       
   116      * the client has been called from..   The search order is as follows..
       
   117      *    - traversing downwards from (PWD) - current working directory
       
   118      *    - if an enpoint variable has been registered in teh client registry - key=workingDirectory
       
   119      *    - if an ENV variable with the key ZFPROJECT_PATH is found
       
   120      *
       
   121      * @param $loadProfileFlag bool Whether or not to throw an exception when no profile is found
       
   122      * @param $projectDirectory string The project directory to use to search
       
   123      * @param $searchParentDirectories bool Whether or not to search upper level direcotries
       
   124      * @return Zend_Tool_Project_Profile
       
   125      */
       
   126     protected function _loadProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION, $projectDirectory = null, $searchParentDirectories = true)
       
   127     {
       
   128         $foundPath = $this->_findProfileDirectory($projectDirectory, $searchParentDirectories);
       
   129 
       
   130         if ($foundPath == false) {
       
   131             if ($loadProfileFlag == self::NO_PROFILE_THROW_EXCEPTION) {
       
   132                 throw new Zend_Tool_Project_Provider_Exception('A project profile was not found.');
       
   133             } else {
       
   134                 return false;
       
   135             }
       
   136         }
       
   137         
       
   138         $profile = new Zend_Tool_Project_Profile();
       
   139         $profile->setAttribute('projectDirectory', $foundPath);
       
   140         $profile->loadFromFile();
       
   141         $this->_loadedProfile = $profile;
       
   142         return $profile;
       
   143     }
       
   144     
       
   145     protected function _findProfileDirectory($projectDirectory = null, $searchParentDirectories = true)
       
   146     {
       
   147         // use the cwd if no directory was provided
       
   148         if ($projectDirectory == null) {
       
   149             $projectDirectory = getcwd();
       
   150         } elseif (realpath($projectDirectory) == false) {
       
   151             throw new Zend_Tool_Project_Provider_Exception('The $projectDirectory supplied does not exist.');
       
   152         }
       
   153 
       
   154         $profile = new Zend_Tool_Project_Profile();
       
   155 
       
   156         $parentDirectoriesArray = explode(DIRECTORY_SEPARATOR, ltrim($projectDirectory, DIRECTORY_SEPARATOR));
       
   157         while ($parentDirectoriesArray) {
       
   158             $projectDirectoryAssembled = implode(DIRECTORY_SEPARATOR, $parentDirectoriesArray);
       
   159 
       
   160             if (DIRECTORY_SEPARATOR !== "\\") {
       
   161                 $projectDirectoryAssembled = DIRECTORY_SEPARATOR . $projectDirectoryAssembled;
       
   162             }
       
   163 
       
   164             $profile->setAttribute('projectDirectory', $projectDirectoryAssembled);
       
   165             if ($profile->isLoadableFromFile()) {
       
   166                 unset($profile);
       
   167                 return $projectDirectoryAssembled;
       
   168             }
       
   169             
       
   170             // break after first run if we are not to check upper directories
       
   171             if ($searchParentDirectories == false) {
       
   172                 break;
       
   173             }
       
   174 
       
   175             array_pop($parentDirectoriesArray);
       
   176         }
       
   177         
       
   178         return false;
       
   179     }
       
   180     
       
   181     /**
       
   182      * Load the project profile from the current working directory, if not throw exception
       
   183      *
       
   184      * @return Zend_Tool_Project_Profile
       
   185      */
       
   186     protected function _loadProfileRequired()
       
   187     {
       
   188         $profile = $this->_loadProfile();
       
   189         if ($profile === false) {
       
   190             require_once 'Zend/Tool/Project/Provider/Exception.php';
       
   191             throw new Zend_Tool_Project_Provider_Exception('A project profile was not found in the current working directory.');
       
   192         }
       
   193         return $profile;
       
   194     }
       
   195 
       
   196     /**
       
   197      * Return the currently loaded profile
       
   198      *
       
   199      * @return Zend_Tool_Project_Profile
       
   200      */
       
   201     protected function _getProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION)
       
   202     {
       
   203         if (!$this->_loadedProfile) {
       
   204             if (($this->_loadProfile($loadProfileFlag) === false) && ($loadProfileFlag === self::NO_PROFILE_RETURN_FALSE)) {
       
   205                 return false;
       
   206             }
       
   207         }
       
   208 
       
   209         return $this->_loadedProfile;
       
   210     }
       
   211 
       
   212     /**
       
   213      * _storeProfile()
       
   214      *
       
   215      * This method will store the profile into its proper location
       
   216      *
       
   217      */
       
   218     protected function _storeProfile()
       
   219     {
       
   220         $projectProfileFile = $this->_loadedProfile->search('ProjectProfileFile');
       
   221 
       
   222         $name = $projectProfileFile->getContext()->getPath();
       
   223 
       
   224         $this->_registry->getResponse()->appendContent('Updating project profile \'' . $name . '\'');
       
   225 
       
   226         $projectProfileFile->getContext()->save();
       
   227     }
       
   228 
       
   229     protected function _getContentForContext(Zend_Tool_Project_Context_Interface $context, $methodName, $parameters)
       
   230     {
       
   231         $storage = $this->_registry->getStorage();
       
   232         if (!$storage->isEnabled()) {
       
   233             return false;
       
   234         }
       
   235 
       
   236         if (!class_exists('Zend_Tool_Project_Context_Content_Engine')) {
       
   237             require_once 'Zend/Tool/Project/Context/Content/Engine.php';
       
   238         }
       
   239 
       
   240         $engine = new Zend_Tool_Project_Context_Content_Engine($storage);
       
   241         return $engine->getContent($context, $methodName, $parameters);
       
   242     }
       
   243 
       
   244     protected function _hasProjectProviderDirectory($pathToProfileFile)
       
   245     {
       
   246         // do some static analysis of the file so that we can determin whether or not to incure
       
   247         // the cost of loading the profile before the system is fully bootstrapped
       
   248         if (!file_exists($pathToProfileFile)) {
       
   249             return false;
       
   250         }
       
   251         
       
   252         $contents = file_get_contents($pathToProfileFile);
       
   253         if (strstr($contents, '<projectProvidersDirectory') === false) {
       
   254             return false;
       
   255         }
       
   256         
       
   257         if (strstr($contents, '<projectProvidersDirectory enabled="false"')) {
       
   258             return false;
       
   259         }
       
   260         
       
   261         return true;
       
   262     }
       
   263     
       
   264     /**
       
   265      * _loadContextClassesIntoRegistry() - This is called by the constructor
       
   266      * so that child providers can provide a list of contexts to load into the
       
   267      * context repository
       
   268      *
       
   269      * @param array $contextClasses
       
   270      */
       
   271     private function _loadContextClassesIntoRegistry($contextClasses)
       
   272     {
       
   273         $registry = Zend_Tool_Project_Context_Repository::getInstance();
       
   274 
       
   275         foreach ($contextClasses as $contextClass) {
       
   276             $registry->addContextClass($contextClass);
       
   277         }
       
   278     }
       
   279 }