/zf/library/Zend/Tool/Project/Profile/Resource/Container.php
PHP | 421 lines | 185 code | 49 blank | 187 comment | 25 complexity | d9406c220cbea4491fc9da206a8c5a02 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
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-2011 Zend Technologies USA Inc. (http://www.zend.com) 19 * @license http://framework.zend.com/license/new-bsd New BSD License 20 * @version $Id: Container.php 23775 2011-03-01 17:25:24Z ralph $ 21 */ 22 23/** 24 * @see Zend_Tool_Project_Profile_Resource_SearchConstraints 25 */ 26require_once 'Zend/Tool/Project/Profile/Resource/SearchConstraints.php'; 27 28/** 29 * This class is an iterator that will iterate only over enabled resources 30 * 31 * @category Zend 32 * @package Zend_Tool 33 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) 34 * @license http://framework.zend.com/license/new-bsd New BSD License 35 */ 36class Zend_Tool_Project_Profile_Resource_Container implements RecursiveIterator, Countable 37{ 38 39 /** 40 * @var array 41 */ 42 protected $_subResources = array(); 43 44 /** 45 * @var int 46 */ 47 protected $_position = 0; 48 49 /** 50 * @var bool 51 */ 52 protected $_appendable = true; 53 54 /** 55 * @var array 56 */ 57 protected $_attributes = array(); 58 59 /** 60 * Finder method to be able to find resources by context name 61 * and attributes. Example usage: 62 * 63 * <code> 64 * 65 * </code> 66 * 67 * @param Zend_Tool_Project_Profile_Resource_SearchConstraints|string|array $searchParameters 68 * @return Zend_Tool_Project_Profile_Resource 69 */ 70 public function search($matchSearchConstraints, $nonMatchSearchConstraints = null) 71 { 72 if (!$matchSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_SearchConstraints) { 73 $matchSearchConstraints = new Zend_Tool_Project_Profile_Resource_SearchConstraints($matchSearchConstraints); 74 } 75 76 $this->rewind(); 77 78 /** 79 * @todo This should be re-written with better support for a filter iterator, its the way to go 80 */ 81 82 if ($nonMatchSearchConstraints) { 83 $filterIterator = new Zend_Tool_Project_Profile_Iterator_ContextFilter($this, array('denyNames' => $nonMatchSearchConstraints)); 84 $riIterator = new RecursiveIteratorIterator($filterIterator, RecursiveIteratorIterator::SELF_FIRST); 85 } else { 86 $riIterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST); 87 } 88 89 $foundResource = false; 90 $currentConstraint = $matchSearchConstraints->getConstraint(); 91 $foundDepth = 0; 92 93 foreach ($riIterator as $currentResource) { 94 95 // if current depth is less than found depth, end 96 if ($riIterator->getDepth() < $foundDepth) { 97 break; 98 } 99 100 if (strtolower($currentResource->getName()) == strtolower($currentConstraint->name)) { 101 102 $paramsMatch = true; 103 104 // @todo check to ensure params match (perhaps) 105 if (count($currentConstraint->params) > 0) { 106 $currentResourceAttributes = $currentResource->getAttributes(); 107 if (!is_array($currentConstraint->params)) { 108 require_once 'Zend/Tool/Project/Profile/Exception.php'; 109 throw new Zend_Tool_Project_Profile_Exception('Search parameter specifics must be in the form of an array for key "' 110 . $currentConstraint->name .'"'); 111 } 112 foreach ($currentConstraint->params as $paramName => $paramValue) { 113 if (!isset($currentResourceAttributes[$paramName]) || $currentResourceAttributes[$paramName] != $paramValue) { 114 $paramsMatch = false; 115 break; 116 } 117 } 118 } 119 120 if ($paramsMatch) { 121 $foundDepth = $riIterator->getDepth(); 122 123 if (($currentConstraint = $matchSearchConstraints->getConstraint()) == null) { 124 $foundResource = $currentResource; 125 break; 126 } 127 } 128 129 } 130 131 } 132 133 return $foundResource; 134 } 135 136 /** 137 * createResourceAt() 138 * 139 * @param array|Zend_Tool_Project_Profile_Resource_SearchConstraints $appendResourceOrSearchConstraints 140 * @param string $context 141 * @param array $attributes 142 * @return Zend_Tool_Project_Profile_Resource 143 */ 144 public function createResourceAt($appendResourceOrSearchConstraints, $context, Array $attributes = array()) 145 { 146 if (!$appendResourceOrSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_Container) { 147 if (($parentResource = $this->search($appendResourceOrSearchConstraints)) == false) { 148 require_once 'Zend/Tool/Project/Profile/Exception.php'; 149 throw new Zend_Tool_Project_Profile_Exception('No node was found to append to.'); 150 } 151 } else { 152 $parentResource = $appendResourceOrSearchConstraints; 153 } 154 155 return $parentResource->createResource($context, $attributes); 156 } 157 158 /** 159 * createResource() 160 * 161 * Method to create a resource with a given context with specific attributes 162 * 163 * @param string $context 164 * @param array $attributes 165 * @return Zend_Tool_Project_Profile_Resource 166 */ 167 public function createResource($context, Array $attributes = array()) 168 { 169 if (is_string($context)) { 170 $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance(); 171 if ($contextRegistry->hasContext($context)) { 172 $context = $contextRegistry->getContext($context); 173 } else { 174 require_once 'Zend/Tool/Project/Profile/Exception.php'; 175 throw new Zend_Tool_Project_Profile_Exception('Context by name ' . $context . ' was not found in the context registry.'); 176 } 177 } elseif (!$context instanceof Zend_Tool_Project_Context_Interface) { 178 require_once 'Zend/Tool/Project/Profile/Exception.php'; 179 throw new Zend_Tool_Project_Profile_Exception('Context must be of type string or Zend_Tool_Project_Context_Interface.'); 180 } 181 182 $newResource = new Zend_Tool_Project_Profile_Resource($context); 183 184 if ($attributes) { 185 $newResource->setAttributes($attributes); 186 } 187 188 /** 189 * Interesting logic here: 190 * 191 * First set the parentResource (this will also be done inside append). This will allow 192 * the initialization routine to change the appendability of the parent resource. This 193 * is important to allow specific resources to be appendable by very specific sub-resources. 194 */ 195 $newResource->setParentResource($this); 196 $newResource->initializeContext(); 197 $this->append($newResource); 198 199 return $newResource; 200 } 201 202 /** 203 * setAttributes() 204 * 205 * persist the attributes if the resource will accept them 206 * 207 * @param array $attributes 208 * @return Zend_Tool_Project_Profile_Resource_Container 209 */ 210 public function setAttributes(Array $attributes) 211 { 212 foreach ($attributes as $attrName => $attrValue) { 213 $setMethod = 'set' . $attrName; 214 if (method_exists($this, $setMethod)) { 215 $this->{$setMethod}($attrValue); 216 } else { 217 $this->setAttribute($attrName, $attrValue); 218 } 219 } 220 return $this; 221 } 222 223 /** 224 * getAttributes() 225 * 226 * @return array 227 */ 228 public function getAttributes() 229 { 230 return $this->_attributes; 231 } 232 233 /** 234 * setAttribute() 235 * 236 * @param string $name 237 * @param mixed $value 238 * @return Zend_Tool_Project_Profile_Resource_Container 239 */ 240 public function setAttribute($name, $value) 241 { 242 $this->_attributes[$name] = $value; 243 return $this; 244 } 245 246 /** 247 * getAttribute() 248 * 249 * @param string $name 250 * @return Zend_Tool_Project_Profile_Resource_Container 251 */ 252 public function getAttribute($name) 253 { 254 return (array_key_exists($name, $this->_attributes)) ? $this->_attributes[$name] : null; 255 } 256 257 /** 258 * hasAttribute() 259 * 260 * @param string $name 261 * @return bool 262 */ 263 public function hasAttribute($name) 264 { 265 return array_key_exists($name, $this->_attributes); 266 } 267 268 /** 269 * setAppendable() 270 * 271 * @param bool $appendable 272 * @return Zend_Tool_Project_Profile_Resource_Container 273 */ 274 public function setAppendable($appendable) 275 { 276 $this->_appendable = (bool) $appendable; 277 return $this; 278 } 279 280 /** 281 * isAppendable() 282 * 283 * @return bool 284 */ 285 public function isAppendable() 286 { 287 return $this->_appendable; 288 } 289 290 /** 291 * setParentResource() 292 * 293 * @param Zend_Tool_Project_Profile_Resource_Container $parentResource 294 * @return Zend_Tool_Project_Profile_Resource_Container 295 */ 296 public function setParentResource(Zend_Tool_Project_Profile_Resource_Container $parentResource) 297 { 298 $this->_parentResource = $parentResource; 299 return $this; 300 } 301 302 /** 303 * getParentResource() 304 * 305 * @return Zend_Tool_Project_Profile_Resource_Container 306 */ 307 public function getParentResource() 308 { 309 return $this->_parentResource; 310 } 311 312 /** 313 * append() 314 * 315 * @param Zend_Tool_Project_Profile_Resource_Container $resource 316 * @return Zend_Tool_Project_Profile_Resource_Container 317 */ 318 public function append(Zend_Tool_Project_Profile_Resource_Container $resource) 319 { 320 if (!$this->isAppendable()) { 321 throw new Exception('Resource by name ' . (string) $this . ' is not appendable'); 322 } 323 array_push($this->_subResources, $resource); 324 $resource->setParentResource($this); 325 326 return $this; 327 } 328 329 /** 330 * current() - required by RecursiveIterator 331 * 332 * @return Zend_Tool_Project_Profile_Resource 333 */ 334 public function current() 335 { 336 return current($this->_subResources); 337 } 338 339 /** 340 * key() - required by RecursiveIterator 341 * 342 * @return int 343 */ 344 public function key() 345 { 346 return key($this->_subResources); 347 } 348 349 /** 350 * next() - required by RecursiveIterator 351 * 352 * @return bool 353 */ 354 public function next() 355 { 356 return next($this->_subResources); 357 } 358 359 /** 360 * rewind() - required by RecursiveIterator 361 * 362 * @return bool 363 */ 364 public function rewind() 365 { 366 return reset($this->_subResources); 367 } 368 369 /** 370 * valid() - - required by RecursiveIterator 371 * 372 * @return bool 373 */ 374 public function valid() 375 { 376 return (bool) $this->current(); 377 } 378 379 /** 380 * hasChildren() 381 * 382 * @return bool 383 */ 384 public function hasChildren() 385 { 386 return (count($this->_subResources > 0)) ? true : false; 387 } 388 389 /** 390 * getChildren() 391 * 392 * @return array 393 */ 394 public function getChildren() 395 { 396 return $this->current(); 397 } 398 399 /** 400 * count() 401 * 402 * @return int 403 */ 404 public function count() 405 { 406 return count($this->_subResources); 407 } 408 409 /** 410 * __clone() 411 * 412 */ 413 public function __clone() 414 { 415 $this->rewind(); 416 foreach ($this->_subResources as $index => $resource) { 417 $this->_subResources[$index] = clone $resource; 418 } 419 } 420 421}