[MANUAL] English:
[zend.git] / documentation / manual / en / module_specs / Zend_Tool_Framework-Architecture.xml
blobc1840d616e37aa7234b6e7aa78898a762b140804
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.tool.framework.architecture">
4     <title>Architecture</title>
6     <sect2 id="zend.tool.framework.architecture.registry">
7         <title>Registry</title>
9         <para>
10             Because providers and manifests may come from anywhere in the
11             <property>include_path</property>, a registry is provided to simplify access
12             to the various pieces of the toolchain. This registry is injected
13             into registry-aware components, which may then pull dependencies
14             from them as necessary. Most dependencies registered with the
15             registry will be sub-component-specific repositories.
16         </para>
18         <para>
19             The interface for the registry consists of the following definition:
20         </para>
22         <programlisting language="php"><![CDATA[
23 interface Zend_Tool_Framework_Registry_Interface
25     public function setClient(Zend_Tool_Framework_Client_Abstract $client);
26     public function getClient();
27     public function setLoader(Zend_Tool_Framework_Loader_Abstract $loader);
28     public function getLoader();
29     public function setActionRepository(
30         Zend_Tool_Framework_Action_Repository $actionRepository
31     );
32     public function getActionRepository();
33     public function setProviderRepository(
34         Zend_Tool_Framework_Provider_Repository $providerRepository
35     );
36     public function getProviderRepository();
37     public function setManifestRepository(
38         Zend_Tool_Framework_Manifest_Repository $manifestRepository
39     );
40     public function getManifestRepository();
41     public function setRequest(Zend_Tool_Framework_Client_Request $request);
42     public function getRequest();
43     public function setResponse(Zend_Tool_Framework_Client_Response $response);
44     public function getResponse();
46 ]]></programlisting>
48         <para>
49             The various objects the registry manages will be discussed in their
50             appropriate sections.
51         </para>
53         <para>
54             Classes that should be registry-aware should implement
55             <classname>Zend_Tool_Framework_Registry_EnabledInterface</classname>. This
56             interface merely allows initialization of the registry in the target
57             class.
58         </para>
60         <programlisting language="php"><![CDATA[
61 interface Zend_Tool_Framework_Registry_EnabledInterface
63     public function setRegistry(
64         Zend_Tool_Framework_Registry_Interface $registry
65     );
67 ]]></programlisting>
68     </sect2>
70     <sect2 id="zend.tool.framework.architecture.providers">
71         <title>Providers</title>
73         <para>
74             <classname>Zend_Tool_Framework_Provider</classname> represents the functional
75             or "capability" aspect of the framework. Fundamentally,
76             <classname>Zend_Tool_Framework_Provider</classname> will provide the
77             interfaces necessary to produce "providers", or bits of tooling
78             functionality that can be called and used inside the
79             <classname>Zend_Tool_Framework</classname> toolchain. The simplistic nature of
80             implementing this provider interface allows the developer a
81             "one-stop-shop" of adding functionality or capabilities to
82             <classname>Zend_Tool_Framework</classname>.
83         </para>
85         <para>
86             The provider interface is an empty interface and enforces no methods
87             (this is the Marker Interface pattern):
88         </para>
90         <programlisting language="php"><![CDATA[
91 interface Zend_Tool_Framework_Provider_Interface
93 ]]></programlisting>
95         <para>
96             Or, if you wish, you can implement the base (or abstract) Provider
97             which will give you access to the
98             <classname>Zend_Tool_Framework_Registry</classname>:
99         </para>
101         <programlisting language="php"><![CDATA[
102 abstract class Zend_Tool_Framework_Provider_Abstract
103     implements Zend_Tool_Framework_Provider_Interface,
104                Zend_Tool_Registry_EnabledInterface
106     protected $_registry;
107     public function setRegistry(
108         Zend_Tool_Framework_Registry_Interface $registry
109     );
111 ]]></programlisting>
112     </sect2>
114     <sect2 id="zend.tool.framework.architecture.loaders">
115         <title>Loaders</title>
117         <para>
118             The purpose of a Loader is to find Providers and Manifest files that
119             contain classes which implement either
120             <classname>Zend_Tool_Framework_Provider_Interface</classname> or
121             <classname>Zend_Tool_Framework_Manifest_Interface</classname>. Once these files are
122             found by a loader, providers are loaded into the Provider Repository and
123             manifest metadata is loaded into the Manifest Repository.
124         </para>
126         <para>
127             To implement a loader, one must extend the following abstract class:
128         </para>
130         <programlisting language="php"><![CDATA[
131 abstract class Zend_Tool_Framework_Loader_Abstract
134     abstract protected function _getFiles();
136     public function load()
137     {
138         /** ... */
139     }
141 ]]></programlisting>
143         <para>
144             The <methodname>_getFiles()</methodname> method should return an array of files
145             (absolute paths). The built-in loader supplied with Zend Framework is called the
146             IncludePath loader. By default, the Tooling framework will use an
147             include_path based loader to find files that might include Providers
148             or Manifest Metadata objects.
149             <classname>Zend_Tool_Framework_Loader_IncludePathLoader</classname>, without
150             any other options, will search for files inside the include path
151             that end in <filename>Mainfest.php</filename>, <filename>Tool.php</filename> or
152             <filename>Provider.php</filename>. Once found, they will be tested (by the
153             <methodname>load()</methodname> method of the
154             <classname>Zend_Tool_Framework_Loader_Abstract</classname>) to determine if
155             they implement any of the supported interfaces. If they do, an
156             instance of the found class is instantiated, and it is appended to
157             the proper repository.
158         </para>
160         <programlisting language="php"><![CDATA[
161 class Zend_Tool_Framework_Loader_IncludePathLoader
162     extends Zend_Tool_Framework_Loader_Abstract
165     protected $_filterDenyDirectoryPattern = '.*(/|\\\\).svn';
166     protected $_filterAcceptFilePattern = '.*(?:Manifest|Provider)\.php$';
168     protected function _getFiles()
169     {
170         /** ... */
171     }
173 ]]></programlisting>
175         <para>
176             As you can see, the IncludePath loader will search all include_paths
177             for the files that match the <varname>$_filterAcceptFilePattern</varname>
178             and <emphasis>not</emphasis> match the <varname>$_filterDenyDirectoryPattern</varname>.
179         </para>
180     </sect2>
182     <sect2 id="zend.tool.framework.architecture.manifests">
183         <title>Manifests</title>
185         <para>
186             In short, the Manifest shall contain specific or arbitrary metadata
187             that is useful to any provider or client, as well as be responsible
188             for loading any additional providers into the provider repository.
189         </para>
191         <para>
192             To introduce metadata into the manifest repository, all one must do
193             is implement the empty <classname>Zend_Tool_Framework_Manifest_Interface</classname>,
194             and provide a <methodname>getMetadata()</methodname> method which shall return an array
195             of objects that implement <classname>Zend_Tool_Framework_Manifest_Metadata</classname>.
196         </para>
198         <programlisting language="php"><![CDATA[
199 interface Zend_Tool_Framework_Manifest_Interface
201     public function getMetadata();
203 ]]></programlisting>
205         <para>
206             Metadata objects are loaded (by a loader defined below) into the
207             Manifest Repository (<classname>Zend_Tool_Framework_Manifest_Repository</classname>).
208             Manifests will be processed after all Providers have been found to be
209             loaded into the provider repository. This shall allow Manifests to
210             create Metadata objects based on what is currently inside the
211             provider repository.
212         </para>
214         <para>
215             There are a few different metadata classes that can be used to
216             describe metadata. The
217             <classname>Zend_Tool_Framework_Manifest_Metadata</classname> is the base
218             metadata object. As you can see by the following code
219             snippet, the base metadata class is fairly lightweight and
220             abstract in nature:
221         </para>
223         <programlisting language="php"><![CDATA[
224 class Zend_Tool_Framework_Metadata_Basic
227     protected $_type        = 'Global';
228     protected $_name        = null;
229     protected $_value       = null;
230     protected $_reference   = null;
232     public function getType();
233     public function getName();
234     public function getValue();
235     public function getReference();
236     /** ... */
238 ]]></programlisting>
240         <para>
241             There are other built in metadata classes as well for describing
242             more specialized metadata: <classname>ActionMetadata</classname> and
243             <classname>ProviderMetadata</classname>. These classes will help you describe
244             in more detail metadata that is specific to either actions or
245             providers, and the reference is expected to be a reference to an
246             action or a provider respectively. These classes are described in
247             the following code snippet.
248         </para>
250         <programlisting language="php"><![CDATA[
251 class Zend_Tool_Framework_Manifest_ActionMetadata
252     extends Zend_Tool_Framework_Manifest_Metadata
255     protected $_type = 'Action';
256     protected $_actionName = null;
258     public function getActionName();
259     /** ... */
262 class Zend_Tool_Framework_Manifest_ProviderMetadata
263     extends Zend_Tool_Framework_Manifest_Metadata
266     protected $_type = 'Provider';
267     protected $_providerName  = null;
268     protected $_actionName    = null;
269     protected $_specialtyName = null;
271     public function getProviderName();
272     public function getActionName();
273     public function getSpecialtyName();
274     /** ... */
276 ]]></programlisting>
278         <para>
279             'Type' in these classes is used to describe the type of metadata the
280             object is responsible for. In the cases of the
281             <classname>ActionMetadata</classname>, the type would be 'Action', and
282             conversely in the case of the <classname>ProviderMetadata</classname> the type
283             is 'Provider'. These metadata types will also include additional
284             structured information about both the "thing" they are describing as
285             well as the object (the <methodname>getReference()</methodname>) they are
286             referencing with this new metadata.
287         </para>
289         <para>
290             In order to create your own metadata type, all one must do is extend
291             the base <classname>Zend_Tool_Framework_Manifest_Metadata</classname> class
292             and return these new metadata objects via a local Manifest
293             class or object. These user based classes will live in the Manifest
294             Repository
295         </para>
297         <para>
298             Once these metadata objects are in the repository, there are then two
299             different methods that can be used in order to search for them in
300             the repository.
301         </para>
303         <programlisting language="php"><![CDATA[
304 class Zend_Tool_Framework_Manifest_Repository
306     /**
307      * To use this method to search, $searchProperties should contain the names
308      * and values of the key/value pairs you would like to match within the
309      * manifest.
310      *
311      * For Example:
312      *     $manifestRepository->findMetadatas(array(
313      *         'action' => 'Foo',
314      *         'name'   => 'cliActionName'
315      *         ));
316      *
317      * Will find any metadata objects that have a key with name 'action' value
318      * of 'Foo', AND a key named 'name' value of 'cliActionName'
319      *
320      * Note: to either exclude or include name/value pairs that exist in the
321      * search criteria but do not appear in the object, pass a bool value to
322      * $includeNonExistentProperties
323      */
324     public function findMetadatas(Array $searchProperties = array(),
325                                   $includeNonExistentProperties = true);
327     /**
328      * The following will return exactly one of the matching search criteria,
329      * regardless of how many have been returned. First one in the manifest is
330      * what will be returned.
331      */
332     public function findMetadata(Array $searchProperties = array(),
333                                  $includeNonExistentProperties = true)
334     {
335         $metadatas = $this->getMetadatas($searchProperties,
336                                          $includeNonExistentProperties);
337         return array_shift($metadatas);
338     }
340 ]]></programlisting>
342         <para>
343             Looking at the search methods above, the signatures allow for
344             extremely flexible searching. In order to find a metadata object,
345             simply pass in an array of matching constraints via an array. If
346             the data is accessible through the Property accessor (the
347             <methodname>getSomething()</methodname> methods implemented on the metadata
348             object), then it will be passed back to the user as a "found"
349             metadata object.
350         </para>
351     </sect2>
353     <sect2 id="zend.tool.framework.architecture.clients">
354         <title>Clients</title>
356         <para>
357             Clients are the interface which bridges a user or external tool into
358             the <classname>Zend_Tool_Framework</classname> system. Clients can come in all
359             shapes and sizes: <acronym>RPC</acronym> endpoints, Command Line Interface, or
360             even a web interface. <classname>Zend_Tool</classname> has implemented the command
361             line interface as the default interface for interacting with
362             the <classname>Zend_Tool_Framework</classname> system.
363         </para>
365         <para>
366             To implement a client, one would need to extend the following
367             abstract class:
368         </para>
370         <programlisting language="php"><![CDATA[
371 abstract class Zend_Tool_Framework_Client_Abstract
373     /**
374      * This method should be implemented by the client implementation to
375      * construct and set custom loaders, request and response objects.
376      *
377      * (not required, but suggested)
378      */
379     protected function _preInit();
381     /**
382      * This method should be implemented by the client implementation to parse
383      * out and set up the request objects action, provider and parameter
384      * information.
385      */
386     abstract protected function _preDispatch();
388     /**
389      * This method should be implemented by the client implementation to take
390      * the output of the response object and return it (in an client specific
391      * way) back to the Tooling Client.
392      *
393      * (not required, but suggested)
394      */
395     abstract protected function _postDispatch();
397 ]]></programlisting>
399         <para>
400             As you can see, there 1 method is required to fulfill the needs of a
401             client (two others suggested), the initialization, prehandling and post handling. For a
402             more in depth study of how the command line client works, please see
403             the <ulink
404                 url="http://framework.zend.com/svn/framework/standard/branches/release-1.8/library/Zend/Tool/Framework/Client/Console.php">source
405                 code</ulink>.
406         </para>
407     </sect2>
408 </sect1>