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 }