File indexing completed on 2024-12-29 05:28:09

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 // require_once 'Zend/Tool/Project/Profile/FileParser/Interface.php';
0024 // require_once 'Zend/Tool/Project/Context/Repository.php';
0025 // require_once 'Zend/Tool/Project/Profile.php';
0026 // require_once 'Zend/Tool/Project/Profile/Resource.php';
0027 
0028 /**
0029  * @category   Zend
0030  * @package    Zend_Tool
0031  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0032  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0033  */
0034 class Zend_Tool_Project_Profile_FileParser_Xml implements Zend_Tool_Project_Profile_FileParser_Interface
0035 {
0036 
0037     /**
0038      * @var Zend_Tool_Project_Profile
0039      */
0040     protected $_profile = null;
0041 
0042     /**
0043      * @var Zend_Tool_Project_Context_Repository
0044      */
0045     protected $_contextRepository = null;
0046 
0047     /**
0048      * __construct()
0049      *
0050      */
0051     public function __construct()
0052     {
0053         $this->_contextRepository = Zend_Tool_Project_Context_Repository::getInstance();
0054     }
0055 
0056     /**
0057      * serialize()
0058      *
0059      * create an xml string from the provided profile
0060      *
0061      * @param Zend_Tool_Project_Profile $profile
0062      * @return string
0063      */
0064     public function serialize(Zend_Tool_Project_Profile $profile)
0065     {
0066 
0067         $profile = clone $profile;
0068 
0069         $this->_profile = $profile;
0070         $xmlElement = new SimpleXMLElement('<projectProfile />');
0071 
0072         if ($profile->hasAttribute('type')) {
0073             $xmlElement->addAttribute('type', $profile->getAttribute('type'));
0074         }
0075 
0076         if ($profile->hasAttribute('version')) {
0077             $xmlElement->addAttribute('version', $profile->getAttribute('version'));
0078         }
0079 
0080         self::_serializeRecurser($profile, $xmlElement);
0081 
0082         $doc = new DOMDocument('1.0');
0083         $doc->formatOutput = true;
0084         $domnode = dom_import_simplexml($xmlElement);
0085         $domnode = $doc->importNode($domnode, true);
0086         $domnode = $doc->appendChild($domnode);
0087 
0088         return $doc->saveXML();
0089     }
0090 
0091     /**
0092      * unserialize()
0093      *
0094      * Create a structure in the object $profile from the structure specficied
0095      * in the xml string provided
0096      *
0097      * @param string xml data
0098      * @param Zend_Tool_Project_Profile The profile to use as the top node
0099      * @return Zend_Tool_Project_Profile
0100      */
0101     public function unserialize($data, Zend_Tool_Project_Profile $profile)
0102     {
0103         if ($data == null) {
0104             throw new Exception('contents not available to unserialize.');
0105         }
0106 
0107         $this->_profile = $profile;
0108 
0109         $xmlDataIterator = new SimpleXMLIterator($data);
0110 
0111         if ($xmlDataIterator->getName() != 'projectProfile') {
0112             throw new Exception('Profiles must start with a projectProfile node');
0113         }
0114 
0115         if (isset($xmlDataIterator['type'])) {
0116             $this->_profile->setAttribute('type', (string) $xmlDataIterator['type']);
0117         }
0118 
0119         if (isset($xmlDataIterator['version'])) {
0120             $this->_profile->setAttribute('version', (string) $xmlDataIterator['version']);
0121         }
0122 
0123         // start un-serialization of the xml doc
0124         $this->_unserializeRecurser($xmlDataIterator);
0125 
0126         // contexts should be initialized after the unwinding of the profile structure
0127         $this->_lazyLoadContexts();
0128 
0129         return $this->_profile;
0130 
0131     }
0132 
0133     /**
0134      * _serializeRecurser()
0135      *
0136      * This method will be used to traverse the depths of the structure
0137      * when *serializing* an xml structure into a string
0138      *
0139      * @param array $resources
0140      * @param SimpleXmlElement $xmlNode
0141      */
0142     protected function _serializeRecurser($resources, SimpleXmlElement $xmlNode)
0143     {
0144         // @todo find a better way to handle concurrency.. if no clone, _position in node gets messed up
0145         //if ($resources instanceof Zend_Tool_Project_Profile_Resource) {
0146         //    $resources = clone $resources;
0147         //}
0148 
0149         foreach ($resources as $resource) {
0150 
0151             if ($resource->isDeleted()) {
0152                 continue;
0153             }
0154 
0155             $resourceName = $resource->getContext()->getName();
0156             $resourceName[0] = strtolower($resourceName[0]);
0157 
0158             $newNode = $xmlNode->addChild($resourceName);
0159 
0160             //$reflectionClass = new ReflectionClass($resource->getContext());
0161 
0162             if ($resource->isEnabled() == false) {
0163                 $newNode->addAttribute('enabled', 'false');
0164             }
0165 
0166             foreach ($resource->getPersistentAttributes() as $paramName => $paramValue) {
0167                 $newNode->addAttribute($paramName, $paramValue);
0168             }
0169 
0170             if ($resource->hasChildren()) {
0171                 self::_serializeRecurser($resource, $newNode);
0172             }
0173 
0174         }
0175 
0176     }
0177 
0178 
0179     /**
0180      * _unserializeRecurser()
0181      *
0182      * This method will be used to traverse the depths of the structure
0183      * as needed to *unserialize* the profile from an xmlIterator
0184      *
0185      * @param SimpleXMLIterator $xmlIterator
0186      * @param Zend_Tool_Project_Profile_Resource $resource
0187      */
0188     protected function _unserializeRecurser(SimpleXMLIterator $xmlIterator, Zend_Tool_Project_Profile_Resource $resource = null)
0189     {
0190 
0191         foreach ($xmlIterator as $resourceName => $resourceData) {
0192 
0193             $contextName = $resourceName;
0194             $subResource = new Zend_Tool_Project_Profile_Resource($contextName);
0195             $subResource->setProfile($this->_profile);
0196 
0197             if ($resourceAttributes = $resourceData->attributes()) {
0198                 $attributes = array();
0199                 foreach ($resourceAttributes as $attrName => $attrValue) {
0200                     $attributes[$attrName] = (string) $attrValue;
0201                 }
0202                 $subResource->setAttributes($attributes);
0203             }
0204 
0205             if ($resource) {
0206                 $resource->append($subResource, false);
0207             } else {
0208                 $this->_profile->append($subResource);
0209             }
0210 
0211             if ($this->_contextRepository->isOverwritableContext($contextName) == false) {
0212                 $subResource->initializeContext();
0213             }
0214 
0215             if ($xmlIterator->hasChildren()) {
0216                 self::_unserializeRecurser($xmlIterator->getChildren(), $subResource);
0217             }
0218         }
0219     }
0220 
0221     /**
0222      * _lazyLoadContexts()
0223      *
0224      * This method will call initializeContext on the resources in a profile
0225      * @todo determine if this method belongs inside the profile
0226      *
0227      */
0228     protected function _lazyLoadContexts()
0229     {
0230 
0231         foreach ($this->_profile as $topResource) {
0232             $rii = new RecursiveIteratorIterator($topResource, RecursiveIteratorIterator::SELF_FIRST);
0233             foreach ($rii as $resource) {
0234                 $resource->initializeContext();
0235             }
0236         }
0237 
0238     }
0239 
0240 }