| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.tool.framework.architecture">
- <title>Architecture</title>
- <sect2 id="zend.tool.framework.architecture.registry">
- <title>Registry</title>
- <para>
- Because providers and manifests may come from anywhere in the
- <property>include_path</property>, a registry is provided to simplify access
- to the various pieces of the toolchain. This registry is injected
- into registry-aware components, which may then pull dependencies
- from them as necessary. Most dependencies registered with the
- registry will be sub-component-specific repositories.
- </para>
- <para>
- The interface for the registry consists of the following definition:
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Tool_Framework_Registry_Interface
- {
- public function setClient(Zend_Tool_Framework_Client_Abstract $client);
- public function getClient();
- public function setLoader(Zend_Tool_Framework_Loader_Abstract $loader);
- public function getLoader();
- public function setActionRepository(
- Zend_Tool_Framework_Action_Repository $actionRepository
- );
- public function getActionRepository();
- public function setProviderRepository(
- Zend_Tool_Framework_Provider_Repository $providerRepository
- );
- public function getProviderRepository();
- public function setManifestRepository(
- Zend_Tool_Framework_Manifest_Repository $manifestRepository
- );
- public function getManifestRepository();
- public function setRequest(Zend_Tool_Framework_Client_Request $request);
- public function getRequest();
- public function setResponse(Zend_Tool_Framework_Client_Response $response);
- public function getResponse();
- }
- ]]></programlisting>
- <para>
- The various objects the registry manages will be discussed in their
- appropriate sections.
- </para>
- <para>
- Classes that should be registry-aware should implement
- <classname>Zend_Tool_Framework_Registry_EnabledInterface</classname>. This
- interface merely allows initialization of the registry in the target
- class.
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Tool_Framework_Registry_EnabledInterface
- {
- public function setRegistry(
- Zend_Tool_Framework_Registry_Interface $registry
- );
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.tool.framework.architecture.providers">
- <title>Providers</title>
- <para>
- <classname>Zend_Tool_Framework_Provider</classname> represents the functional
- or "capability" aspect of the framework. Fundamentally,
- <classname>Zend_Tool_Framework_Provider</classname> will provide the
- interfaces necessary to produce "providers", or bits of tooling
- functionality that can be called and used inside the
- <classname>Zend_Tool_Framework</classname> toolchain. The simplistic nature of
- implementing this provider interface allows the developer a
- "one-stop-shop" of adding functionality or capabilities to
- <classname>Zend_Tool_Framework</classname>.
- </para>
- <para>
- The provider interface is an empty interface and enforces no methods
- (this is the Marker Interface pattern):
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Tool_Framework_Provider_Interface
- {}
- ]]></programlisting>
- <para>
- Or, if you wish, you can implement the base (or abstract) Provider
- which will give you access to the
- <classname>Zend_Tool_Framework_Registry</classname>:
- </para>
- <programlisting language="php"><![CDATA[
- abstract class Zend_Tool_Framework_Provider_Abstract
- implements Zend_Tool_Framework_Provider_Interface,
- Zend_Tool_Registry_EnabledInterface
- {
- protected $_registry;
- public function setRegistry(
- Zend_Tool_Framework_Registry_Interface $registry
- );
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.tool.framework.architecture.loaders">
- <title>Loaders</title>
- <para>
- The purpose of a Loader is to find Providers and Manifest files that
- contain classes which implement either
- <classname>Zend_Tool_Framework_Provider_Interface</classname> or
- <classname>Zend_Tool_Framework_Manifest_Interface</classname>. Once these files are
- found by a loader, providers are loaded into the Provider Repository and
- manifest metadata is loaded into the Manifest Repository.
- </para>
- <para>
- To implement a loader, one must extend the following abstract class:
- </para>
- <programlisting language="php"><![CDATA[
- abstract class Zend_Tool_Framework_Loader_Abstract
- {
- abstract protected function _getFiles();
- public function load()
- {
- /** ... */
- }
- }
- ]]></programlisting>
- <para>
- The <methodname>_getFiles()</methodname> method should return an array of files
- (absolute paths). The built-in loader supplied with Zend Framework is called the
- IncludePath loader. By default, the Tooling framework will use an
- include_path based loader to find files that might include Providers
- or Manifest Metadata objects.
- <classname>Zend_Tool_Framework_Loader_IncludePathLoader</classname>, without
- any other options, will search for files inside the include path
- that end in <filename>Mainfest.php</filename>, <filename>Tool.php</filename> or
- <filename>Provider.php</filename>. Once found, they will be tested (by the
- <methodname>load()</methodname> method of the
- <classname>Zend_Tool_Framework_Loader_Abstract</classname>) to determine if
- they implement any of the supported interfaces. If they do, an
- instance of the found class is instantiated, and it is appended to
- the proper repository.
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_Tool_Framework_Loader_IncludePathLoader
- extends Zend_Tool_Framework_Loader_Abstract
- {
- protected $_filterDenyDirectoryPattern = '.*(/|\\\\).svn';
- protected $_filterAcceptFilePattern = '.*(?:Manifest|Provider)\.php$';
- protected function _getFiles()
- {
- /** ... */
- }
- }
- ]]></programlisting>
- <para>
- As you can see, the IncludePath loader will search all include_paths
- for the files that match the <varname>$_filterAcceptFilePattern</varname>
- and <emphasis>not</emphasis> match the <varname>$_filterDenyDirectoryPattern</varname>.
- </para>
- </sect2>
- <sect2 id="zend.tool.framework.architecture.manifests">
- <title>Manifests</title>
- <para>
- In short, the Manifest shall contain specific or arbitrary metadata
- that is useful to any provider or client, as well as be responsible
- for loading any additional providers into the provider repository.
- </para>
- <para>
- To introduce metadata into the manifest repository, all one must do
- is implement the empty <classname>Zend_Tool_Framework_Manifest_Interface</classname>,
- and provide a <methodname>getMetadata()</methodname> method which shall return an array
- of objects that implement <classname>Zend_Tool_Framework_Manifest_Metadata</classname>.
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Tool_Framework_Manifest_Interface
- {
- public function getMetadata();
- }
- ]]></programlisting>
- <para>
- Metadata objects are loaded (by a loader defined below) into the
- Manifest Repository (<classname>Zend_Tool_Framework_Manifest_Repository</classname>).
- Manifests will be processed after all Providers have been found to be
- loaded into the provider repository. This shall allow Manifests to
- create Metadata objects based on what is currently inside the
- provider repository.
- </para>
- <para>
- There are a few different metadata classes that can be used to
- describe metadata. The
- <classname>Zend_Tool_Framework_Manifest_Metadata</classname> is the base
- metadata object. As you can see by the following code
- snippet, the base metadata class is fairly lightweight and
- abstract in nature:
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_Tool_Framework_Metadata_Basic
- {
- protected $_type = 'Global';
- protected $_name = null;
- protected $_value = null;
- protected $_reference = null;
- public function getType();
- public function getName();
- public function getValue();
- public function getReference();
- /** ... */
- }
- ]]></programlisting>
- <para>
- There are other built in metadata classes as well for describing
- more specialized metadata: <classname>ActionMetadata</classname> and
- <classname>ProviderMetadata</classname>. These classes will help you describe
- in more detail metadata that is specific to either actions or
- providers, and the reference is expected to be a reference to an
- action or a provider respectively. These classes are described in
- the following code snippet.
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_Tool_Framework_Manifest_ActionMetadata
- extends Zend_Tool_Framework_Manifest_Metadata
- {
- protected $_type = 'Action';
- protected $_actionName = null;
- public function getActionName();
- /** ... */
- }
- class Zend_Tool_Framework_Manifest_ProviderMetadata
- extends Zend_Tool_Framework_Manifest_Metadata
- {
- protected $_type = 'Provider';
- protected $_providerName = null;
- protected $_actionName = null;
- protected $_specialtyName = null;
- public function getProviderName();
- public function getActionName();
- public function getSpecialtyName();
- /** ... */
- }
- ]]></programlisting>
- <para>
- 'Type' in these classes is used to describe the type of metadata the
- object is responsible for. In the cases of the
- <classname>ActionMetadata</classname>, the type would be 'Action', and
- conversely in the case of the <classname>ProviderMetadata</classname> the type
- is 'Provider'. These metadata types will also include additional
- structured information about both the "thing" they are describing as
- well as the object (the <methodname>getReference()</methodname>) they are
- referencing with this new metadata.
- </para>
- <para>
- In order to create your own metadata type, all one must do is extend
- the base <classname>Zend_Tool_Framework_Manifest_Metadata</classname> class
- and return these new metadata objects via a local Manifest
- class or object. These user based classes will live in the Manifest
- Repository
- </para>
- <para>
- Once these metadata objects are in the repository, there are then two
- different methods that can be used in order to search for them in
- the repository.
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_Tool_Framework_Manifest_Repository
- {
- /**
- * To use this method to search, $searchProperties should contain the names
- * and values of the key/value pairs you would like to match within the
- * manifest.
- *
- * For Example:
- * $manifestRepository->findMetadatas(array(
- * 'action' => 'Foo',
- * 'name' => 'cliActionName'
- * ));
- *
- * Will find any metadata objects that have a key with name 'action' value
- * of 'Foo', AND a key named 'name' value of 'cliActionName'
- *
- * Note: to either exclude or include name/value pairs that exist in the
- * search criteria but do not appear in the object, pass a bool value to
- * $includeNonExistentProperties
- */
- public function findMetadatas(Array $searchProperties = array(),
- $includeNonExistentProperties = true);
- /**
- * The following will return exactly one of the matching search criteria,
- * regardless of how many have been returned. First one in the manifest is
- * what will be returned.
- */
- public function findMetadata(Array $searchProperties = array(),
- $includeNonExistentProperties = true)
- {
- $metadatas = $this->getMetadatas($searchProperties,
- $includeNonExistentProperties);
- return array_shift($metadatas);
- }
- }
- ]]></programlisting>
- <para>
- Looking at the search methods above, the signatures allow for
- extremely flexible searching. In order to find a metadata object,
- simply pass in an array of matching constraints via an array. If
- the data is accessible through the Property accessor (the
- <methodname>getSomething()</methodname> methods implemented on the metadata
- object), then it will be passed back to the user as a "found"
- metadata object.
- </para>
- </sect2>
- <sect2 id="zend.tool.framework.architecture.clients">
- <title>Clients</title>
- <para>
- Clients are the interface which bridges a user or external tool into
- the <classname>Zend_Tool_Framework</classname> system. Clients can come in all
- shapes and sizes: <acronym>RPC</acronym> endpoints, Command Line Interface, or
- even a web interface. <classname>Zend_Tool</classname> has implemented the command
- line interface as the default interface for interacting with
- the <classname>Zend_Tool_Framework</classname> system.
- </para>
- <para>
- To implement a client, one would need to extend the following
- abstract class:
- </para>
- <programlisting language="php"><![CDATA[
- abstract class Zend_Tool_Framework_Client_Abstract
- {
- /**
- * This method should be implemented by the client implementation to
- * construct and set custom loaders, request and response objects.
- *
- * (not required, but suggested)
- */
- protected function _preInit();
- /**
- * This method should be implemented by the client implementation to parse
- * out and set up the request objects action, provider and parameter
- * information.
- */
- abstract protected function _preDispatch();
- /**
- * This method should be implemented by the client implementation to take
- * the output of the response object and return it (in an client specific
- * way) back to the Tooling Client.
- *
- * (not required, but suggested)
- */
- abstract protected function _postDispatch();
- }
- ]]></programlisting>
- <para>
- As you can see, there 1 method is required to fulfill the needs of a
- client (two others suggested), the initialization, prehandling and post handling. For a
- more in depth study of how the command line client works, please see
- the <ulink
- url="http://framework.zend.com/svn/framework/standard/branches/release-1.8/library/Zend/Tool/Framework/Client/Console.php">source
- code</ulink>.
- </para>
- </sect2>
- </sect1>
|