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 /** 0024 * @see Zend_Tool_Project_Profile_Resource_SearchConstraints 0025 */ 0026 // require_once 'Zend/Tool/Project/Profile/Resource/SearchConstraints.php'; 0027 0028 /** 0029 * This class is an iterator that will iterate only over enabled resources 0030 * 0031 * @category Zend 0032 * @package Zend_Tool 0033 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0034 * @license http://framework.zend.com/license/new-bsd New BSD License 0035 */ 0036 class Zend_Tool_Project_Profile_Resource_Container implements RecursiveIterator, Countable 0037 { 0038 0039 /** 0040 * @var array 0041 */ 0042 protected $_subResources = array(); 0043 0044 /** 0045 * @var int 0046 */ 0047 protected $_position = 0; 0048 0049 /** 0050 * @var bool 0051 */ 0052 protected $_appendable = true; 0053 0054 /** 0055 * @var array 0056 */ 0057 protected $_attributes = array(); 0058 0059 /** 0060 * Finder method to be able to find resources by context name 0061 * and attributes. Example usage: 0062 * 0063 * <code> 0064 * 0065 * </code> 0066 * 0067 * @param Zend_Tool_Project_Profile_Resource_SearchConstraints|string|array $searchParameters 0068 * @return Zend_Tool_Project_Profile_Resource 0069 */ 0070 public function search($matchSearchConstraints, $nonMatchSearchConstraints = null) 0071 { 0072 if (!$matchSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_SearchConstraints) { 0073 $matchSearchConstraints = new Zend_Tool_Project_Profile_Resource_SearchConstraints($matchSearchConstraints); 0074 } 0075 0076 $this->rewind(); 0077 0078 /** 0079 * @todo This should be re-written with better support for a filter iterator, its the way to go 0080 */ 0081 0082 if ($nonMatchSearchConstraints) { 0083 $filterIterator = new Zend_Tool_Project_Profile_Iterator_ContextFilter($this, array('denyNames' => $nonMatchSearchConstraints)); 0084 $riIterator = new RecursiveIteratorIterator($filterIterator, RecursiveIteratorIterator::SELF_FIRST); 0085 } else { 0086 $riIterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST); 0087 } 0088 0089 $foundResource = false; 0090 $currentConstraint = $matchSearchConstraints->getConstraint(); 0091 $foundDepth = 0; 0092 0093 foreach ($riIterator as $currentResource) { 0094 0095 // if current depth is less than found depth, end 0096 if ($riIterator->getDepth() < $foundDepth) { 0097 break; 0098 } 0099 0100 if (strtolower($currentResource->getName()) == strtolower($currentConstraint->name)) { 0101 0102 $paramsMatch = true; 0103 0104 // @todo check to ensure params match (perhaps) 0105 if (count($currentConstraint->params) > 0) { 0106 $currentResourceAttributes = $currentResource->getAttributes(); 0107 if (!is_array($currentConstraint->params)) { 0108 // require_once 'Zend/Tool/Project/Profile/Exception.php'; 0109 throw new Zend_Tool_Project_Profile_Exception('Search parameter specifics must be in the form of an array for key "' 0110 . $currentConstraint->name .'"'); 0111 } 0112 foreach ($currentConstraint->params as $paramName => $paramValue) { 0113 if (!isset($currentResourceAttributes[$paramName]) || $currentResourceAttributes[$paramName] != $paramValue) { 0114 $paramsMatch = false; 0115 break; 0116 } 0117 } 0118 } 0119 0120 if ($paramsMatch) { 0121 $foundDepth = $riIterator->getDepth(); 0122 0123 if (($currentConstraint = $matchSearchConstraints->getConstraint()) == null) { 0124 $foundResource = $currentResource; 0125 break; 0126 } 0127 } 0128 0129 } 0130 0131 } 0132 0133 return $foundResource; 0134 } 0135 0136 /** 0137 * createResourceAt() 0138 * 0139 * @param array|Zend_Tool_Project_Profile_Resource_SearchConstraints $appendResourceOrSearchConstraints 0140 * @param string $context 0141 * @param array $attributes 0142 * @return Zend_Tool_Project_Profile_Resource 0143 */ 0144 public function createResourceAt($appendResourceOrSearchConstraints, $context, Array $attributes = array()) 0145 { 0146 if (!$appendResourceOrSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_Container) { 0147 if (($parentResource = $this->search($appendResourceOrSearchConstraints)) == false) { 0148 // require_once 'Zend/Tool/Project/Profile/Exception.php'; 0149 throw new Zend_Tool_Project_Profile_Exception('No node was found to append to.'); 0150 } 0151 } else { 0152 $parentResource = $appendResourceOrSearchConstraints; 0153 } 0154 0155 return $parentResource->createResource($context, $attributes); 0156 } 0157 0158 /** 0159 * createResource() 0160 * 0161 * Method to create a resource with a given context with specific attributes 0162 * 0163 * @param string $context 0164 * @param array $attributes 0165 * @return Zend_Tool_Project_Profile_Resource 0166 */ 0167 public function createResource($context, Array $attributes = array()) 0168 { 0169 if (is_string($context)) { 0170 $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance(); 0171 if ($contextRegistry->hasContext($context)) { 0172 $context = $contextRegistry->getContext($context); 0173 } else { 0174 // require_once 'Zend/Tool/Project/Profile/Exception.php'; 0175 throw new Zend_Tool_Project_Profile_Exception('Context by name ' . $context . ' was not found in the context registry.'); 0176 } 0177 } elseif (!$context instanceof Zend_Tool_Project_Context_Interface) { 0178 // require_once 'Zend/Tool/Project/Profile/Exception.php'; 0179 throw new Zend_Tool_Project_Profile_Exception('Context must be of type string or Zend_Tool_Project_Context_Interface.'); 0180 } 0181 0182 $newResource = new Zend_Tool_Project_Profile_Resource($context); 0183 0184 if ($attributes) { 0185 $newResource->setAttributes($attributes); 0186 } 0187 0188 /** 0189 * Interesting logic here: 0190 * 0191 * First set the parentResource (this will also be done inside append). This will allow 0192 * the initialization routine to change the appendability of the parent resource. This 0193 * is important to allow specific resources to be appendable by very specific sub-resources. 0194 */ 0195 $newResource->setParentResource($this); 0196 $newResource->initializeContext(); 0197 $this->append($newResource); 0198 0199 return $newResource; 0200 } 0201 0202 /** 0203 * setAttributes() 0204 * 0205 * persist the attributes if the resource will accept them 0206 * 0207 * @param array $attributes 0208 * @return Zend_Tool_Project_Profile_Resource_Container 0209 */ 0210 public function setAttributes(Array $attributes) 0211 { 0212 foreach ($attributes as $attrName => $attrValue) { 0213 $setMethod = 'set' . $attrName; 0214 if (method_exists($this, $setMethod)) { 0215 $this->{$setMethod}($attrValue); 0216 } else { 0217 $this->setAttribute($attrName, $attrValue); 0218 } 0219 } 0220 return $this; 0221 } 0222 0223 /** 0224 * getAttributes() 0225 * 0226 * @return array 0227 */ 0228 public function getAttributes() 0229 { 0230 return $this->_attributes; 0231 } 0232 0233 /** 0234 * setAttribute() 0235 * 0236 * @param string $name 0237 * @param mixed $value 0238 * @return Zend_Tool_Project_Profile_Resource_Container 0239 */ 0240 public function setAttribute($name, $value) 0241 { 0242 $this->_attributes[$name] = $value; 0243 return $this; 0244 } 0245 0246 /** 0247 * getAttribute() 0248 * 0249 * @param string $name 0250 * @return Zend_Tool_Project_Profile_Resource_Container 0251 */ 0252 public function getAttribute($name) 0253 { 0254 return (array_key_exists($name, $this->_attributes)) ? $this->_attributes[$name] : null; 0255 } 0256 0257 /** 0258 * hasAttribute() 0259 * 0260 * @param string $name 0261 * @return bool 0262 */ 0263 public function hasAttribute($name) 0264 { 0265 return array_key_exists($name, $this->_attributes); 0266 } 0267 0268 /** 0269 * setAppendable() 0270 * 0271 * @param bool $appendable 0272 * @return Zend_Tool_Project_Profile_Resource_Container 0273 */ 0274 public function setAppendable($appendable) 0275 { 0276 $this->_appendable = (bool) $appendable; 0277 return $this; 0278 } 0279 0280 /** 0281 * isAppendable() 0282 * 0283 * @return bool 0284 */ 0285 public function isAppendable() 0286 { 0287 return $this->_appendable; 0288 } 0289 0290 /** 0291 * setParentResource() 0292 * 0293 * @param Zend_Tool_Project_Profile_Resource_Container $parentResource 0294 * @return Zend_Tool_Project_Profile_Resource_Container 0295 */ 0296 public function setParentResource(Zend_Tool_Project_Profile_Resource_Container $parentResource) 0297 { 0298 $this->_parentResource = $parentResource; 0299 return $this; 0300 } 0301 0302 /** 0303 * getParentResource() 0304 * 0305 * @return Zend_Tool_Project_Profile_Resource_Container 0306 */ 0307 public function getParentResource() 0308 { 0309 return $this->_parentResource; 0310 } 0311 0312 /** 0313 * append() 0314 * 0315 * @param Zend_Tool_Project_Profile_Resource_Container $resource 0316 * @return Zend_Tool_Project_Profile_Resource_Container 0317 */ 0318 public function append(Zend_Tool_Project_Profile_Resource_Container $resource) 0319 { 0320 if (!$this->isAppendable()) { 0321 throw new Exception('Resource by name ' . (string) $this . ' is not appendable'); 0322 } 0323 array_push($this->_subResources, $resource); 0324 $resource->setParentResource($this); 0325 0326 return $this; 0327 } 0328 0329 /** 0330 * current() - required by RecursiveIterator 0331 * 0332 * @return Zend_Tool_Project_Profile_Resource 0333 */ 0334 public function current() 0335 { 0336 return current($this->_subResources); 0337 } 0338 0339 /** 0340 * key() - required by RecursiveIterator 0341 * 0342 * @return int 0343 */ 0344 public function key() 0345 { 0346 return key($this->_subResources); 0347 } 0348 0349 /** 0350 * next() - required by RecursiveIterator 0351 * 0352 * @return bool 0353 */ 0354 public function next() 0355 { 0356 return next($this->_subResources); 0357 } 0358 0359 /** 0360 * rewind() - required by RecursiveIterator 0361 * 0362 * @return bool 0363 */ 0364 public function rewind() 0365 { 0366 return reset($this->_subResources); 0367 } 0368 0369 /** 0370 * valid() - - required by RecursiveIterator 0371 * 0372 * @return bool 0373 */ 0374 public function valid() 0375 { 0376 return (bool) $this->current(); 0377 } 0378 0379 /** 0380 * hasChildren() 0381 * 0382 * @return bool 0383 */ 0384 public function hasChildren() 0385 { 0386 return (count($this->_subResources > 0)) ? true : false; 0387 } 0388 0389 /** 0390 * getChildren() 0391 * 0392 * @return array 0393 */ 0394 public function getChildren() 0395 { 0396 return $this->current(); 0397 } 0398 0399 /** 0400 * count() 0401 * 0402 * @return int 0403 */ 0404 public function count() 0405 { 0406 return count($this->_subResources); 0407 } 0408 0409 /** 0410 * __clone() 0411 * 0412 */ 0413 public function __clone() 0414 { 0415 $this->rewind(); 0416 foreach ($this->_subResources as $index => $resource) { 0417 $this->_subResources[$index] = clone $resource; 0418 } 0419 } 0420 0421 }