<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Evilprofessor.co.uk &#187; framework</title>
	<atom:link href="http://www.evilprofessor.co.uk/tag/framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.evilprofessor.co.uk</link>
	<description>The website of Steven Lloyd Watkin</description>
	<lastBuildDate>Thu, 04 Aug 2011 09:56:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>&#8220;Sign in with Twitter&#8221; using Zend Framework</title>
		<link>http://www.evilprofessor.co.uk/359-sign-in-with-twitter-using-zend-framework/</link>
		<comments>http://www.evilprofessor.co.uk/359-sign-in-with-twitter-using-zend-framework/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 01:07:26 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Oauth]]></category>
		<category><![CDATA[Zend_Oauth_Consumer]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[Sign in with twitter]]></category>
		<category><![CDATA[token]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=359</guid>
		<description><![CDATA[Despite all the twitter hate at the moment, I&#8217;ve set out to create a new twitter-based application. Being someone who manages several accounts (both personal and for my charity work) I&#8217;ve been needing a tool for sometime that I&#8217;m just getting around to writing (more of that in the near future&#8230;). I&#8217;ve read up on [...]]]></description>
			<content:encoded><![CDATA[<p>Despite all the <a title="Twitter hate" href="http://storify.com/abraham/consistency-and-ecosystem-opportunities-links" target="_blank">twitter hate</a> at the moment, I&#8217;ve set out to create a new <a href="http://www.twitter.com" class="kblinker" target="_blank" title="More about twitter &raquo;">twitter</a>-based application. Being someone who manages several accounts (both personal and for my charity work) I&#8217;ve been needing a tool for sometime that I&#8217;m just getting around to writing (more of that in the near future&#8230;).</p>
<p>I&#8217;ve read up on <a href="http://framework.zend.com/manual/en/zend.oauth.introduction.html" class="kblinker" target="_blank" title="More about Zend_Oauth_Consumer &raquo;">Zend_Oauth_Consumer</a> and how it can be used to get authorisation for interacting with twitter using <a href="http://oauth.net/" class="kblinker" target="_blank" title="More about oauth &raquo;">oauth</a>. All well and good, I have my access key and I can merrily post away on a user&#8217;s behalf. There&#8217;s plenty of resources out there to do this so I won&#8217;t bore people.</p>
<p>The next step was to allow people to return to the website, log in and modify their account. This is where I reached a slight problem. Using the code examples on websites meant that I&#8217;d have twitter asking me for access authorisation again for each login, not good. Scanning through the framework I couldn&#8217;t see anything which would allow me to just request authentication. That isn&#8217;t to say its not there, but there didn&#8217;t seem to be an authentication mechanism that could be invoked without knowing the access token already.</p>
<p>The alternatives were to implement a site-based log in or somehow store the user&#8217;s access token on the client (encrypted of course). Neither of these seemed like a good/suitable solution.</p>
<p><span id="more-359"></span></p>
<p>Having a look at the requests made by my code I knew that all that was required was to change the URL to which Zend_Oauth_Consumer redirects. It seemed the easiest way to do this was to override the authorizationUrl parameter with the authentication URL from twitter. This was done as follows:</p>
<pre name="code" class="php">
$config = array(
'callbackUrl'    =&gt; ...callback-url...,
'siteUrl'        =&gt; 'https://twitter.com/oauth',
'consumerKey'    =&gt; ...consumer-key...,
'consumerSecret' =&gt; ...secret-key...,
);
$consumer = new Zend_Oauth_Consumer($config);

$token = $consumer-&gt;getRequestToken();
// persist the token to storage
$_SESSION['TWITTER_REQUEST_TOKEN'] = serialize($token);
$consumer-&gt;setAuthorizeUrl('https://twitter.com/oauth/authenticate');
$consumer-&gt;redirect();
</pre>
<p>On return to the application from twitter we process the response as so:</p>
<pre name="code" class="php">
$token = $consumer-&gt;getAccessToken(
$_GET,
unserialize($_SESSION['TWITTER_REQUEST_TOKEN'])
);

echo $token-&gt;user_id . ' :: ' . $token-&gt;screen_name;
</pre>
<p>How you validate/store the authentication is up to you, but this should successfully implement a &#8216;sign in with twitter&#8217; system.</p>
<blockquote><p>If anyone knows of a more correct/more elegant solution to this I would be very much interested in hearing. There seems to be a lack of information on &#8216;sign in with twitter&#8217; using <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a>/<a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> on the internet</p>
</blockquote>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F359-sign-in-with-twitter-using-zend-framework%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/359-sign-in-with-twitter-using-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Render If Exists</title>
		<link>http://www.evilprofessor.co.uk/349-zend-framework-render-if-exists/</link>
		<comments>http://www.evilprofessor.co.uk/349-zend-framework-render-if-exists/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 16:19:58 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_View]]></category>
		<category><![CDATA[Zend_View_Helper]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[render]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[view helper]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend_view]]></category>
		<category><![CDATA[Zend_View_Helper_Abstract]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=349</guid>
		<description><![CDATA[Summary This is a quick post to discuss the rather simple view helper I created for rendering a Zend Framework style view file only if it exists. Generally asking the code to render a file which doesn&#8217;t exist will throw an exception. Therefore I created a wrapper for the Zend_View::render() method which determined whether the [...]]]></description>
			<content:encoded><![CDATA[<h2>Summary</h2>
<p>This is a quick post to discuss the rather simple view helper I created for rendering a <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> style view file only if it exists. Generally asking the code to render a file which doesn&#8217;t exist will throw an exception. Therefore I created a wrapper for the Zend_View::render() method which determined whether the file exists and if so renders, otherwise simply returns an empty string.<br />
<span id="more-349"></span><br />
<div class="wp-caption alignright" style="width: 250px"><img title="Wood" src="http://farm5.static.flickr.com/4114/4829390369_ed85ecc900_m.jpg" alt="" width="240" height="160" /><p class="wp-caption-text">Joost J. Bakker IJmuiden - http://www.flickr.com/photos/joost-ijmuiden/</p></div></p>
<h2>Motivation</h2>
<p>The motivation for this is that I have one controller/view/etc which shows slightly different output depending on a parameter. Some of these outputs have a related help information box defined, some do not. I didn&#8217;t want to have empty files hanging around my code just as much as I didn&#8217;t want to have try {} catch {} blocks in my view file. Therefore, I quickly created a &#8216;render if exists&#8217; view helper for use in my code.</p>
<p>I realise that here I could have just wrapped the render method within a try{}catch{} within the view helper itself. In this case however any exceptions thrown from the rendered view would not bubble back up in the case of something going wrong.</p>
<h2>How It Works</h2>
<p>The view helper is created by extending Zend_View_Helper_Abstract as normally, this injected with the view upon use. The view helper is passed the view file you wish to render:</p>
<pre class="php" name="code">$this-&gt;renderIfExists('info-box.phtml');</pre>
<p>Internally the object gathers the script paths from the view object and loops over them trying to find the file:</p>
<pre class="php" name="code">
    /**
     * Check to see if a <a href="http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/" class="kblinker" title="More about view script &raquo;">view script</a> exists
     *
     * @return boolean
     */
    protected function _fileExists()
    {
        $paths = $this-&gt;view-&gt;getScriptPaths();
        foreach ($paths as $path) {
            if (file_exists($path . $this-&gt;_file)) {
                return true;
            }
        }
        return false;
    }</pre>
<p>If a matching file is found it uses the standard Zend_View::render() method, otherwise it returns an empty string.</p>
<h2>Summary</h2>
<p>This is a very simple view helper to render a view file if it exists and simply return an empty string if not. It does not use a try{} catch{} block which would prevent any deeper exceptions being thrown from bubbling up and making themselves known. Instead it loops through the script paths defined within the view object and attempts to detect the file before trying to render it.</p>
<p>The full file can be found at my <a title="RenderIfExists View Helper @ GitHub" href="https://github.com/lloydwatkin/Demos/blob/master/zendframework/renderifexists/RenderIfExists.php" target="_blank">github repo</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F349-zend-framework-render-if-exists%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/349-zend-framework-render-if-exists/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Zend Framework Body Tag View Helper</title>
		<link>http://www.evilprofessor.co.uk/311-zend-framework-body-tag-view-helper/</link>
		<comments>http://www.evilprofessor.co.uk/311-zend-framework-body-tag-view-helper/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 23:13:28 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Registry]]></category>
		<category><![CDATA[Zend_View_Helper]]></category>
		<category><![CDATA[Body]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[view helper]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[Zend_View_Helper_Placeholder_Container_Standalone]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=311</guid>
		<description><![CDATA[Summary Here I discuss the creation of a view helper for modifying HTML tags, and more specifically body tags. The created view helper allows functionality similar to the head*/inlineScript view helpers already in the standard Zend Framework view helpers, but allows the programmatic modification of tag attributes. Definitely check out the demo page and the [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_320" class="wp-caption alignright" style="width: 222px"><a href="http://www.evilprofessor.co.uk/wp-content/uploads/2010/08/422213306_02bcf3f7d2_m.jpg"><img class="size-full wp-image-320 " title="Photo from  http://www.flickr.com/photos/daniello/" src="http://www.evilprofessor.co.uk/wp-content/uploads/2010/08/422213306_02bcf3f7d2_m.jpg" alt="Photo from  http://www.flickr.com/photos/daniello/" width="212" height="300" /></a><p class="wp-caption-text">Photo from http://www.flickr.com/photos/daniello/</p></div>
<h2>Summary</h2>
<p>Here I discuss the creation of a view helper for modifying HTML tags, and more specifically <a href="http://www.evilprofessor.co.uk/311-zend-framework-body-tag-view-helper/" class="kblinker" title="More about body tag &raquo;">body tags</a>. The created view helper allows functionality similar to the head*/inlineScript view helpers already in the standard <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> view helpers, but allows the programmatic modification of tag attributes. Definitely check out the demo page and the code on github.</p>
<h2>Motivation</h2>
<p>The standard Zend Framework view helpers are a great set of tools for streamlining mundane view tasks and allowing for the modification/addition of scripts and header blocks (generally held in the layout) from within the view without applying ugly hacks (i.e. the head*/inlineScript view helpers).</p>
<p>Upon occasion I have found need to make modifications to the &lt;body&gt; tag, for example adding an <em><a title="body onload attribute" href="http://www.w3schools.com/jsref/event_body_onload.asp" target="_blank">onload</a>, class, </em>or <em>style </em>attribute etc. I also required to be able to perform this from within other view helpers. Take this following contrived example&#8230;</p>
<blockquote><p>On website X, certain pages include standard <a href="http://www.dojotoolkit.org/" class="kblinker" target="_blank" title="More about Dojo &raquo;">dojo</a> forms. These dojo forms are held within view helpers for convenience. Generally it has been decided not to include the dojo <a href="http://www.w3schools.com/css/css_intro.asp" class="kblinker" target="_blank" title="More about CSS &raquo;">CSS</a> classes in the body tag and only add them when necessary. There maybe several view helpers on the page that need to add their own attributes to the body tag.<em> (I said it was contrived)</em></p></blockquote>
<p>The code is available in my GIT repository @ <a title="Body tag view helper @ github" href="http://github.com/lloydwatkin/Demos/tree/master/zendframework/abstracttag/" target="_blank">github</a> and the <a title="Body Tag View Helper Demo" href="http://www.evilprofessor.co.uk/uploads/php/zendframework/abstracttag/demo.php" target="_blank">demo page</a>.<br />
<span id="more-311"></span></p>
<h2>How it works</h2>
<p>When creating the body tag view helper I soon realised that most of the code was not specific to what I was developing so I pulled out the common functionality into an abstract class.  By concreting the  abstract class it is possible to modify any tag in the same way as the body tag discussed here making the code much more versitile.</p>
<p>Underneath the hood (so to speak) the code is based on that of the head* and the inlineScript view helpers. It utilises Zend_View_Helper_Placeholder_Container_Standalone to store the attributes and their values until they are required. The container itself uses <a href="http://framework.zend.com/manual/en/zend.registry.html" class="kblinker" target="_blank" title="More about Zend_Registry &raquo;">Zend_Registry</a> to store values under the key defined in the class (if you look at the <a href="http://www.phpunit.de/" class="kblinker" target="_blank" title="More about unit test &raquo;">unit tests</a> I clear the registry down after each test).</p>
<p>The code would fit in well with the &#8220;<a href="http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/" class="kblinker" title="More about Naked Zend_Layout and Zend_View &raquo;">Naked Zend_Layout and Zend_View</a>&#8221; code I wrote about a couple of weeks ago or as part of the standard Zend Framework <a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller" class="kblinker" target="_blank" title="More about MVC &raquo;">MVC</a> install.</p>
<p><strong>Usage</strong></p>
<p>The class should be very simple to use. Firstly two entries are required within your layout script as follows:</p>
<pre class="php" name="code" type="code">&lt;?php echo $this-&gt;bodyTag() ?&gt;
&lt;?php echo $this-&gt;bodyTag()-&gt;toString(Pro_View_Helper_AbstractTag::CLOSE) ?&gt;</pre>
<p>Note: You&#8217;ll need to change the class name should you move the view helper to your own library. Obviously the constant is available through the implementation (bodyTag) as well as through the abstract class.</p>
<p>An example of making changes to your body tag using the view helper to echo &lt;body class=&#8221;nihilo myclass&#8221; style=&#8221;text-align-left; width: 80em&#8221;&gt; is:</p>
<pre class="php" name="code" type="code">&lt;?php
$this-&gt;bodyTag('class', 'nihilo')
    -&gt;bodyTag('style', 'text-align: left')
    -&gt;bodyTag('style', 'width: 80em', false, ';')
    -&gt;bodyTag('class', 'myclass')
?&gt;</pre>
<p>This can be done throughout the view file, in several view helpers, and in the layout file (provided its before the body tag is written out). Attributes can be removed/overwritten whilst values can be added and appended (separator can be passed). If the same attribute value is passed several times only a single copy is written with the attribute.</p>
<p>For a full demo either fork the github repository and run the demo.php file in your own browser, or alternatively visit <a title="Body tag view helper demo" href="http://www.evilprofessor.co.uk/uploads/php/zendframework/abstracttag/demo.php" target="_blank">this page</a> to see it in action. Usage of the <a href="http://github.com/lloydwatkin/Demos/blob/master/zendframework/abstracttag/demo.php" target="_blank">demo.php</a> script assumes you have the Zend Autoloader (or similar) already setup.</p>
<h2>Creating your own Tag helper</h2>
<p>To implement your own view helper simply extend the abstract tag class and overwrite the following class properties:</p>
<ul>
<li><em>$_regKey</em>: A unique key for the tag (used for Zend_Registry)</li>
<li><em>$_validAttributes</em>: An array of valid attribute names, should be lowercase to comply with <a href="http://www.w3.org/" class="kblinker" target="_blank" title="More about w3c &raquo;">W3C</a></li>
<li><em>$_selfClosing</em>: Boolean value to specify if tag is self closing or not, e.g. <strong>&lt;br/&gt;</strong></li>
<li><em>$_tagName</em>: Name of the tag (i.e. <strong>body</strong> in this example)</li>
</ul>
<p>So, finally the code for the bodyTag view helper itself, its very compact:</p>
<pre class="php" name="code" type="code">/**
 * View helper for the body tag
 *
 * @author     Lloyd Watkin
 * @since      21/08/2010
 * @package    Pro
 * @subpackage ViewHelper
 */
class Pro_View_Helper_BodyTag
    extends Pro_View_Helper_AbstractTag
{
    /**
     * Registry key for placeholder
     *
     * @var string
     */
    protected $_regKey = 'Pro_View_Helper_BodyTag';

    /**
     * Which attributes are valid
     *
     * Currently only STF attributes supported
     * (S = STRICT, T = TRANSITIONAL, F = FRAMESET)
     *
     * @see http://www.w3schools.com/tags/tag_body.asp
     * @var array
     */
    protected $_validAttributes = array(
        /* Standard Attributes */
        'class', 'dir', 'id', 'lang', 'style', 'title', '<a href="http://en.wikipedia.org/wiki/XML" class="kblinker" target="_blank" title="More about XML &raquo;">xml</a>:lang',
        /* Event Attributes */
        'onclick', 'ondblclick', 'onload', 'onmousedown', 'onmousemove',
        'onmouseout', 'onmouseover', 'onmouseup', 'onkeydown', 'onkeypress',
        'onkeyup', 'onunload',
    );

    /**
     * Self closing tag?
     *
     * @var boolean
     */
    protected $_selfClosing = false;    

    /**
     * Tag name
     *
     * @var string
     */
    protected $_tagName = 'body';
}</pre>
<p>If you take a look at the repository there&#8217;s also a group of unit tests that fully cover the functionality. The unit tests are written in <a href="http://www.phpunit.de/" class="kblinker" target="_blank" title="More about phpunit &raquo;">PHPUnit</a> and are in the <a href="http://github.com/lloydwatkin/Demos/blob/master/zendframework/abstracttag/BodyTagTest.php" target="_blank">BodyTagTest.php</a> file.</p>
<h2>Finally&#8230;</h2>
<p>Here I&#8217;ve shown you my implementation of an abstract tag abstract view helper (eek) and its body tag implementation. Whilst the javaScript functionality can be implemented in other ways (other than hard coding at output time) other things can&#8217;t (without javaScript that is) without changing other parts of the application. I hope you find the classes helpful in your application&#8230;</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F311-zend-framework-body-tag-view-helper%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/311-zend-framework-body-tag-view-helper/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quick Start Symfony DI (Dependency Injection) Tutorial</title>
		<link>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/</link>
		<comments>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 14:21:35 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Dependency Injection Container]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Cache]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[inversion of control]]></category>
		<category><![CDATA[IOC]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[yaml]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=264</guid>
		<description><![CDATA[What is Dependency Injection (DI)? Dependency injection is a technique that allows for loosely coupled objects within a software application. Generally if an object requires access to the functionality of another it would be instantiated internally leading to tightly coupled systems. By implementing dependency injection we inject the required objects ready for use (sometimes also [...]]]></description>
			<content:encoded><![CDATA[<h2>What is <a href="http://en.wikipedia.org/wiki/Dependency_injection" class="kblinker" target="_blank" title="More about Dependency Injection &raquo;">Dependency Injection</a> (DI)?</h2>
<p>Dependency injection is a technique that allows for loosely coupled objects within a software application. Generally if an object requires access to the functionality of another it would be instantiated internally leading to tightly coupled systems. By implementing dependency injection we inject the required objects ready for use (sometimes also referred to inversion of control &#8211; IOC). Take the following example:</p>
<pre class="php" type="code" name="code">&lt;?php
class DecisionMaker {
    public function makeDecision(array $parameters) {
        // Need the database adapter
        $dp = new DecisionParameters();
        $parameterScore = $dp-&gt;getScore($parameters);
        /* ... Some more decision logic ... */
        return ($parameterScore &gt; 50);
    }
}</pre>
<p>This piece of code is said to be tightly coupled to the <em>DecisionParameters</em> object. Rewriting the above in a loosely coupled fashion we&#8217;d have something like&#8230;.</p>
<pre class="php" type="code" name="code">&lt;?php
class DecisionMaker {
    private $_dp;
    public function __construct($dp) {
        $this-&gt;_dp = $dp;
    }
    public function makeDecision(array $parameters) {
        $parameterScore = $this-&gt;_dp-&gt;getScore($parameters);
        /* ... Some more decision logic ... */
        return ($parameterScore &gt; 50);
    }
}</pre>
<p>Whilst gaining the benefits of loosely coupled code we are adding complexity such that each time an object is instantiated we also have to instantiate its dependencies and pass these in too. For example, this:</p>
<pre class="php" type="code" name="code">$choice = new DecisionMaker();
echo $choice-&gt;makeDecision(array('effort' =&gt; 'low', 'return' =&gt; 'high'));</pre>
<p>now becomes:</p>
<pre class="php" type="code" name="code">$dp = new DecisionParameters();
$choice = new DecisionMaker($dp);
echo $choice-&gt;makeDecision(array('effort' =&gt; 'low', 'return' =&gt; 'high'));</pre>
<p>This situation becomes more painful as the number of dependencies for a class is increased, and what if the dependencies themselves have dependencies? This can quite quickly become an object administration nightmare! Enter dependency injection containers (or frameworks)&#8230;<br />
<span id="more-264"></span></p>
<h2>Dependency Injection Containers/Frameworks</h2>
<p>Dependency injection containers (or frameworks) handle the process of object creation; instantiating and injecting any dependencies before returning an instance to the caller.</p>
<p>In your code rather than create new objects directly we request a copy of the object from the DI container. The object we are returned already has  all its dependencies injected and the object is ready to go.</p>
<h3><a href="http://www.symfony-project.org/" class="kblinker" target="_blank" title="More about Symfony &raquo;">Symfony</a> Dependency Injection Container</h3>
<p>Symfony is probably best known for their full stack <a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller" class="kblinker" target="_blank" title="More about MVC &raquo;">MVC</a> framework however they have also released a number of the components that can be used independently. For example, the dependency injection container we&#8217;re going to talk about here, a <a href="http://www.yaml.org/" class="kblinker" target="_blank" title="More about yaml &raquo;">YAML</a> parser, a templating engine, see <a href="http://components.symfony-project.org/" class="kblinker" target="_blank" title="More about symfony components &raquo;">Symfony components</a> for more.</p>
<p>The Symfony DI container is based on that from the <a href="http://en.wikipedia.org/wiki/Spring_Framework" class="kblinker" target="_blank" title="More about spring framework &raquo;">Spring Framework</a> in <a href="http://www.java.com/en/" class="kblinker" target="_blank" title="More about java &raquo;">Java</a>.</p>
<h2>Bootstrapping</h2>
<p>In order to bootstrap the Symfony dependency injection framework we use code as included below. I have chosen to use YAML just because its easy to read and setup. For maximum speed you may want to write out your containers to plain <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a> (the Symfony container can do this for you once setup), or alternatively cache the whole container using <a href="http://framework.zend.com/manual/en/zend.cache.html" class="kblinker" target="_blank" title="More about Zend_Cache &raquo;">Zend_Cache</a>, or similar.</p>
<p>To install Symfony DI follow the instructions included here <a href="http://components.symfony-project.org/dependency-injection/installation">http://components.symfony-project.org/dependency-injection/installation</a>, and add it to your path.</p>
<pre class="php" type="code" name="code">// Load the Symfony DI container
require 'sfServiceContainerBuilder.php';
$container = new sfServiceContainerBuilder();
$loader = new sfServiceContainerLoaderFileYaml($container);
$loader-&gt;load(APPLICATION_PATH . '/config/di/services.yml');</pre>
<p>Firstly we instantiate a new container, and then we load our configuration from a YAML file. Note: the DI container can load config from several formats such as <a href="http://en.wikipedia.org/wiki/XML" class="kblinker" target="_blank" title="More about XML &raquo;">XML</a>, YAML, PHP, and INI*.  I tend to include a single YAML file and import other files from within there.</p>
<p>Several configuration files can be imported using different formats, the newer definitions overwriting those that have already been defined. Configuration files can include references to objects and parameters.</p>
<p><em>*INI is only able to define parameters and is unable to import other files</em></p>
<h2>Configuration Example</h2>
<pre>imports:
  - { resource: daos.yml }

parameters:
  username: false

services:
  # Customer model
  model.customer:
    class:  Pro_Customer
    calls:
      - [ setLogger, [ @utils.logger ] ]
      - [ setDao, [ @data.userdata.mysql ] ]
      - [ setUserName, [ %username% ] ]

  # Product model
  model.product:
    class:  Pro_Product
    arguments: [%username%, { type: %accesslevel%, lastlogin: %lastlogin% } ]
    calls:
     - [ setDao, [ @data.product.mysql ] ]

  # Logger
  utils.logger:
    class: Pro_Logger
    constructor: getInstance
    calls:
      - [ setHandle, [ @utils.filewriter ] ]</pre>
<p>I think the code above is fairly self explanatory but for clarity I&#8217;ll explain each part now.</p>
<p>First off we define some imports (i.e. other files to parse), I like to group my configurations for example DAOs in one file, utilities in another and name the file appropriately. Whilst a little slower it speeds up the maintenance of the configuration files. Its also possible to parse files of other formats using different import flags. Files are parsed in order with newer definitions overwriting or amending previously defined services/parameters.</p>
<p>Next we define a parameter, a parameter can generally be any PHP variable type. At this point I didn&#8217;t  know what my username parameter should be (I need to authenticate for that!), so I&#8217;ve defined a default value and I&#8217;ll overwrite that value later. Note, classes aren&#8217;t instantiated until you ask for them so defining parameters a little later is perfectly fine. Following this I define some services:</p>
<ol>
<li>Instantiate Pro_Customer, pass an instance of my logger to the setLogger() method, add in my <a href="http://www.mysql.com/?bydis_dis_index=1" class="kblinker" target="_blank" title="More about mysql &raquo;">MySQL</a> <a href="http://en.wikipedia.org/wiki/Data_access_object" class="kblinker" target="_blank" title="More about data access object &raquo;">data access object</a> (DAO), and pass in the username as well. Each time I ask for this object I want a new instance</li>
<li>Create an instance of Pro_Product, pass arguments of username and an options array to the constructor. After instantiation call setDao() and pass it my product DAO</li>
<li>Give me a copy of Pro_Logger, instantiate it using the getInstance() method and pass a copy of my file writer object via setHandle() once its loaded. My file writer is defined in one of my imports.</li>
</ol>
<p>Within the configuration files <em>services</em> are referenced by prepending the name with an &#8216;@&#8217; symbol, <em>parameters</em> are referenced by prepending and appending with &#8216;%&#8217; symbols, e.g. <em>@utils.logger %username%</em>.</p>
<h2>Adding data post loading</h2>
<p>Sometimes you don&#8217;t know what the value of parameters should be until after you have bootstrapped, as with our <em>username</em> parameter above. In order to overwrite the value the <em>offsetSet()</em> method is used, firstly passing the parameter name followed by its new value:</p>
<pre class="php" type="code" name="code">$container-&gt;offsetSet('username', $username);</pre>
<h2>Getting Objects from the container</h2>
<p>Once setup rather than instantiating objects directly we now go to the DI container to get instances. With the Symfony DI we call the <em>getService() </em>method, passing in a string which describes the variable you wish to retrieve, e.g.</p>
<pre class="php" type="code" name="code">$logger = $container-&gt;getService('utils.logger');</pre>
<p>This will perform the equivalent of:</p>
<pre class="php" type="code" name="code">$logger = Pro_Logger::getInstance();
$fileWriter = new Pro_Writer_FileWriter();
$logger-&gt;setHandler($fileWriter);</pre>
<p>It is possible to determine if the container has an instance of a service by calling the <em>hasService()</em> method, which returns a boolean value.</p>
<p>Its not necessary to have access to the container beyond the top level of your application since once retrieving an instance all of the required dependencies right down to the deepest depths of your application are already setup and waiting to be called.</p>
<h2>Unit Testing</h2>
<p>Dependency injection also has the added benefit of allowing objects to be tested in isolation. Taking the <em>DecisionMaker</em> class example before implementing the dependency injection setup our test results were also dependent on the implementation of the <em>DecisionParameters</em> class.</p>
<p>Should the <em>DecisionParameters</em> class return different results our tests could start failing through no fault of our own. Using dependency injection we can now pass in a <em>DecisionParameters</em> object which returns a known/fixed set of results for certain input parameters, we are now testing <em>DecisionMaker</em> in isolation from any external factors, i.e. if our tests start failing this can be directly attributed to something changing in the <em>DecisionMakeer</em> class. This is particularly important should you be relying on test data from a database for testing.</p>
<h2>Application Configuration</h2>
<p>The way in which your application behaves on your production server will inevitably differ from your development setup. For example, in a development environment the level of logging would be much more granular than on your production system. By altering your dependency injection container configuration files slightly (or parsing an additional configuration file) the altering of behaviour depending on the environment is made simple.</p>
<p>By type hinting on interfaces rather than implementations when setting your dependencies its also possible to swap out components for compatible components with a few lines of YAML or XML. For instance, you may currently access your database via a MySQL DAO (Data Access Object), but in time you may develop a PDO, Zend_Db, or <a href="http://www.doctrine-project.org/" class="kblinker" target="_blank" title="More about Doctrine &raquo;">Doctrine</a> implementation of this DAO. By adding the new implementation into your configuration file suddenly all the objects that used the old MySQL implementation are now using your new implementation without needing to attack the bowels of your application.</p>
<h2>Notes</h2>
<ul>
<li>By setting <em>shared: true</em> in the configuration we are always given the same instance of an object. This is very useful when dealing with objects which contain resources such as database connections, file handles, etc</li>
<li>There are two methods by which dependencies can be injected. One is to pass dependencies with the constructor, or alternatively via setter methods. The generally accepted pattern is to pass required dependencies via the constructor and optionals via setters. My personal preference is to use setters for everything, but this is down to the individual developer</li>
</ul>
<h2>Finally&#8230;.</h2>
<p>Along with a brief discussion on dependency injection and its advantages and disadvantages this has also been a quick-start guide to implementing the Symfony Dependency Injection Container&#8230; hopefully you&#8217;ve seen that it&#8217;s surprisingly quick and easy. From here you&#8217;ll be able to start using dependency injection through your application and look to using many more of the advanced features (although the simple example covers the vast majority of functionality you&#8217;ll require). As always I point you to the <a title="Symfony DI container manual" href="http://components.symfony-project.org/dependency-injection/documentation" target="_blank">manual</a> for further information.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F264-quick-start-symfony-di-dependency-injection-tutorial%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Naked Zend_Layout and Zend_View</title>
		<link>http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/</link>
		<comments>http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 23:47:28 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Layout]]></category>
		<category><![CDATA[Zend_View]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[view helper]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend_layout]]></category>
		<category><![CDATA[zend_view]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=269</guid>
		<description><![CDATA[In this article I look at using Zend_Layout and Zend_View along with a simple front controller to show how it is possible to start separating business logic and presentation within your application. All code is available on github: Naked Zend_Layout and Zend_View on GitHub. MVC A common design pattern for modern web applications is the [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>In this article I look at using Zend_Layout and Zend_View along with a simple front controller to show how it is possible to start separating business logic and presentation within your application. All code is available on github:<br />
<a title="Naked Zend_Layout and Zend_View" href="http://github.com/lloydwatkin/Demos/tree/master/view/" target="_blank">Naked Zend_Layout and Zend_View on GitHub</a>.</p></blockquote>
<h2><span id="more-269"></span></h2>
<h2><a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller" class="kblinker" target="_blank" title="More about MVC &raquo;">MVC</a></h2>
<p>A common <a href="http://www.evilprofessor.co.uk/category/internet/design-patterns/" class="kblinker" title="More about design pattern &raquo;">design pattern</a> for modern web applications is the MVC pattern. The <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> in &#8216;full stack&#8217; mode is one implementation of MVC in <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a> and consists of three parts:</p>
<ul>
<li>Model (M)</li>
<li>View (V)</li>
<li>Controller (C)</li>
</ul>
<p>The pattern is designed such that business and presentation logic are completely separated from one another (with business logic in the model, and presentation in the view) and the controller sitting in the middle conducting the &#8220;orchestra&#8221;.</p>
<h2>Presentation and Logic</h2>
<p>In the Zend Framework the view  is handled by two main components: <strong>Zend_View</strong> and<strong> Zend_Layout</strong>. Zend_Layout as the name suggests looks after the layout  aspect of the site (generally headers, footers, sidebars, etc). Zend_View focusses on presenting the data that your model has been working to produce or derive.</p>
<p>As developers, and their applications, evolve we tend to move through various stages, generally each an improvement on the previous, improving maintainability and extensibility. One of the main issues is that presentation and logic still get intermingled and its not simple to start separating the two.</p>
<h4>What&#8217;s wrong with mixing the two?</h4>
<p><a href="http://www.evilprofessor.co.uk/wp-content/uploads/2010/08/ostrich-0776.jpg"><img class="alignright size-thumbnail wp-image-271" style="margin: 5px;" title="Ostrich" src="http://www.evilprofessor.co.uk/wp-content/uploads/2010/08/ostrich-0776-150x150.jpg" alt="Ostrich" width="225" height="225" /></a>There&#8217;s several reasons why mixing different parts of the application, for example a designer working on your site may not want to (or have the knowledge) to scan around in code trying to work out where to make presentation changes. In the same way a developer (if you&#8217;re like me who has the design skills of an ostrich) may break out in a cold sweat when you mention design or UI work.</p>
<p>Additionally what if later you would like to present your sites on different media, such as mobile telephones, tablet PCs, or expose the data via web services (XML/JSON/etc)? Having mixed presentation and logic you stand almost no hope without some very ugly hacks to pull the presentation back out of your code, before injecting something new. If data and presentation has been separated making these changes are almost trivial, create a new view script for the new format and direct requests as appropriate.</p>
<h2>Separating the two</h2>
<p>In an evolving application its not always economical to start implementing a full MVC solution and the application needs to be migrated slowly &#8211; sometimes running old code in parallel with new. It maybe that there are masses of logic (such as database connection setup, authentication, cookie handling, etc) that aren&#8217;t ready for moulding to your chosen frameworks setup, therefore old and known-to-be-working code can continue to be used until such time it can be rewritten/refactored.</p>
<p style="padding-left: 30px;"><em>Note: Using Zend_Layout and Zend_View like this is perfectly acceptable within the Zend Framework landscape and the framework has been designed such that individual components can be used without the rest of the framework. A great advantage in evolving applications and probably one of the major reasons for its high uptake in enterprise applications.</em></p>
<h2>Front Controller</h2>
<p>Below I create a front controller  - a single file designed to pick up any requests which are not matched to a file on the file-system. This is often achieved using a .htaccess file such as the one used in the default Zend Framework install. Within the front controller I will be setting up our layout and view and showing where the different parts of the application slip into it.</p>
<pre class="php">define('APP_PATH', dirname(__FILE__). '/..');
// Start buffering output
ob_start();

// Create a Zend_View instance
Zend_Layout::startMvc();
$layout = Zend_Layout::getMvcInstance();
$layout-&gt;setLayoutPath(APP_PATH . '/layout/scripts')
    -&gt;setViewSuffix('phtml')
    -&gt;setLayout('index');

$view = $layout-&gt;getView()
    -&gt;setScriptPath(APP_PATH . '/view/scripts')
    -&gt;addHelperPath(APP_PATH . '/library/Zend/View/Helper', 'Zend_View_Helper');

// Set Base URL - ok *almost* naked, but you don't need this!
Zend_Controller_Front::getInstance()-&gt;setBaseUrl($_SERVER['HTTP_HOST']);

try {
    /**
     * Perform some application routing...
     *  - Could be using this as a front controller and directing all requests
     *    through this one file (provided file does not exist in file system
     *  - Note the method below is only really for demonstration, it would be
     *    horrible with a large site
     */
    switch ($_GET['page']) {
    	case 'index':
    	case 'exception':
    		$pageName = $_GET['page'];
    		break;
    	default:
    		$pageName = false;
    		break;
    }
    // Example of a page not being found...
    if (false === $pageName) {
        $responseHeader = 'HTTP/1.1 404 Page Not Found';
        throw new Exception('Page not Found');
    }

    /**
     * Add data to your view object here
     *   You may have your own controller implementation or some includes files
     *   where business logic is partly separated from view logic
     */
    $view-&gt;displayText = 'Hello from Lloyd';
    $view-&gt;buttonText  = 'I\'m not active!';

	$layout-&gt;content = $view-&gt;render("{$pageName}.phtml");
    echo $layout-&gt;render();
} catch (Exception $e) {
	// Clean out already buffered content - we don't want to display that!
	ob_clean();
    if (!isset($responseHeader)) {
    	$responseHeader = 'HTTP/1.1 500 Internal Server Error';
    }
    header($responseHeader);
    $view-&gt;exception = $e;
    $layout-&gt;content = $view-&gt;render('error.phtml');
    echo $layout-&gt;render();
}</pre>
<p>Firstly we start output buffering, by doing this we can set our headers at any point in the request and know that it is possible to send them. Should an exception be thrown at any stage of the code execution we clean this buffer and write out or error message content and layout. This ensures that we do not deliver part rendered content containing errors to the end user.</p>
<p>Next a new MVC instance of Zend_Layout is generated and we tell it that out <a href="http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/" class="kblinker" title="More about layout script &raquo;">layout scripts</a> have the extension phtml, are to be found in a directory outside of the public path, and that our default layout is called index(.phtml). From the layout we then extract the view object (to which we set our data to be presented) and apply similar setup.</p>
<p>Next we setup the view object with a reference to the default Zend_View helpers. View helpers are sets of additional convenience functionality. For example, writing out a float in monetary format, or creating a zebra striped table (they can be read about <a title="Zend_View Helpers" href="http://framework.zend.com/manual/en/zend.view.helpers.html" target="_blank">here</a>). By extending Zend_View_Helper_Abstract and adding your own library at this point its possible to use your own application view helpers.</p>
<p>The rest of the application code is now wrapped in a try {} catch {} block. Should anything throw an uncaught exception we can catch it and display a nice error message to the end user.</p>
<p>Our first task within the try {} catch {} is to route our request, what does the user want to see? Here I&#8217;ve implemented some very simple demonstration code where I check the value of the &#8216;page&#8217; get variable. Your routing can be very much more complex. The routing is used to call what ever code needs to be executed to get/handle data provided by the user and to tell the system what view (and possibly layout script) to use.</p>
<p>Ultimately if our router does not match any page it sets a 404 response code and displays a nice page not found message to the end user. Here, we throw and catch our own exception (and a very generic exception at that) but probably you&#8217;d be throwing your own exception from within the router code.</p>
<p>Once we&#8217;ve successfully routed our request we can begin to do something with the code. It might be that you have your own controllers/models implemented or you include some code that&#8217;s already been separated somewhat. Here I set a couple of simple variables to the view object.</p>
<p>Once this is completed we simply render the views with our data. If the code throws an uncaught exception for any reason this is trapped near the bottom of the script. Here we clear already buffered output, set a 500 response header, and tell our application to render the &#8216;error&#8217; view script (which is generally a much stripped down version of the normal layout/view and logs the error for checking later).</p>
<p>As the view is rendered first and injected into the layout it is possible to change the layout from within the view, and indeed set required extras, for example,</p>
<ul>
<li>Page title</li>
<li>Meta tags</li>
<li>Scripts (URLs or code) into the &amp;lt;head&amp;gt; section</li>
<li>Add additional styles, etc</li>
</ul>
<p>Additionally its even possible to change the entire layout from within the view by using&#8230;</p>
<pre class="php">&lt;?php $this-&gt;layout()-&gt;setLayout('alternativeLayout') ?&gt;</pre>
<p>&#8230;as and when required.</p>
<h2>Finally&#8230;</h2>
<p>I hope this has been a useful introduction to Zend_Layout and Zend_View and it will enable you to start implementing your own basic MVC and improve the maintainibility/extensibility of your code. Please take a look at the source code for examples of usage (see the README file for instructions).</p>
<p><strong>The code assumes that you&#8217;ve already got autoloading working (or you have included the required classes).  In addition, I would not recommend that you implement the routing or data setting as above, this is very much simplified for demonstration. To see the full code take a look at the source code linked at the top of this article.</strong></p>
<p><strong>Zend Framework version: 1.10.6</strong></p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F269-naked-zend_layout-and-zend_view%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Framework Per Module Layout Settings &#8211; Follow Up</title>
		<link>http://www.evilprofessor.co.uk/242-zend-framework-per-module-layout-settings-follow-up/</link>
		<comments>http://www.evilprofessor.co.uk/242-zend-framework-per-module-layout-settings-follow-up/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 20:48:44 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[action]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=242</guid>
		<description><![CDATA[As a follow up to my previous post on per module based layout settings for Zend Framework, I&#8217;ve updated the code to require less configuration then before (not that it required more that a few lines in your application configuration!). Again we make use of a Zend Controller Action Helper invoking it from the bootstrap [...]]]></description>
			<content:encoded><![CDATA[<p>As a follow up to my previous post on <a title="Per Module Based Layout Settings - Zend Framework" href="http://www.evilprofessor.co.uk/227-zend-framework-per-module-based-settings/" target="_blank">per module based layout settings</a> for <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a>, I&#8217;ve updated the code to require less configuration then before (not that it required more that a few lines in your application configuration!).<br />
<span id="more-242"></span><br />
Again we make use of a <a title="Zend Controller Action Helper" href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html" target="_blank">Zend Controller Action Helper</a> invoking it from the bootstrap as follows:</p>
<pre class="php" name="code">
    /**
     * Sets up <a href="http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/" class="kblinker" title="More about layout script &raquo;">layout scripts</a> on a per-module basis
     */
    protected function _initLayoutHelper()
	{
	    $this-&gt;bootstrap('frontController');
	    $layout = Zend_Controller_Action_HelperBroker::addHelper(
	        new Pro_Controller_Action_Helper_SetLayoutPath(APPLICATION_PATH));
	}
</pre>
<p>Almost exactly the same as before except this time we pass the constant <strong>APPLICATION_PATH</strong> into the constructor as our base path.</p>
<p>Next the controller action helper itself now looks as follows:</p>
<pre class="php" name="code">
/**
 * Sets the layout path on a per-module basis
 *
 * @author     Lloyd Watkin
 * @since      16/02/2010
 * @package    Pro
 * @subpackage Controller_Action_Helper
 */

/**
 * Sets the layout path on a per-module basis
 *
 * @author     Lloyd Watkin
 * @since      16/02/2010
 * @package    Pro
 * @subpackage Controller_Action_Helper
 */
class Pro_Controller_Action_Helper_SetLayoutPath
    extends Zend_Controller_Action_Helper_Abstract
{
	/**
	 * Base path
	 *
	 * @var string
	 */
	protected $_path;

	/**
	 * Construct
	 *
	 * @param string $path
	 */
	public function __construct($path)
	{
	    $this-&gt;setBasePath($path);
	}

	/**
	 * Set base path
	 *
	 * @param string $path
     */
	public function setBasePath($path)
	{
		if (!is_string($path) || empty($path)) {
			throw new Exception('Excepted string for base path');
		}
		$this-&gt;_path = $path;
	}

	/**
	 * Get the base path
	 *
	 * @return string
	 */
	protected function _getBasePath()
	{
		if (is_null($this-&gt;_path)) {
			if (!defined('APPLICATION_PATH')) {
				throw new Exception('Base path can not be determined');
			}
			$this-&gt;_path = APPLICATION_PATH;
		}
		return $this-&gt;_path;
	}

    /**
     * Sets layout path based on module
     */
    public function preDispatch()
    {
    	$module = preg_replace(
    	    '/[^A-Z]/i', '', $this-&gt;getRequest()-&gt;getModuleName()
    	);

	    if ($bootstrap = $this-&gt;getActionController()
	                       -&gt;getInvokeArg('bootstrap')) {

	        $view = $bootstrap-&gt;getResource('view');
	        $layoutPath = $this-&gt;_getBasePath() .
	            "/modules/{$module}/layouts/scripts/";

	        /* If layout directory exists then apply it, otherwise just fall
	         * back on the default
	         */
	        if (is_dir($layoutPath)) {
	            $this-&gt;getActionController()
	                 -&gt;getHelper('layout')
	                 -&gt;setLayoutPath($layoutPath);
	            $view-&gt;headLink()-&gt;appendStylesheet(
	                "/styles/{$module}/style.css"
	            );
	        }
    	}
    }
}
</pre>
<p>Note the passing of our base path (cf. APPLICATION_PATH) in the constructor, we also have a getter and setter for the base path. Unlike the previous version of the code if the layouts path does not exist then the code will fall back the default layout path. If the base path is not set it will try to determine the base path from the constant APPLICATION_PATH, otherwise an exception is thrown. I&#8217;ve also cheekily thrown in a module-based style sheet for good measure</p>
<p>The module based layout is determined from whether the layout script path exists (obviously this method can be changed easily). This does add a little overhead from the application.ini setup (however if the layout path exists <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a> will cache the result for performance*) but in return you gain the <em>added convenience</em> of more easily dropping in new modules.</p>
<p>That&#8217;s it, not much different, but you don&#8217;t need to add a new configuration entry each time you wish to add a new module :)</p>
<p>*To clear this cache (if required) use the <a href="http://uk.php.net/manual/en/function.clearstatcache.php" target="_blank">clearstatcache</a> function.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F242-zend-framework-per-module-layout-settings-follow-up%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/242-zend-framework-per-module-layout-settings-follow-up/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating URL in Zend Custom View Helper</title>
		<link>http://www.evilprofessor.co.uk/239-creating-url-in-zend-custom-view-helper/</link>
		<comments>http://www.evilprofessor.co.uk/239-creating-url-in-zend-custom-view-helper/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 23:01:57 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_View]]></category>
		<category><![CDATA[Zend_View_Helper]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[front controller]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[Router]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[Zend_View_Helper_Abstract]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=239</guid>
		<description><![CDATA[This may seem simple, but I was banging my head trying to create a URL in a custom view helper in Zend Framework. I have routing setup which gets the module from the sub-domain in use so I couldn&#8217;t use a simple hardcoded URL. Basically but invoking an instance of the front controller its possible [...]]]></description>
			<content:encoded><![CDATA[<p>This may seem simple, but I was banging my head trying to create a URL in a custom view helper in <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a>. I have routing setup which gets the module from the sub-domain in use so I couldn&#8217;t use a simple hardcoded URL.</p>
<p><span id="more-239"></span></p>
<p>Basically but invoking an instance of the front controller its possible to grab the router and assemble a url. Assemble is the function used in the view helper. The URL is built up from an array of module, controller, action, etc, followed by a second parameter of the route to use. The code is as follows:</p>
<pre name="code" class="php">&lt;?php
/**
 * View helper which returns link category URL
 *
 * @author     Lloyd Watkin
 * @since      25/01/2010
 * @package    ViewHelper
 * @subpackage LinksUrl
 */
class Pro_View_Helper_LinksUrl
    extends Zend_View_Helper_Abstract
{
	/**
	 * Returns link category URL
	 *
	 * @param  Doctrine_Record $category
	 * @param  string          $module
	 * @param  string          $controller
	 * @param  string          $action
	 * @return string Url
	 */
    public function linksUrl($category, $module = 'www',
        $controller = 'links', $action = 'index')
    {
    	$router = Zend_Controller_Front::getInstance()-&gt;getRouter();

        return $router-&gt;assemble(array(
            'module'     =&gt; $module,
            'controller' =&gt; $controller,
            'action'     =&gt; $action,
            'category'   =&gt; "{$category-&gt;id}-{$category-&gt;name}",
        ), 'www-index');
    }
}</pre>
<p>Another way to do this is to invoke Zend_View_Helper_Url itself and call the Url method (if you want to use the helper itself). This can be done by using the following code:</p>
<pre class="php" name="code">&lt;?php
/**
 * View helper which returns link category URL
 *
 * @author     Lloyd Watkin
 * @since      25/01/2010
 * @package    ViewHelper
 * @subpackage LinksUrl
 */
class Pro_View_Helper_LinksUrl
    extends Zend_View_Helper_Abstract
{
	/**
	 * Returns link category URL
	 *
	 * @param  Doctrine_Record $category
	 * @param  string          $module
	 * @param  string          $controller
	 * @param  string          $action
	 * @return string Url
	 */
    public function linksUrl($category, $module = 'www',
        $controller = 'links', $action = 'index')
    {
    	$link = new Zend_View_Helper_Url();

        return $link-&gt;url(array(
            'module'     =&gt; $module,
            'controller' =&gt; $controller,
            'action'     =&gt; $action,
            'category'   =&gt; "{$category-&gt;id}-{$slug}",
        ), 'www-index');
    }
}</pre>
<p>Both almost identical. Not a hard thing to do in the framework but can catch you out ;)</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F239-creating-url-in-zend-custom-view-helper%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/239-creating-url-in-zend-custom-view-helper/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Route requests for sitemap.xml to custom controller/action</title>
		<link>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/</link>
		<comments>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 00:13:56 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[Router]]></category>
		<category><![CDATA[Routes]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[Zend_Navigation]]></category>
		<category><![CDATA[Zend_Router]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=231</guid>
		<description><![CDATA[In order to direct requests for /sitemap.xml to a custom controller and action in your Zend Framework application simply add the following in your application.ini or alternative config file (e.g. I use navigation.ini): resources.router.routes.sitemap.route = "sitemap.xml" resources.router.routes.sitemap.defaults.controller = index resources.router.routes.sitemap.defaults.action = sitemap Example code for outputting can be seen by creating an action in the [...]]]></description>
			<content:encoded><![CDATA[<p>In order to direct requests for /<a href="http://en.wikipedia.org/wiki/Sitemaps">sitemap.xml</a> to a custom controller and action in your <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> application simply add the following in your application.ini or alternative config file (e.g. I use navigation.ini):</p>
<pre name="code" class="ini">
resources.router.routes.sitemap.route                = "sitemap.xml"
resources.router.routes.sitemap.defaults.controller  = index
resources.router.routes.sitemap.defaults.action      = sitemap
</pre>
<p>Example code for outputting can be seen by creating an action in the appropriate controller (e.g. my sitemap lies in the index controller, sitemap action):</p>
<pre name="code" class="php">
&lt;<a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">php</a>
class IndexController
    extends Zend_Controller_Action
{
    /**
     * Renders a sitemap based on Zend_Navigation setup
     */
    public function sitemapAction()
    {
    	echo $this->view->navigation()->sitemap();
    	$this->view->layout()->disableLayout();
    	$this->_helper->viewRenderer->setNoRender(true);
    }
}
</pre>
<p>Sitemaps can quickly and easily be generated using <a href="http://framework.zend.com/manual/en/zend.navigation.html">Zend_Navigation</a>, a great quick tutorial (and generally very useful for Zend Framework tutorials) is <a href="http://www.zendcasts.com/">Zend Casts</a> &#8211; <a href="http://www.zendcasts.com/zend_navigation-dynamically-creating-a-menu-a-sitemap-and-breadcrumbs/2009/06/">Dynamically creating a menu a sitemap and breadcrumbs</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F231-route-requests-for-sitemap-xml-to-custom-controlleraction%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Zend Framework Per-Module based settings</title>
		<link>http://www.evilprofessor.co.uk/227-zend-framework-per-module-based-settings/</link>
		<comments>http://www.evilprofessor.co.uk/227-zend-framework-per-module-based-settings/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 22:40:16 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[layoutPath]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=227</guid>
		<description><![CDATA[I&#8217;ve created a followup to this post which requires less configuration, please see Module Based Layout &#8211; Zend Framework. When using the zend framework with modules, its obvious that if you&#8217;re running various (sub-)sites off the same application you don&#8217;t necessarily want the same layout scripts for each part. I decided to go with the [...]]]></description>
			<content:encoded><![CDATA[<p><em>I&#8217;ve created a followup to this post which requires less configuration, please see <a href="http://www.evilprofessor.co.uk/242-zend-framework-per-module-layout-settings-follow-up/">Module Based Layout &#8211; Zend Framework</a>.</em></p>
<p>When using the <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">zend framework</a> with modules, its obvious that if you&#8217;re running various (sub-)sites off the same application you don&#8217;t necessarily want the same <a href="http://www.evilprofessor.co.uk/269-naked-zend_layout-and-zend_view/" class="kblinker" title="More about layout script &raquo;">layout scripts</a> for each part. I decided to go with the following site structure:</p>
<pre>/Application
    /controllers
        ...
    /models
    /modules
        /default
            /controllers
            /layout
                /scripts
            /views
                /scripts
        /anotherModule
            ...
    /scripts
</pre>
<p>The problem was setting up the layout scripts on a per-module basis. The answer came through using an Action Helper. Setting up the layouts on a per-module basis involves three steps:</p>
<ol>
<li>Application.ini (or similar configuration setup):<br/>
<pre name="code" class="ini">admin.resources.layout.layoutPath = APPLICATION_PATH "/modules/admin/layouts/scripts"
default.resources.layout.layoutPath = APPLICATION_PATH "/modules/default/layouts/scripts"
member.resources.layout.layoutPath = APPLICATION_PATH "/modules/member/layouts/scripts"
affiliate.resources.layout.layoutPath = APPLICATION_PATH "/modules/affiliate/layouts/scripts"</pre>
</li>
<li>Create your Action Helper:<br/>
<pre name="code" class="php">&lt;?php
/**
 * Sets the layout path on a per-module basis
 *
 * @author Lloyd Watkin &lt;lloyd@evilprofessor.co.uk&gt;
 * @since  2010-01-01
 */
class Pro_Controller_Action_Helper_SetLayoutPath
    extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * Sets layout path based on module
     */
    public function preDispatch()
    {
    	$module = $this->getRequest()->getModuleName();

	    if ($bootstrap = $this->getActionController()
	                       ->getInvokeArg('bootstrap')) {

	        $config = $bootstrap->getOptions();

	        if (isset($config[$module]['resources']['layout']['layoutPath'])) {
	            $layoutPath =
	                 $config[$module]['resources']['layout']['layoutPath'];
	            $this->getActionController()
	                 ->getHelper('layout')
	                 ->setLayoutPath($layoutPath);
	        }
    	}
    }
}</pre>
</li>
<li>And lastly boostrap the action helper:<br/>
<pre name="code" class="php">...
    /**
     * Sets up layout scripts on a per-module basis
     */
    protected function _initLayoutHelper()
	{
	    $this->bootstrap('frontController');
	    $layout = Zend_Controller_Action_HelperBroker::addHelper(
	        new Pro_Controller_Action_Helper_SetLayoutPath());
	}
...</pre>
</li>
</ol>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F227-zend-framework-per-module-based-settings%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/227-zend-framework-per-module-based-settings/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Fundamentals &#8211; Review</title>
		<link>http://www.evilprofessor.co.uk/117-zend-framework-fundamentals-review/</link>
		<comments>http://www.evilprofessor.co.uk/117-zend-framework-fundamentals-review/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 22:42:27 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Courses]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[course]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[dynamic libraries]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[fundamentals]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[summary]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[webex]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=117</guid>
		<description><![CDATA[For developers who haven't had time to look at the Zend Framework this course (Zend Framework: Fundamentals) offers a good overall picture of the framework introducing you to the key areas and giving enough information in order to continue. For those who have spent time looking at the framework and have followed one or two tutorials this course does not offer much beyond.]]></description>
			<content:encoded><![CDATA[<p>My employer recently paid for a group of us developers to take the <a title="Zend Framework: Fundamentals" href="http://www.zend.com/services/training/course-catalog/zend-framework" target="_blank">Zend Framework: Fundamentals</a> course, here I&#8217;ll summarise my thoughts and opinions on the course for others. For those looking to save time, here&#8217;s my summary:</p>
<p><em>For developers who haven&#8217;t had time to look at the <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> this course (Zend Framework: Fundamentals) offers a good overall picture of the framework introducing you to the key areas and giving enough information in order to continue. For those who have spent time looking at the framework and have followed one or two tutorials this course does not offer much beyond.</em></p>
<h2>Background</h2>
<p>I&#8217;ve been a <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a> developer for around 5-6 years, and have started working with the Zend Framework on a component basis over the last 6 months. I&#8217;ve developed and/or been a developer on a couple of small Zend Framework <a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller" class="kblinker" target="_blank" title="More about MVC &raquo;">MVC</a> sites.Â  I&#8217;ll be honest, I haven&#8217;t had a huge amount of exposure to other frameworks from a coding point of view but have spent several hours researching the project websites and evaluating them.Â  The framework and the community surrounding Zend Framework it is quite exciting and there seem to be huge possibilities in where its going.</p>
<h2>About the Course</h2>
<p>The course is delivered over 9 two hour webex sessions (with a 10-minute break in the middle). The time is spent going through a set of slides provided by Zend with discussion at any time. You can use a microphone to talk to the instructor, but to be honest I didn&#8217;t see anyone use anything more than the chat window. In addition a VMWare Ubuntu machine is provided that has example code and projects set up an a trial version of Zend Studio. The course leader talks to attendees either over an integrated VoIP solution, or you can dial in using one of the many worldwide dial in numbers.</p>
<p>During the course the material consists of a brief overview of the Framework and the MVC pattern before heading into a sample guestbook application. The discussion demonstrated bootstrapping, Zend_Application, Db Tables, Database access, Forms, Filtering, ACL, Validating, etc, etc. Basically covering all the topics you&#8217;d require to get a basic site up an running all the time giving you the tools to go and get more advanced in the framework (although this did amount to &#8216;See the website&#8217; much of the time).</p>
<p>Time is given to code up some examples, and to develop the &#8216;guestbook&#8217; and simple &#8216;wiki&#8217; application. Personally I felt that providing the code or each app and then asking us to develop what was essentially a copy alongside didn&#8217;t really provide a good learning experience. I would have preferred to develop an application similar, but not identical. to the example application with the benefit of having a guide to refer to. Alternatively building the applications from scratch with the demonstrator would of possibly led to more questions about <strong>why</strong> and <strong>how</strong>, thus giving a better understanding of the framework, after all you can look up specifics after the course.</p>
<p>The last lecture consisted of working on the wiki application with help/guidance from the instructor. After the course feedback was taken, it was emphasised several times through the course that Zend takes feedback very seriously, in fact apparently our version of the course was quite new. Some of the other developers in the company will be taking the course soon so it will be interesting to see if this has happened.</p>
<p>The course style was informal, allowed for feedback and collaboration between attendees and the instructor. The course leader was friendly, approachable (email addresses were shared for questions), and whilst his presentation from the slides was a bit shaky seemed fully competent in the framework. He was clearly someone who used the framework on a regular basis rather than someone who is taught to teach the course, I liked the &#8216;real world&#8217; experience in that respect.</p>
<h2>Overall Feeling</h2>
<p>In some ways I found the course a waste of time, in others it was very handy. Hopefully I&#8217;ll get my reasons across clearly, and maybe provide some food for thought or useful feedback (knowing me this is unlikely!).</p>
<p>For myself this course was aimed at too low a level. Having gone through the quickstart guide, read Rob Allen&#8217;s Zend Framework in Action, and worked with the framework a little I didn&#8217;t really get anything too much. I would of liked the course to pick up from the end of the quickstart and develop additional skills.</p>
<p>That said, the course title does clearly state &#8220;Zend Framework: <strong>Fundamentals</strong>&#8221; and in that aspect the course achieves what it sets out to do. Other members of the development team that haven&#8217;t spent the time looking into the framework finished each session with enthusiasm and asked questions which was really nice to see.</p>
<p>All was not lost, it was good to spend time confirming the basic details of the framework and get to ask a couple of questions in areas where I wasn&#8217;t 100%. It was also time that I got to sit down each day and think about coding using the framework and future projects, something I wouldn&#8217;t of been able to do otherwise (can you imagine your company agreeing to that? :) ). Last but not least you also get a nice certificate from Zend to say that you attended the course (albeit by email).</p>
<h3>Zend Framework Certification</h3>
<p>This was one question that kept coming to mind during the course, would it prepare me for the certification? The quick, easy is a resounding <strong>No</strong>. The course instructor was quite clear on that with the additional advice that for the certification you should really be using the framework on a day to day basis and feel very comfortable and confident in its usage and methodologies.</p>
<h2>Summary</h2>
<p>Given everything I&#8217;ve written above, I&#8217;ll summarise everything in two easy bullet points:</p>
<ul>
<li><em>New to Zend Framework: </em>This course does exactly what you&#8217;d expect, it gives you a nice introduction to the framework and a good grounding on the basics from which you can build. The course seems to generate interest and enthusiasm for the framework amongst developers.</li>
<li><em>Used the Zend Framework: </em>While it was nice to shore up some of the very basics I felt the time, effort, and funds to take the course could of been better spent elsewhere. It will be nice to seeÂ  Zend create a new higher level course to take developers to the next level &#8211; at least to the standard of certification and beyond. <strong>For that I would sign up immediately.</strong></li>
</ul>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F117-zend-framework-fundamentals-review%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/117-zend-framework-fundamentals-review/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Log to DB using Zend Framework</title>
		<link>http://www.evilprofessor.co.uk/98-log-to-db-using-zend-framework/</link>
		<comments>http://www.evilprofessor.co.uk/98-log-to-db-using-zend-framework/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 21:06:30 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[writers]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=98</guid>
		<description><![CDATA[I&#8217;ve managed to get a site up and running with the Zend Framework, everything is logging nicely to FireBug/FirePHP so next step was to log to the DB. I also wanted to log some additional information using the framework such as user agent, date and time, get and post variables. So to extend the manual [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve managed to get a site up and running with the <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a>, everything is logging nicely to FireBug/FirePHP so next step was to log to the DB. I also wanted to log some additional information using the framework such as user agent, date and time, get and post variables. So to extend the manual a little here&#8217;s what I did:</p>
<p><code>// Set up logging to DB<br />
$db = <a href="http://framework.zend.com/manual/en/zend.registry.html" class="kblinker" target="_blank" title="More about Zend_Registry &raquo;">Zend_Registry</a>::get('dbAdapters');<br />
$db = $db['general'];</p>
<p>$columnMapping = array(	'priority' 	=> 'priority',<br />
						'message' 	=> 'message',<br />
						'datetime' 	=> 'timestamp',<br />
						'user_agent'=> 'user_agent',<br />
						'get_vars'	=> 'get_vars',<br />
						'post_vars'	=> 'post_vars',<br />
						'site'		=> 'site'<br />
						);</p>
<p>$writerDb   = new Zend_Log_Writer_Db($db, 'error_logging', $columnMapping);<br />
$logger 	= new Zend_Log($writerDb);</p>
<p>$logger->setEventItem('datetime',date('Y-m-d H:i:s'));<br />
$logger->setEventItem('user_agent',$_SERVER['HTTP_USER_AGENT']);<br />
$logger->setEventItem('get_vars',print_r($_GET,true));<br />
$logger->setEventItem('post_vars',print_r($_POST,true));<br />
$logger->setEventItem('site',SITE);	</p>
<p>$logger->info('Informational message');</code></p>
<p>Where the array keys in $columnMapping are my column names. &#8216;Priority&#8217; and &#8216;message&#8217; are understood by <a href="http://framework.zend.com/manual/en/zend.log.writers.html">Zend_Log_Writers</a> but the additional fields were added to give me some additional information.</p>
<p>Obviously this assumes that you have logging working using one of the other writers first :)</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F98-log-to-db-using-zend-framework%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/98-log-to-db-using-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
