|
|
@@ -10,6 +10,39 @@
|
|
|
"controller" is inside of your <acronym>MVC</acronym> application.
|
|
|
</para>
|
|
|
|
|
|
+ <sect2 id="zend.tool.framework.writing-providers.manifest">
|
|
|
+ <title>Exposing Your Providers with a Manifest</title>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ Before writing your own providers you need to create a manifest, which
|
|
|
+ returns instances of your providers to allow Zend Tool to detect
|
|
|
+ them. A Provider Manifest is an implementation of the
|
|
|
+ <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface>
|
|
|
+ and requires the <code>getProviders()</code> method to return
|
|
|
+ an array of instantiated providers. In anticipation of our first
|
|
|
+ own provider <classname>My_Component_HelloProvider</classname>
|
|
|
+ we will create the following manifest:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class My_Component_Manifest implements Zend_Tool_Framework_Manifest_ProviderManifestable
|
|
|
+{
|
|
|
+ public function getProviders()
|
|
|
+ {
|
|
|
+ return array(
|
|
|
+ new My_Component_HelloProvider()
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ A provider manifest class always has to end with the Term "Manifest" otherwise
|
|
|
+ Zend_Tool cannot autodetect it while searching through your include path.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
+
|
|
|
<sect2 id="zend.tool.framework.writing-providers.basic">
|
|
|
<title>Basic Instructions for Creating Providers</title>
|
|
|
|
|
|
@@ -48,26 +81,58 @@ Hello from my provider!
|
|
|
]]></programlisting>
|
|
|
</sect2>
|
|
|
|
|
|
- <sect2 id="zend.tool.framework.writing-providers.advanced">
|
|
|
- <title>Advanced Development Information</title>
|
|
|
+ <sect2 id="zend.tool.framework.writing-providers.response">
|
|
|
+ <title>The response object</title>
|
|
|
|
|
|
<para>
|
|
|
- The above "Hello World" example is great for simple commands, but
|
|
|
- what about something more advanced? As your scripting and tooling
|
|
|
- needs grow, you might find that you need the ability to accept
|
|
|
- variables. Much like function signatures have parameters, your
|
|
|
- tooling requests can also accept parameters.
|
|
|
+ As discussed in the architecture section Zend Tool allows to hook different clients for
|
|
|
+ using your Zend Tool providers. To keep compliant with different clients you should
|
|
|
+ use the response object to return messages from your providers instead of using <code>echo</code>
|
|
|
+ or a similiar output mechanism. Rewritting our hello provider with this knowledge it looks like:
|
|
|
</para>
|
|
|
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class My_Component_HelloProvider
|
|
|
+ extends Zend_Tool_Framework_Provider_Abstract
|
|
|
+{
|
|
|
+ public function say()
|
|
|
+ {
|
|
|
+ $this->_registry->getResponse()->appendContent("Hello from my provider!");
|
|
|
+ }
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+
|
|
|
<para>
|
|
|
- Just as each tooling request can be isolated to a method within a
|
|
|
- class, the parameters of a tooling request can also be isolated in a
|
|
|
- very well known place. Parameters of the action methods of a
|
|
|
- provider can include the same parameters you want your client to
|
|
|
- utilize when calling that provider and action combination. For
|
|
|
- example, if you wanted to accept a name in the above example, you
|
|
|
- would probably do this in OO code:
|
|
|
+ As you can see one has to extend the <classname>Zend_Tool_Framework_Provider_Abstract</classname>
|
|
|
+ to gain access to the Registry which holds the <classname>Zend_Tool_Framework_Client_Response</classname>
|
|
|
+ instance.
|
|
|
</para>
|
|
|
+ </sect2>
|
|
|
+
|
|
|
+ <sect2 id="zend.tool.framework.writing-providers.advanced">
|
|
|
+ <title>Advanced Development Information</title>
|
|
|
+
|
|
|
+ <sect3 id="zend.tool.framework.writing-providers.advanced.variables">
|
|
|
+ <title>Passing Variables to a Provider</title>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ The above "Hello World" example is great for simple commands, but
|
|
|
+ what about something more advanced? As your scripting and tooling
|
|
|
+ needs grow, you might find that you need the ability to accept
|
|
|
+ variables. Much like function signatures have parameters, your
|
|
|
+ tooling requests can also accept parameters.
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ Just as each tooling request can be isolated to a method within a
|
|
|
+ class, the parameters of a tooling request can also be isolated in a
|
|
|
+ very well known place. Parameters of the action methods of a
|
|
|
+ provider can include the same parameters you want your client to
|
|
|
+ utilize when calling that provider and action combination. For
|
|
|
+ example, if you wanted to accept a name in the above example, you
|
|
|
+ would probably do this in OO code:
|
|
|
+ </para>
|
|
|
|
|
|
<programlisting language="php"><![CDATA[
|
|
|
class My_Component_HelloProvider
|
|
|
@@ -80,35 +145,40 @@ class My_Component_HelloProvider
|
|
|
}
|
|
|
]]></programlisting>
|
|
|
|
|
|
- <para>
|
|
|
- The above example can then be called via the command line
|
|
|
- <command>zf say hello Joe</command>. "Joe" will be supplied to the provider as
|
|
|
- a parameter of the method call. Also note, as you see that the
|
|
|
- parameter is optional, that means it is also optional on the command
|
|
|
- line, so that <command>zf say hello</command> will still work, and default
|
|
|
- to the name "Ralph".
|
|
|
- </para>
|
|
|
+ <para>
|
|
|
+ The above example can then be called via the command line
|
|
|
+ <command>zf say hello Joe</command>. "Joe" will be supplied to the provider as
|
|
|
+ a parameter of the method call. Also note, as you see that the
|
|
|
+ parameter is optional, that means it is also optional on the command
|
|
|
+ line, so that <command>zf say hello</command> will still work, and default
|
|
|
+ to the name "Ralph".
|
|
|
+ </para>
|
|
|
|
|
|
- <para>
|
|
|
- Another interesting feature you might wish to implement is
|
|
|
- <emphasis>pretendability</emphasis>. Pretendabilty is the ability
|
|
|
- for your provider to "pretend" as if it is doing the requested
|
|
|
- action and provider combination and give the user as much
|
|
|
- information about what it <emphasis>would</emphasis> do without
|
|
|
- actually doing it. This might be an important notion when doing
|
|
|
- heavy database or filesystem modifications that the user might not
|
|
|
- otherwise want to do.
|
|
|
- </para>
|
|
|
+ </sect3>
|
|
|
|
|
|
- <para>
|
|
|
- Pretendability is easy to implement. There are two parts to this
|
|
|
- feature: 1) marking the provider as having the ability to "pretend",
|
|
|
- and 2) checking the request to ensure the current request was indeed
|
|
|
- asked to be "pretended". This feature is demonstrated in the code
|
|
|
- sample below.
|
|
|
- </para>
|
|
|
+ <sect3 id="zend.tool.framework.writing-providers.advanced.pretendable">
|
|
|
+ <title>Pretending to execute a Provider Action</title>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <para>
|
|
|
+ Another interesting feature you might wish to implement is
|
|
|
+ <emphasis>pretendability</emphasis>. Pretendabilty is the ability
|
|
|
+ for your provider to "pretend" as if it is doing the requested
|
|
|
+ action and provider combination and give the user as much
|
|
|
+ information about what it <emphasis>would</emphasis> do without
|
|
|
+ actually doing it. This might be an important notion when doing
|
|
|
+ heavy database or filesystem modifications that the user might not
|
|
|
+ otherwise want to do.
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ Pretendability is easy to implement. There are two parts to this
|
|
|
+ feature: 1) marking the provider as having the ability to "pretend",
|
|
|
+ and 2) checking the request to ensure the current request was indeed
|
|
|
+ asked to be "pretended". This feature is demonstrated in the code
|
|
|
+ sample below.
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
class My_Component_HelloProvider
|
|
|
extends Zend_Tool_Framework_Provider_Abstract
|
|
|
implements Zend_Tool_Framework_Provider_Pretendable
|
|
|
@@ -123,5 +193,126 @@ class My_Component_HelloProvider
|
|
|
}
|
|
|
}
|
|
|
]]></programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ To run the provider in pretend mode just call:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="sh"><![CDATA[
|
|
|
+% zf --pretend say hello Ralph
|
|
|
+I would say hello Ralph.
|
|
|
+]]></programlisting>
|
|
|
+
|
|
|
+ </sect3>
|
|
|
+
|
|
|
+ <sect3 id="zend.tool.framework.writing-providers.advanced.verbosedebug">
|
|
|
+ <title>Verbose and Debug modes</title>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ You can also run your provider actions in "verbose" or "debug" modes.
|
|
|
+ The semantics in regard to this actions have to be implemented by you
|
|
|
+ in the context of your provider. You can access debug or verbose modes
|
|
|
+ with:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class My_Component_HelloProvider
|
|
|
+ implements Zend_Tool_Framework_Provider_Interface
|
|
|
+{
|
|
|
+ public function say($name = 'Ralph')
|
|
|
+ {
|
|
|
+ if($this->_registry->getRequest()->isVerbose()) {
|
|
|
+ echo "Hello::say has been called\n";
|
|
|
+ }
|
|
|
+ if($this->_registry->getRequest()->isDebug()) {
|
|
|
+ syslog(LOG_INFO, "Hello::say has been called\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+ </sect3>
|
|
|
+
|
|
|
+ <sect3 id="zend.tool.framework.writing-providers.advanced.configstorage">
|
|
|
+ <title>Accessing User Config and Storage</title>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ Using the Enviroment variable <property>ZF_CONFIG_FILE</property> or the
|
|
|
+ .zf.ini in your home directory you can inject configuration parameters into
|
|
|
+ any Zend Tool provider. Access to this configuration is available via the
|
|
|
+ registry that is passed to your provider if you extend
|
|
|
+ <classname>Zend_Tool_Framework_Provider_Abstract</classname>.
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class My_Component_HelloProvider
|
|
|
+ extends Zend_Tool_Framework_Provider_Abstract
|
|
|
+{
|
|
|
+ public function say()
|
|
|
+ {
|
|
|
+ $username = $this->_registry->getConfig()->username;
|
|
|
+ if(!empty($username)) {
|
|
|
+ echo "Hello $username!";
|
|
|
+ } else {
|
|
|
+ echo "Hello!";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ The returned configuration is of the type <classname>Zend_Tool_Framework_Client_Config</classname>
|
|
|
+ but internally the <code>__get</code> and <code>__set</code> magic methods proxy to a
|
|
|
+ <classname>Zend_Config</classname> of the given configuration type.
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ The storage allows to save arbitrary data for later reference. This can be useful for batch
|
|
|
+ processing tasks or for re-runs of your tasks. You can access the storage in a similar way
|
|
|
+ like the configuration:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class My_Component_HelloProvider
|
|
|
+ extends Zend_Tool_Framework_Provider_Abstract
|
|
|
+{
|
|
|
+ public function say()
|
|
|
+ {
|
|
|
+ $aValue = $this->_registry->getStorage()->get("myUsername");
|
|
|
+ echo "Hello $aValue!";
|
|
|
+ }
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
+ The API of the storage is very simple:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
+class Zend_Tool_Framework_Client_Storage
|
|
|
+{
|
|
|
+ public function setAdapter($adapter);
|
|
|
+ public function isEnabled();
|
|
|
+ public function put($name, $value);
|
|
|
+ public function get($name, $defaultValue=null);
|
|
|
+ public function has($name);
|
|
|
+ public function remove($name);
|
|
|
+ public function getStreamUri($name);
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </programlisting>
|
|
|
+
|
|
|
+ <important>
|
|
|
+ <para>
|
|
|
+ When designing your providers that are config or storage aware remember to
|
|
|
+ check if the required user-config or storage keys really exist for a user.
|
|
|
+ You won't run into fatal errors when none of these are provided though,
|
|
|
+ since empty ones are created upon request.
|
|
|
+ </para>
|
|
|
+ </important>
|
|
|
+ </sect3>
|
|
|
+
|
|
|
</sect2>
|
|
|
</sect1>
|