File indexing completed on 2024-06-23 05:55:51

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Tool
0017  * @subpackage Framework
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Tool_Project_Profile
0025  */
0026 // require_once 'Zend/Tool/Project/Profile.php';
0027 
0028 /**
0029  * @see Zend_Tool_Framework_Provider_Abstract
0030  */
0031 // require_once 'Zend/Tool/Framework/Provider/Abstract.php';
0032 
0033 /**
0034  * @see Zend_Tool_Project_Context_Repository
0035  */
0036 // require_once 'Zend/Tool/Project/Context/Repository.php';
0037 
0038 /**
0039  * @see Zend_Tool_Project_Profile_FileParser_Xml
0040  */
0041 // require_once 'Zend/Tool/Project/Profile/FileParser/Xml.php';
0042 
0043 /**
0044  * @see Zend_Tool_Framework_Registry
0045  */
0046 // require_once 'Zend/Tool/Framework/Registry.php';
0047 
0048 // require_once 'Zend/Tool/Framework/Provider/Initializable.php';
0049 
0050 /**
0051  * @category   Zend
0052  * @package    Zend_Tool
0053  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0054  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0055  */
0056 abstract class Zend_Tool_Project_Provider_Abstract
0057     extends Zend_Tool_Framework_Provider_Abstract
0058     implements Zend_Tool_Framework_Provider_Initializable
0059 {
0060 
0061     const NO_PROFILE_THROW_EXCEPTION = true;
0062     const NO_PROFILE_RETURN_FALSE    = false;
0063 
0064     /**
0065      * @var bool
0066      */
0067     protected static $_isInitialized = false;
0068 
0069     protected $_projectPath = null;
0070 
0071     /**
0072      * @var Zend_Tool_Project_Profile
0073      */
0074     protected $_loadedProfile = null;
0075 
0076     public function initialize()
0077     {
0078         // initialize the ZF Contexts (only once per php request)
0079         if (!self::$_isInitialized) {
0080 
0081             // load all base contexts ONCE
0082             $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance();
0083             $contextRegistry->addContextsFromDirectory(
0084                 dirname(dirname(__FILE__)) . '/Context/Zf/', 'Zend_Tool_Project_Context_Zf_'
0085             );
0086             $contextRegistry->addContextsFromDirectory(
0087                 dirname(dirname(__FILE__)) . '/Context/Filesystem/', 'Zend_Tool_Project_Context_Filesystem_'
0088             );
0089 
0090             // determine if there are project specfic providers ONCE
0091             $profilePath = $this->_findProfileDirectory();
0092             if ($this->_hasProjectProviderDirectory($profilePath . DIRECTORY_SEPARATOR . '.zfproject.xml')) {
0093                 $profile = $this->_loadProfile();
0094                 // project providers directory resource
0095                 $ppd = $profile->search('ProjectProvidersDirectory');
0096                 $ppd->loadProviders($this->_registry);
0097             }
0098 
0099             self::$_isInitialized = true;
0100         }
0101 
0102         // load up the extending providers required context classes
0103         if ($contextClasses = $this->getContextClasses()) {
0104             $this->_loadContextClassesIntoRegistry($contextClasses);
0105         }
0106 
0107     }
0108 
0109     public function getContextClasses()
0110     {
0111         return array();
0112     }
0113 
0114     /**
0115      * _getProject is designed to find if there is project file in the context of where
0116      * the client has been called from..   The search order is as follows..
0117      *    - traversing downwards from (PWD) - current working directory
0118      *    - if an enpoint variable has been registered in teh client registry - key=workingDirectory
0119      *    - if an ENV variable with the key ZFPROJECT_PATH is found
0120      *
0121      * @param bool   $loadProfileFlag         Whether or not to throw an exception when no profile is found
0122      * @param string $projectDirectory        The project directory to use to search
0123      * @param bool   $searchParentDirectories Whether or not to search upper level direcotries
0124      * @return Zend_Tool_Project_Profile
0125      */
0126     protected function _loadProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION, $projectDirectory = null, $searchParentDirectories = true)
0127     {
0128         $foundPath = $this->_findProfileDirectory($projectDirectory, $searchParentDirectories);
0129 
0130         if ($foundPath == false) {
0131             if ($loadProfileFlag == self::NO_PROFILE_THROW_EXCEPTION) {
0132                 throw new Zend_Tool_Project_Provider_Exception('A project profile was not found.');
0133             } else {
0134                 return false;
0135             }
0136         }
0137 
0138         $profile = new Zend_Tool_Project_Profile();
0139         $profile->setAttribute('projectDirectory', $foundPath);
0140         $profile->loadFromFile();
0141         $this->_loadedProfile = $profile;
0142         return $profile;
0143     }
0144 
0145     protected function _findProfileDirectory($projectDirectory = null, $searchParentDirectories = true)
0146     {
0147         // use the cwd if no directory was provided
0148         if ($projectDirectory == null) {
0149             $projectDirectory = getcwd();
0150         } elseif (realpath($projectDirectory) == false) {
0151             throw new Zend_Tool_Project_Provider_Exception('The $projectDirectory supplied does not exist.');
0152         }
0153 
0154         $profile = new Zend_Tool_Project_Profile();
0155 
0156         $parentDirectoriesArray = explode(DIRECTORY_SEPARATOR, ltrim($projectDirectory, DIRECTORY_SEPARATOR));
0157         while ($parentDirectoriesArray) {
0158             $projectDirectoryAssembled = implode(DIRECTORY_SEPARATOR, $parentDirectoriesArray);
0159 
0160             if (DIRECTORY_SEPARATOR !== "\\") {
0161                 $projectDirectoryAssembled = DIRECTORY_SEPARATOR . $projectDirectoryAssembled;
0162             }
0163 
0164             $profile->setAttribute('projectDirectory', $projectDirectoryAssembled);
0165             if ($profile->isLoadableFromFile()) {
0166                 unset($profile);
0167                 return $projectDirectoryAssembled;
0168             }
0169 
0170             // break after first run if we are not to check upper directories
0171             if ($searchParentDirectories == false) {
0172                 break;
0173             }
0174 
0175             array_pop($parentDirectoriesArray);
0176         }
0177 
0178         return false;
0179     }
0180 
0181     /**
0182      * Load the project profile from the current working directory, if not throw exception
0183      *
0184      * @return Zend_Tool_Project_Profile
0185      */
0186     protected function _loadProfileRequired()
0187     {
0188         $profile = $this->_loadProfile();
0189         if ($profile === false) {
0190             // require_once 'Zend/Tool/Project/Provider/Exception.php';
0191             throw new Zend_Tool_Project_Provider_Exception('A project profile was not found in the current working directory.');
0192         }
0193         return $profile;
0194     }
0195 
0196     /**
0197      * Return the currently loaded profile
0198      *
0199      * @return Zend_Tool_Project_Profile
0200      */
0201     protected function _getProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION)
0202     {
0203         if (!$this->_loadedProfile) {
0204             if (($this->_loadProfile($loadProfileFlag) === false) && ($loadProfileFlag === self::NO_PROFILE_RETURN_FALSE)) {
0205                 return false;
0206             }
0207         }
0208 
0209         return $this->_loadedProfile;
0210     }
0211 
0212     /**
0213      * _storeProfile()
0214      *
0215      * This method will store the profile into its proper location
0216      *
0217      */
0218     protected function _storeProfile()
0219     {
0220         $projectProfileFile = $this->_loadedProfile->search('ProjectProfileFile');
0221 
0222         $name = $projectProfileFile->getContext()->getPath();
0223 
0224         $this->_registry->getResponse()->appendContent('Updating project profile \'' . $name . '\'');
0225 
0226         $projectProfileFile->getContext()->save();
0227     }
0228 
0229     protected function _getContentForContext(Zend_Tool_Project_Context_Interface $context, $methodName, $parameters)
0230     {
0231         $storage = $this->_registry->getStorage();
0232         if (!$storage->isEnabled()) {
0233             return false;
0234         }
0235 
0236         if (!class_exists('Zend_Tool_Project_Context_Content_Engine')) {
0237             // require_once 'Zend/Tool/Project/Context/Content/Engine.php';
0238         }
0239 
0240         $engine = new Zend_Tool_Project_Context_Content_Engine($storage);
0241         return $engine->getContent($context, $methodName, $parameters);
0242     }
0243 
0244     protected function _hasProjectProviderDirectory($pathToProfileFile)
0245     {
0246         // do some static analysis of the file so that we can determin whether or not to incure
0247         // the cost of loading the profile before the system is fully bootstrapped
0248         if (!file_exists($pathToProfileFile)) {
0249             return false;
0250         }
0251 
0252         $contents = file_get_contents($pathToProfileFile);
0253         if (strstr($contents, '<projectProvidersDirectory') === false) {
0254             return false;
0255         }
0256 
0257         if (strstr($contents, '<projectProvidersDirectory enabled="false"')) {
0258             return false;
0259         }
0260 
0261         return true;
0262     }
0263 
0264     /**
0265      * _loadContextClassesIntoRegistry() - This is called by the constructor
0266      * so that child providers can provide a list of contexts to load into the
0267      * context repository
0268      *
0269      * @param array $contextClasses
0270      */
0271     private function _loadContextClassesIntoRegistry($contextClasses)
0272     {
0273         $registry = Zend_Tool_Project_Context_Repository::getInstance();
0274 
0275         foreach ($contextClasses as $contextClass) {
0276             $registry->addContextClass($contextClass);
0277         }
0278     }
0279 }