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.
17 * @subpackage Framework
18 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
20 * @version $Id: Repository.php 16971 2009-07-22 18:05:45Z mikaelkael $
24 * @see Zend_Tool_Framework_Registry_EnabledInterface
26 require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php';
31 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
32 * @license http://framework.zend.com/license/new-bsd New BSD License
34 class Zend_Tool_Framework_Manifest_Repository
35 implements Zend_Tool_Framework_Registry_EnabledInterface
, IteratorAggregate
, Countable
39 * @var Zend_Tool_Framework_Provider_Registry_Interface
41 protected $_registry = null;
46 protected $_manifests = array();
49 * @var array Array of Zend_Tool_Framework_Metadata_Interface
51 protected $_metadatas = array();
56 * @param Zend_Tool_Framework_Registry_Interface $registry
59 public function setRegistry(Zend_Tool_Framework_Registry_Interface
$registry)
61 $this->_registry
= $registry;
66 * addManifest() - Add a manifest for later processing
68 * @param Zend_Tool_Framework_Manifest_Interface $manifest
69 * @return Zend_Tool_Framework_Manifest_Repository
71 public function addManifest(Zend_Tool_Framework_Manifest_Interface
$manifest)
73 // we need to get an index number so that manifests with
74 // higher indexes have priority over others
75 $index = count($this->_manifests
);
77 if ($manifest instanceof Zend_Tool_Framework_Registry_EnabledInterface
) {
78 $manifest->setRegistry($this->_registry
);
81 // if the manifest supplies a getIndex() method, use it
82 if ($manifest instanceof Zend_Tool_Framework_Manifest_Indexable
) {
83 $index = $manifest->getIndex();
86 // get the required objects from the framework registry
87 $actionRepository = $this->_registry
->getActionRepository();
88 $providerRepository = $this->_registry
->getProviderRepository();
90 // load providers if interface supports that method
91 if ($manifest instanceof Zend_Tool_Framework_Manifest_ProviderManifestable
) {
92 $providers = $manifest->getProviders();
93 if (!is_array($providers)) {
94 $providers = array($providers);
97 foreach ($providers as $provider) {
98 if (!$provider instanceof Zend_Tool_Framework_Provider_Interface
) {
99 require_once 'Zend/Tool/Framework/Manifest/Exception.php';
100 throw new Zend_Tool_Framework_Manifest_Exception(
101 'A provider provided by the ' . get_class($manifest)
102 . ' does not implement Zend_Tool_Framework_Provider_Interface'
105 if (!$providerRepository->hasProvider($provider, false)) {
106 $providerRepository->addProvider($provider);
112 // load actions if interface supports that method
113 if ($manifest instanceof Zend_Tool_Framework_Manifest_ActionManifestable
) {
114 $actions = $manifest->getActions();
115 if (!is_array($actions)) {
116 $actions = array($actions);
119 foreach ($actions as $action) {
120 if (is_string($action)) {
121 $action = new Zend_Tool_Framework_Action_Base($action);
123 $actionRepository->addAction($action);
127 // should we detect collisions here? does it even matter?
128 $this->_manifests
[$index] = $manifest;
129 ksort($this->_manifests
);
137 * @return Zend_Tool_Framework_Manifest_Interface[]
139 public function getManifests()
141 return $this->_manifests
;
145 * addMetadata() - add a metadata peice by peice
147 * @param Zend_Tool_Framework_Manifest_Metadata $metadata
148 * @return Zend_Tool_Framework_Manifest_Repository
150 public function addMetadata(Zend_Tool_Framework_Metadata_Interface
$metadata)
152 $this->_metadatas
[] = $metadata;
157 * process() - Process is expected to be called at the end of client construction time.
158 * By this time, the loader has run and loaded any found manifests into the repository
161 * @return Zend_Tool_Framework_Manifest_Repository
163 public function process()
166 foreach ($this->_manifests
as $manifest) {
167 if ($manifest instanceof Zend_Tool_Framework_Manifest_MetadataManifestable
) {
168 $metadatas = $manifest->getMetadata();
169 if (!is_array($metadatas)) {
170 $metadatas = array($metadatas);
173 foreach ($metadatas as $metadata) {
174 if (!$metadata instanceof Zend_Tool_Framework_Metadata_Interface
) {
175 require_once 'Zend/Tool/Framework/Manifest/Exception.php';
176 throw new Zend_Tool_Framework_Manifest_Exception(
177 'A Zend_Tool_Framework_Metadata_Interface object was not found in manifest ' . get_class($manifest)
181 $this->addMetadata($metadata);
191 * getMetadatas() - This is the main search function for the repository.
193 * @example This will retrieve all metadata that matches the following criteria
194 * $manifestRepo->getMetadatas(array(
195 * 'providerName' => 'Version',
196 * 'actionName' => 'show'
199 * @param array $searchProperties
200 * @param bool $includeNonExistentProperties
201 * @return Zend_Tool_Framework_Manifest_Metadata[]
203 public function getMetadatas(Array $searchProperties = array(), $includeNonExistentProperties = true)
206 $returnMetadatas = array();
208 // loop through the metadatas so that we can search each individual one
209 foreach ($this->_metadatas
as $metadata) {
211 // each value will be retrieved from the metadata, each metadata should
212 // implement a getter method to retrieve the value
213 foreach ($searchProperties as $searchPropertyName => $searchPropertyValue) {
214 if (method_exists($metadata, 'get' . $searchPropertyName)) {
215 if ($metadata->{'get' . $searchPropertyName}() != $searchPropertyValue) {
216 // if the metadata supports a specific property but the value does not
220 } elseif (!$includeNonExistentProperties) {
221 // if the option $includeNonExitentProperties is false, then move on as
222 // we dont want to include this metadata if non existent
223 // search properties are not inside the target (current) metadata
228 // all searching has been accounted for, if we reach this point, then the metadata
229 // is good and we can return it
230 $returnMetadatas[] = $metadata;
234 return $returnMetadatas;
238 * getMetadata() - This will proxy to getMetadatas(), but will only return a single metadata. This method
239 * should be used in situations where the search criteria is known to only find a single metadata object
241 * @param array $searchProperties
242 * @param bool $includeNonExistentProperties
243 * @return Zend_Tool_Framework_Manifest_Metadata
245 public function getMetadata(Array $searchProperties = array(), $includeNonExistentProperties = true)
247 $metadatas = $this->getMetadatas($searchProperties, $includeNonExistentProperties);
248 return array_shift($metadatas);
252 * __toString() - cast to string
256 public function __toString()
258 $metadatasByType = array();
260 foreach ($this->_metadatas
as $metadata) {
261 if (!array_key_exists($metadata->getType(), $metadatasByType)) {
262 $metadatasByType[$metadata->getType()] = array();
264 $metadatasByType[$metadata->getType()][] = $metadata;
268 foreach ($metadatasByType as $type => $metadatas) {
269 $string .= $type . PHP_EOL
;
270 foreach ($metadatas as $metadata) {
271 $metadataString = ' ' . $metadata->__toString() . PHP_EOL
;
272 //$metadataString = str_replace(PHP_EOL, PHP_EOL . ' ', $metadataString);
273 $string .= $metadataString;
281 * count() - required by the Countable Interface
285 public function count()
287 return count($this->_metadatas
);
291 * getIterator() - required by the IteratorAggregate interface
293 * @return ArrayIterator
295 public function getIterator()
297 return new ArrayIterator($this->_metadatas
);