compared with
Current by Ralph Schindler
on Dec 22, 2008 07:24.

(show comment)
Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (46)

View Page History
Zend_Tool for the Developer
<p>Zend_Tool for the Developer</p>

<p>By now, you have probably read the <a href="http://devzone.zend.com/article/3811-Using-Zend_Tool-to-start-up-your-ZF-Project">earlier article</a> &lt;a href=&quot;http://devzone.zend.com/article/3811-Using-Zend_Tool-to-start-up-your-ZF-Project&quot;&gt;earlier article&lt;/a&gt; on getting Zend_Tool installed and working on your development machine... (or at least you should have!) And you might have casually played with it, or perhaps you are using it to create the general scaffold for your ZF MVC based projects. Either way, at some point you are bound to ask the question "how &quot;how do I extend Zend_Tool?" Zend_Tool?&quot;</p>

Background on Zend_Tool_Framework
<p>Background on Zend_Tool_Framework</p>

<p>In order to understand how to extend Zend_Tool, you need to know a few things about its overall structure. The whole of the system was built with extensibility in mind. Each of the major functional parts of the system are abstracted in such a way that its easy to not only extend, but to replace with completely separate implementations. For example, our initial interface to this system is a command line interface (cli), but its just as easy to replace the cli interface with an XML-RPC interface, or a web interface. Once replaced, the internals of the tooling system can remain the same, but you'll see that you can issue requests to the system from drastically different environments.</p>

We will strictly be dealing with the CLI client for this system in this article, but its important to know that CLI could just as easily be some other environment. To understand in greater detail how these different parts work together, you can read both the <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Tool_Framework+-+Ralph+Schindler">RPC System/internals of Zend_Tool proposal</a>, and also have a look at the <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Tool_Framework_Client_Cli+-+Ralph+Schindler">CLI Specific Implementation proposal</a>.
<p>We will strictly be dealing with the CLI client for this system in this article, but its important to know that CLI could just as easily be some other environment. To understand in greater detail how these different parts work together, you can read both the &lt;a href=&quot;http://framework.zend.com/wiki/display/ZFPROP/Zend_Tool_Framework+<span style="text-decoration: line-through;"><span style="text-decoration: underline;">Ralph+Schindler&quot;&gt;RPC System/internals of Zend_Tool proposal&lt;/a&gt;, and also have a look at the &lt;a href=&quot;http://framework.zend.com/wiki/display/ZFPROP/Zend_Tool_Framework_Client_Cli</span></span>+Ralph+Schindler&quot;&gt;CLI Specific Implementation proposal&lt;/a&gt;.</p>

<p>But for our first order of business, we'll demonstrate how to add new commands to the Zend_Tool system.</p>


Hello World!
<p>Hello World!</p>

<p>Out of the box, Zend_Tool finds all its commands on php's include_path. Finding which files might contain what Zend_Tool calls "Providers", &quot;Providers&quot;, is based off of some conventions set by the default Zend_Tool loader. When Zend_Tool starts up, the first thing it does is scan all the paths in your include_path in order to find files that match the regular expression ".*(?:Tool|Manifest|Provider)\.php". &quot;.*(?:Tool|Manifest|Provider)\.php&quot;. That essentially says any files that end in Tool.php, Manifest.php or Provider.php. Once it finds these files, it will require_once them into the runtime, and look for any classes within them that implement either the Zend_Tool_Framework_Manifest_Interface interface or the Zend_Tool_Framework_Provider_Interface interface. If they do indeed implement this interface, these classes are loaded into the tooling system and can now be called by your client.</p>

<p>To illustrate how this works, open two files in a text editor, first Zend/Tool/Framework/System/Manifest.php, then Zend/Tool/Framework/System/Provider/Version.php. First thing to note is that Zend/Tool/Framework/System/Manifest.php ends in Manifest.php and the class within it (Zend_Tool_Framework_System_Manifest) implements Zend_Tool_Framework_Manifest_Interface. Classes implementing the Zend_Tool_Framework_Manifest_Interface interface allow us to tell the tooling system which "providers" &quot;providers&quot; can be loaded and used. This method allows us to specify multiple providers without explicitly naming them XXXXProvider.php. As you can see, in the getProviders() method, you'll notice that it returns an array of two classes, one of those classes is Zend_Tool_Framework_System_Provider_Version.</p>

<p>Now, lets turn our attention to the Zend/Tool/Framework/System/Provider/Version.php file. As you can see, the class in this file implements Zend_Tool_Framework_Provider_Interface, thus it "provides" &quot;provides&quot; a set of capabilities that can be dispatched from the tooling system. In our last article, we saw the command "zf &quot;zf show version". version&quot;. Effectively, that ran the show() method from the Zend_Tool_Framework_System_Provider_Version class.</p>

<p>Without getting into the gory details, there is are a few things we want to take away from this exercise:<br />
1) Zend/Tool/Framework/System/Manifest.php is in the php include_path, so it can be found by the Zend_Tool loader.<br />
2) Zend_Tool_Framework_System_Manifest implements Zend_Tool_Framework_Manifest_Interface which allows Zend_Tool to know what providers to load.<br />
3) Zend_Tool_Framework_System_Provider_Version is in the aforementioned Manifest file AND it implements Zend_Tool_Framework_Provider_Interface, so Zend_Tool can dispatch this "provider" &quot;provider&quot;<br />
4) Zend_Tool_Framework_System_Provider_Version has a show() method which can be called from the command line "zf &quot;zf show version", version&quot;, where Version is the short name for this provider.</p>

<p>So, with that newly acquired knowledge, we should be able to create a hello world provider. Assuming your include_path is /usr/lib/php, lets create a file at this location: /usr/lib/php/My/HelloWorldProvider.php</p>

<p>Inside that file, we will put this following code:</p>

{code}
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
<?php


}
{code}
]]></ac:plain-text-body></ac:macro>

<p>Save file, and now on the command line, we should be able to issue the following command:</p>

zf say hello-world
<p>zf say hello-world</p>

<p>You SHOULD receive output that looks like this:</p>

~$ zf say hello-world
Hello World!
<p>~$ zf say hello-world<br />
Hello World!<br />
~$</p>

Thats it! So lets review what just happened here:
<p>Thats it! So lets review what just happened here:<br />
1) we created a file that ended in Provider.php (My/HelloWorldProvider.php) in our include_path.<br />
2) the class My_HelloWorldProvider implements Zend_Tool_Framework_Provider_Interface<br />
3) we saved the file, and issued the command "zf &quot;zf say hello-world" hello-world&quot;</p>

<p>At this point you might have a few questions:</p>

<p> How do I know what the provider name is?</p>

The provider name is the <b>last segment</b> name of the class with the words "Provider" or "Manifest" stripped off the end. There are ways to override this behavior, but that is a topic for a more in-depth article.
<p> The provider name is the &lt;b&gt;last segment&lt;/b&gt; name of the class with the words &quot;Provider&quot; or &quot;Manifest&quot; stripped off the end. There are ways to override this behavior, but that is a topic for a more in-depth article.</p>

<p> Why is the provider name dash-separated on the command line, but camel case in the class?</p>

<p> The idiom you use within a specific environment (or are generally used to seeing), is kept consistent with respect to the environment you are in. So for command line, dash-separated is the common format, and in OO code, CamelCase is the common format. Zend_Tool strives to keep these namings consistent with the environment they are in.</p>