<?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>Rob Allen&#039;s DevNotes &#187; Zend Framework</title>
	<atom:link href="http://akrabat.com/category/zend-framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://akrabat.com</link>
	<description>Developing PHP software in the Real World, by Rob Allen</description>
	<lastBuildDate>Wed, 01 Sep 2010 14:33:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>The Redirector action helper</title>
		<link>http://akrabat.com/zend-framework/the-redirector-action-helper/</link>
		<comments>http://akrabat.com/zend-framework/the-redirector-action-helper/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 07:08:13 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=1171</guid>
		<description><![CDATA[Following on from the discussion on the FlashMessenger action helper, I thought I'd also cover another supplied helper: Redirector. Redirector does what it says on the tin and redirects the user to another page. I mostly use this when coming back from filling a form in, so that the user is then redirected to another [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from the discussion on the <a href="http://akrabat.com/zend-framework/zend-frameworks-flash-messenger-action-helper/">FlashMessenger action helper</a>, I thought I'd also cover another supplied helper: <a href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.redirector">Redirector</a>.</p>
<p>Redirector does what it says on the tin and redirects the user to another page. I mostly use this when coming back from filling a form in, so that the user is then redirected to another page. In admin systems, this is usually a list page. On front end websites, this is usually a thank you page. Though for log-in forms, I tend to try and return the user to where they were going!</p>
<p>It's used in a controller action method like this:</p>
<pre class="phpcode"><span style="color: #0000BB">$urlOptions&nbsp;</span><span style="color: #007700">=&nbsp;array(</span><span style="color: #DD0000">'controller'</span><span style="color: #007700">=&gt;</span><span style="color: #DD0000">'index'</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'action'</span><span style="color: #007700">=&gt;</span><span style="color: #DD0000">'index'</span><span style="color: #007700">);
</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">redirector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">gotoRoute</span><span style="color: #007700">(</span><span style="color: #0000BB">$urlOptions</span><span style="color: #007700">);</span>
</span></code></pre>
<p><tt>gotoRoute()</tt> takes the same set of parameters are the <tt>url()</tt> view helper which is not a surprise as they both proxy through to the Front Controller's router object. It's handy though as one you know one, you know the other :)</p>
<p>If you are using the default route, then you can use <tt>gotoSimple()</tt>. For example to redirect to the news controller's list action, you would do:</p>
<pre class="phpcode"><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">redirector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">gotoSimple</span><span style="color: #007700">(</span><span style="color: #DD0000">'list'</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'news'</span><span style="color: #007700">);</span>
</span></code></pre>
<p>The <tt>gotoSimple()</tt> method signature is:</p>
<pre class="phpcode"><span style="color: #0000BB">gotoSimple</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$controller&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$module&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">,&nbsp;array&nbsp;</span><span style="color: #0000BB">$params&nbsp;</span><span style="color: #007700">=&nbsp;array());</span>
</span></code></pre>
<p>As you can see, it provides defaults for the controller and module and params parameters so you only need to set them if you need to. This works well for admin system as I tend to be redirecting within the same controller (from the edit or delete action to index, usually).</p>
<p>You can also use the Redirector with an absolute URL, by using the <tt>gotoUrl()</tt> method:</p>
<pre class="phpcode"><span style="color: #0000BB">$url&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'http://www.akrabat.com'</span><span style="color: #007700">;
</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">redirector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">gotoUrl</span><span style="color: #007700">(</span><span style="color: #0000BB">$url</span><span style="color: #007700">);</span>
</span></code></pre>
<p>I tend to use this one much less frequently - so infrequently, that I can't think of a use-case off the top of my head :)</p>
<p>By default, Redirector sets a 302 status code, however you can also set a 301 if you want to:</p>
<pre class="phpcode"><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helpers</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">redirector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setCode</span><span style="color: #007700">(</span><span style="color: #0000BB">301</span><span style="color: #007700">);</span>
</span></code></pre>
<p>There are a few other options that can be set like <tt>setExit()</tt> and <tt>setUseAbsoluteUri()</tt>, but to be honest, I don't think I've ever used them!</p>
<p>I find that I use Redirector fairly frequently as its <tt>gotoRoute()</tt> uses the same parameters as <tt>url()</tt> which makes it easy to remember how to use it. Like <tt>url()</tt>, it also benefits from remembering which route was used to get you to the current page and reuses that when creating the next one which is handy. </p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/the-redirector-action-helper/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Zend Framework&#039;s Flash Messenger action helper</title>
		<link>http://akrabat.com/zend-framework/zend-frameworks-flash-messenger-action-helper/</link>
		<comments>http://akrabat.com/zend-framework/zend-frameworks-flash-messenger-action-helper/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 08:10:51 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=1152</guid>
		<description><![CDATA[I've talked about Zend Framework's action helpers before, but haven't covered any of the action helpers that are supplied with Zend Framework. FlashMessenger is a helper that allows you to store messages between requests. The most common use I have for it is for a "saved" message after doing an edit of an item that [...]]]></description>
			<content:encoded><![CDATA[<p>I've talked about Zend Framework's action helpers <a href="http://akrabat.com/zend-framework/hooks-in-action-helpers/">before</a>, but haven't covered any of the action helpers that are supplied with Zend Framework.</p>
<p><a href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.flashmessenger">FlashMessenger</a> is a helper that allows you to store messages between requests. The most common use I have for it is for a "saved" message after doing an edit of an item that then redirects back to a list.</p>
<p>This is how it's used:</p>
<h3>Storing a message</h3>
<p>Storing to the FlashMessenger is easy. This is my typical usage within an action controller:</p>
<pre class="phpcode"><span style="color: #0000BB">
$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">flashMessenger</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">addMessage</span><span style="color: #007700">(</span><span style="color: #DD0000">'Task&nbsp;saved'</span><span style="color: #007700">);
</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">redirector</span><span style="color: #007700">(</span><span style="color: #DD0000">'index'</span><span style="color: #007700">);
</span>
</span></code></pre>
<p>This code adds the message "Task saved" to the FlashMessenger and then redirects the user the index action, which in this case is a list of tasks. As should be obvious from the name of the method, you can add multiple messages and they will all be stored for retrieval after the next redirect.</p>
<p>The FlashMessenger will store the message that you've added for one <em>hop</em>, or number of requests. This means that the message will be available for retrieval on the next request, but unavailable on the request afterwards. This is very useful and it means that if someone refreshes the task list by hitting F5, then the "Task saved" message does not reappear.</p>
<h3>Retrieving the stored messages</h3>
<p>Retrieving the stored messages is similarly simple:</p>
<pre class="phpcode"><span style="color: #0000BB">
$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">messages&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_helper</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">flashMessenger</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getMessages</span><span style="color: #007700">();
</span>
</span></code></pre>
<p>This will create an array of messages in your view object which you can then loop over in your view script:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">count</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">messages</span><span style="color: #007700">))&nbsp;:&nbsp;</span><span style="color: #0000BB">?&gt;
</span>&lt;ul&nbsp;id="messages"&gt;
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">foreach&nbsp;(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">messages&nbsp;</span><span style="color: #007700">as&nbsp;</span><span style="color: #0000BB">$message</span><span style="color: #007700">)&nbsp;:&nbsp;</span><span style="color: #0000BB">?&gt;
</span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">echo&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">escape</span><span style="color: #007700">(</span><span style="color: #0000BB">$message</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">?&gt;</span>&lt;/li&gt;
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">endforeach;&nbsp;</span><span style="color: #0000BB">?&gt;
</span>&lt;/div&gt;
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">endif;&nbsp;</span><span style="color: #0000BB">?&gt;
</span>
</span></code></pre>
<p>and that's all there is to the FlashMessenger.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/zend-frameworks-flash-messenger-action-helper/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>New Zend_Auth tutorial</title>
		<link>http://akrabat.com/zend-framework/new-zend-auth-tutorial/</link>
		<comments>http://akrabat.com/zend-framework/new-zend-auth-tutorial/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 07:38:50 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=1136</guid>
		<description><![CDATA[After too many months of neglect, I have completely rewritten my Zend_Auth tutorial so that it is compatible with Zend Framework 1.10! As an experiment, I have written it directly in HTML, rather than PDF as before and cover the login form along with the login controller code required to authenticate a user using a [...]]]></description>
			<content:encoded><![CDATA[<p>After too many months of neglect, I have completely rewritten my <a href="/zend-auth-tutorial">Zend_Auth tutorial</a> so that it is compatible with Zend Framework 1.10!</p>
<p>As an experiment, I have written it directly in HTML, rather than PDF as before and cover the login form along with the login controller code required to authenticate a user using a database table. For good measure, I've included logging out and a view helper to show how to access the logged in user's details.</p>
<p>The full source code is also available, if you don't want to type it in :)</p>
<p>I hope you find it useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/new-zend-auth-tutorial/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Akrabat_Db_Schema_Manager: table prefix support</title>
		<link>http://akrabat.com/zend-framework/akrabat_db_schema_manager-table-prefix-support/</link>
		<comments>http://akrabat.com/zend-framework/akrabat_db_schema_manager-table-prefix-support/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 10:39:00 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=1072</guid>
		<description><![CDATA[I've updated Akrabat_Db_Schema_Manager so that it now supports table prefixes. It uses the application.ini key of resources.db.table_prefix as I couldn't think of a better one :) and then uses that for the schema_version table's name and also makes it available in your change objects. For example, if application.ini contains resources.db.table_prefix = "myapp", then the manager [...]]]></description>
			<content:encoded><![CDATA[<p>I've updated <a href="http://github.com/akrabat/Akrabat">Akrabat_Db_Schema_Manager</a> so that it now supports table prefixes.</p>
<p>It uses the application.ini key of <tt>resources.db.table_prefix</tt> as I couldn't think of a better one :) and then uses that for the <tt>schema_version</tt> table's name and also makes it available in your change objects.</p>
<p>For example, if application.ini contains <tt>resources.db.table_prefix = "myapp"</tt>, then the manager will create the table <tt>myapp_schema_version</tt> to store the current version of the schema. In your change classes, you can then do this:</p>
<p><strong>001-Users.php:</strong></p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Users&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Akrabat_Db_Schema_AbstractChange&nbsp;
&nbsp;</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">up</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$tableName&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_tablePrefix&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #DD0000">'users'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$sql&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CREATE&nbsp;TABLE&nbsp;IF&nbsp;NOT&nbsp;EXISTS&nbsp;</span><span style="color: #0000BB">$tableName</span><span style="color: #DD0000">&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;int(11)&nbsp;NOT&nbsp;NULL&nbsp;AUTO_INCREMENT,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username&nbsp;varchar(50)&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password&nbsp;varchar(75)&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;role&nbsp;varchar(200)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;'user',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRIMARY&nbsp;KEY&nbsp;(id)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;ENGINE=InnoDB&nbsp;DEFAULT&nbsp;CHARSET=utf8;"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #0000BB">$sql</span><span style="color: #007700">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data&nbsp;</span><span style="color: #007700">=&nbsp;array();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #DD0000">'admin'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'password'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #0000BB">sha1</span><span style="color: #007700">(</span><span style="color: #DD0000">'password'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'role'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #DD0000">'admin'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">insert</span><span style="color: #007700">(</span><span style="color: #0000BB">$tableName</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">down</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$tableName&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_tablePrefix&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #DD0000">'users'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$sql</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"DROP&nbsp;TABLE&nbsp;IF&nbsp;EXISTS&nbsp;</span><span style="color: #0000BB">$tableName</span><span style="color: #DD0000">"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #0000BB">$sql</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;}
</span>
</span></code></pre>
<p>which will create a table called <tt>myapp_users</tt>. Note that you are responsible for using the prefix property as the change classes cannot enforce what you do within the <tt>up()</tt> and <tt>down()</tt> methods. It also follows that you'll have to ensure that your models also use the correct prefix.</p>
<p>I have also made a change to the provider (<tt>Akrabat_Tool_DatabaseSchemaProvider</tt>) so that it loads the correct application.ini file based on the data in the project's profile. This shouldn't affect anyone using Akrabat_Db_Schema_Manager, except that we no longer define <tt>APPLICATION_ENV</tt> and <tt>APPLICATION_PATH</tt> for you.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/akrabat_db_schema_manager-table-prefix-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Community Review Team for Zend Framework</title>
		<link>http://akrabat.com/zend-framework/community-review-team-for-zend-framework/</link>
		<comments>http://akrabat.com/zend-framework/community-review-team-for-zend-framework/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 06:02:09 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=1041</guid>
		<description><![CDATA[On the ZF mailing lists, there's been a discussion on creating a community team with a follow-up by Matthew. I was going to write up a little about it as I'm one of the volunteers on the team. However, Pádraic beat me to it and I don't think I could have written it any better, [...]]]></description>
			<content:encoded><![CDATA[<p>On the ZF mailing lists, there's been a <a href="http://zend-framework-community.634137.n4.nabble.com/Community-Review-Team-td2242135.html#a2242135">discussion</a> on creating a community team with a <a href="http://zend-framework-community.634137.n4.nabble.com/Follow-up-regarding-community-review-team-td2246260.html#a2246260">follow-up</a> by <a href="http://weierophinney.net/matthew/">Matthew</a>.</p>
<p>I was going to write up a little about it as I'm one of the volunteers on the team. However, <a href="http://blog.astrumfutura.com/">Pádraic</a> beat me to it and I don't think I could have written it any better, so go and <a href="http://blog.astrumfutura.com/archives/429-Zend-Framework-Community-Review-Team.html">read his write-up</a> instead!</p>
<p>The CR Team at the moment is:</p>
<ul>
<li>Rob Allen (Akrabat)</li>
<li>Pádraic Brady (PadraicB)</li>
<li>Steven Brown</li>
<li>Shaun Farrell (farrelley)</li>
<li>Pieter Kokx (kokx)</li>
<li>Dolf Schimmel (Freeaqingme)</li>
<li>Ben Scholzen (DASPRiD)</li>
</ul>
<p>(alphabetical order has always suited me!)</p>
<p>We all accept email and can be found on irc in #zftalk.dev (freenode). Most are on Twitter too. Feel free to contact any of us about anything to do with contributing to Zend Framework and we'll find someone to help you!</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/community-review-team-for-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Akrabat_Db_Schema_Manager: Zend Framework database migrations</title>
		<link>http://akrabat.com/zend-framework/akrabat_db_schema_manager-zend-framework-database-migrations/</link>
		<comments>http://akrabat.com/zend-framework/akrabat_db_schema_manager-zend-framework-database-migrations/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 06:14:47 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=967</guid>
		<description><![CDATA[So, it turns out that I had a need for database migrations within a Zend Framework project that's using Zend_Db_Adapter. Those of you with long memories may remember that I created a proposal along these lines back in 2006. Nearly four years later, I read it again and implemented the core section. One of the [...]]]></description>
			<content:encoded><![CDATA[<p>So, it turns out that I had a need for database migrations within a Zend Framework project that's using <tt>Zend_Db_Adapter</tt>.</p>
<p>Those of you with long memories may remember that I created a <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Db_Schema_Manager+-+Rob+Allen">proposal</a> along these lines back in 2006. Nearly four years later, I read it again and implemented the core section.  One of the comments, by Wil, asked why it's worth bothering with a DDL to create tables, columns, indexes etc. as sooner or later you'll hit a wall and need to use SQL anyway. He has a point. My original idea was that as I routinely use MySQL and MS SQL Server, it would be handy to have cross-database code.  Thinking about it however, there's not that much that isn't cross-database and I could just as easily write the specific SQL for those situations.  </p>
<p>If you remove the DDL bit, then the rest is quite easy, so I wrote it and put it up on github into a project I've egotistically called <a href="http://github.com/akrabat/Akrabat">Akrabat</a>.</p>
<h3>Migration files</h3>
<p>It is intended that any time you want to make a change to your database schema (add columns, tables, indexes, etc), then you create a new <em>migration file</em>. A migration file is stored in <tt>./scripts/migrations</tt> and is named like this <tt>001-CreateUsersTable.php</tt>. The number defines the order that the migrations should be performed as any given migration will make assumptions about the state of the database before it is run. </p>
<p>The migration file contains a class that extends <tt>Akrabat_Db_Schema_AbstractChange</tt> and must contain two methods: <tt>up()</tt> and <tt>down()</tt>. It follows that <tt>up()</tt> is called when implementing the changes in this migration and <tt>down()</tt> is called to put the database back where it was if the change is backed out.</p>
<p><strong>001-CreateUsersTable.php:</strong></p>
<pre class="phpcode"><span style="color: #0000BB">class&nbsp;CreateUsersTable&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Akrabat_Db_Schema_AbstractChange&nbsp;
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">up</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$sql&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"CREATE&nbsp;TABLE&nbsp;IF&nbsp;NOT&nbsp;EXISTS&nbsp;users&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;int(11)&nbsp;NOT&nbsp;NULL&nbsp;AUTO_INCREMENT,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username&nbsp;varchar(50)&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password&nbsp;varchar(75)&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;roles&nbsp;varchar(200)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;'user',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRIMARY&nbsp;KEY&nbsp;(id)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #0000BB">$sql</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data&nbsp;</span><span style="color: #007700">=&nbsp;array();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #DD0000">'admin'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'password'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #0000BB">sha1</span><span style="color: #007700">(</span><span style="color: #DD0000">'password'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'roles'</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #DD0000">'user,admin'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">insert</span><span style="color: #007700">(</span><span style="color: #DD0000">'users'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">down</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$sql&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"DROP&nbsp;TABLE&nbsp;IF&nbsp;EXISTS&nbsp;users"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_db</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #0000BB">$sql</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</span>
</span></code></pre>
<p>As you can see, this code will create a database table called users and then insert the first user. The backing out code (<tt>down()</tt>) just drops the table. As you can see, easy enough and uses <tt>Zend_Db_Adater</tt> so the database calls should be familiar.</p>
<p>For this to work, we need to store the current version of the schema within the database. This is done using a table called <tt>schema_version</tt> which contains just one column, <tt>version</tt>, and one row holding the current version number. <tt>Akrabat_Db_Schema_Manager</tt> will create this table if it does not exist.</p>
<h3>Akrabat_Db_Schema_Manager</h3>
<p>This is the class that does the work. It's based on the skeleton on the proposal and the code is <a href="http://github.com/akrabat/Akrabat/blob/master/Db/Schema/Manager.php">here</a>. There are two public methods in <tt>Akrabat_Db_Schema_Manager</tt> :</p>
<ul>
<li><tt>getCurrentSchemaVersion()</tt></li>
<li><tt>updateTo($version)< </tt></tt></li>
</ul>
<p>In order to operate, <tt>Akrabat_Db_Schema_Manager</tt> needs the directory holding the migration files and a database adapter, so these are passed in via the constructor. The operation of <tt>updateTo()</tt> is fairly simple:</p>
<ol>
<li>Find and order migration files from current version to target version</li>
<li>Iterate over migration files and call <tt>up()</tt> or <tt>down()</tt> as appropriate</li>
<li>Update the current version number in the database</li>
</ol>
<p>Obviously, <tt>getCurrentSchemaVersion()</tt> simply queries the database for the current version number.</p>
<h3>Command line</h3>
<p>To actually run the schema manager, we hook into <tt>Zend_Tool</tt> so we can use the <tt>zf</tt> command line tool. This means that we need a provider, <a href="http://github.com/akrabat/Akrabat/blob/master/Tool/DatabaseSchemaProvider.php"><tt>Akrabat_Tool_DatabaseSchemaProvider</tt></a>. A provider is used by Zend_Tool to provide functionality for <tt>zf</tt>. We create a public method for each operation we want to be available at the command line:</p>
<ul>
<li><tt>updateTo($version, $env='development', $dir='./scripts/migrations')</tt></li>
<li><tt>update($env='development', $dir='./scripts/migrations')</tt></li>
<li><tt>current($env='development', $dir='./scripts/migrations')</tt></li>
</ul>
<p>The <tt>update()</tt> method is simply an alias to <tt>updateTo()</tt> that ensures that you update to the latest migration script that you have.</p>
<p>They are used like this:</p>
<pre style="margin-left: 30px;">
$ zf current database-schema
Current schema version is 0

$ zf update database-schema
Schema updated to version 2

$ zf current database-schema
Current schema version is 2
</pre>
<p>The <tt>update-to</tt> operation allows you to roll-back also:</p>
<pre style="margin-left: 30px;">$ zf current database-schema
Current schema version is 2

$ zf update-to database-schema 1
Schema updated to version 1

$ zf current database-schema
Current schema version is 1</pre>
<p>It turns out that adding a new provider to Zend_Tool requires a little bit of work. <a href="http://ralphschindler.com/">Ralph Schindler</a> is the man who writes it all and <a href="http://blog.calevans.com">Cal Evans</a> is the ZF command line guru that writes it up in a way I can understand. A quick search of his blog helped me work this out. Thanks Cal! </p>
<p>These are the steps that you need to do:</p>
<ol>
<li>At the command line, run <tt>zf --setup storage-directory</tt><br />
This creates a folder for storing Zend_Tool configuration files. Make a note of which directory it has created.</li>
<li>Run <tt>zf --setup config-file</tt><br />
This creates <tt>zf.ini</tt> in your storage directory.</li>
<li>Edit <tt>zf.ini</tt> and change the <tt>php.include_path</tt> path so that it includes the full path to Akrabat/library in addition to the path to Zend Framework.For my installation, I have placed both Zend Framework and the Akrabat library in /usr/local/include, so I have:
<pre class="phpcode"><span style="color: #0000BB">php</span><span style="color: #007700">.</span><span style="color: #0000BB">include_path&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"/usr/local/include/zend-framework/library:/usr/local/include/Akrabat/library/"</span>
</span></code></pre>
</li>
<li>Finally, we need to tell Zend_Tool about our new provider. This is done using the <tt>basicloader.classes</tt> key in <tt>zf.ini</tt>. So add:
<pre class="phpcode"><span style="color: #0000BB">basicloader</span><span style="color: #007700">.</span><span style="color: #0000BB">classes.0&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"Akrabat_Tool_DatabaseSchemaProvider"</span>
</span></code></pre>
</li>
</ol>
<p>Once you've done that (and installed <a href="http://github.com/akrabat/Akrabat/"><tt>Akrabat</tt></a> into /usr/local/include or wherever), then you should now be able to run <tt>$ zf ? database-schema</tt> and get a result:<br />
<img src="http://akrabat.com/wp-content/uploads/2010-03-Screen-shot-2010-03-28-at-11.18.13.png" alt="Screen shot 2010-03-28 at 11.18.13.png" border="0" width="714" height="275" /><br />
Everything is now in place.  All you need to do is create a <tt>script/migrations</tt> directory and populate it with migration scripts and you're good to go!</p>
<p>If you come across any bugs, please report any bugs you find (preferably with the fix!)</p>
<p>Update: <a href="/zend-framework/akrabat_db_schema_manager-table-prefix-support/">Table prefixes are now supported</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/akrabat_db_schema_manager-zend-framework-database-migrations/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Zend Framework, IIS and 500 errors</title>
		<link>http://akrabat.com/zend-framework/zend-framework-iis-and-500-errors/</link>
		<comments>http://akrabat.com/zend-framework/zend-framework-iis-and-500-errors/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 10:42:17 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=954</guid>
		<description><![CDATA[One of the dangers of frameworks in general is that you forget that they do lots of handy things for you. Consider Zend Framework's default error controller: &#160;&#160;&#160;public&#160;function&#160;errorAction() &#160;&#160;&#160;&#160;{ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$errors&#160;=&#160;$this-&#62;_getParam('error_handler'); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;switch&#160;($errors-&#62;type)&#160;{ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case&#160;Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case&#160;Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case&#160;Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;404&#160;error&#160;--&#160;controller&#160;or&#160;action&#160;not&#160;found &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this-&#62;getResponse()-&#62;setHttpResponseCode(404); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this-&#62;view-&#62;message&#160;=&#160;'Page&#160;not&#160;found'; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;default: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;application&#160;error &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this-&#62;getResponse()-&#62;setHttpResponseCode(500); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this-&#62;view-&#62;message&#160;=&#160;'Application&#160;error'; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;Log&#160;exception,&#160;if&#160;logger&#160;available &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if&#160;($log&#160;=&#160;$this-&#62;getLog())&#160;{ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$log-&#62;crit($this-&#62;view-&#62;message,&#160;$errors-&#62;exception); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;conditionally&#160;display&#160;exceptions &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if&#160;($this-&#62;getInvokeArg('displayExceptions')&#160;==&#160;true)&#160;{ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this-&#62;view-&#62;exception&#160;=&#160;$errors-&#62;exception; [...]]]></description>
			<content:encoded><![CDATA[<p>One of the dangers of frameworks in general is that you forget that they do lots of handy things for you.</p>
<p>Consider Zend Framework's default error controller:</p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">errorAction</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$errors&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_getParam</span><span style="color: #007700">(</span><span style="color: #DD0000">'error_handler'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(</span><span style="color: #0000BB">$errors</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">type</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">Zend_Controller_Plugin_ErrorHandler</span><span style="color: #007700">::</span><span style="color: #0000BB">EXCEPTION_NO_ROUTE</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">Zend_Controller_Plugin_ErrorHandler</span><span style="color: #007700">::</span><span style="color: #0000BB">EXCEPTION_NO_CONTROLLER</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">Zend_Controller_Plugin_ErrorHandler</span><span style="color: #007700">::</span><span style="color: #0000BB">EXCEPTION_NO_ACTION</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;404&nbsp;error&nbsp;--&nbsp;controller&nbsp;or&nbsp;action&nbsp;not&nbsp;found
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getResponse</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">setHttpResponseCode</span><span style="color: #007700">(</span><span style="color: #0000BB">404</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">message&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'Page&nbsp;not&nbsp;found'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;application&nbsp;error
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getResponse</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">setHttpResponseCode</span><span style="color: #007700">(</span><span style="color: #0000BB">500</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">message&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'Application&nbsp;error'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Log&nbsp;exception,&nbsp;if&nbsp;logger&nbsp;available
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">$log&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getLog</span><span style="color: #007700">())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$log</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">crit</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">message</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$errors</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exception</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;conditionally&nbsp;display&nbsp;exceptions
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getInvokeArg</span><span style="color: #007700">(</span><span style="color: #DD0000">'displayExceptions'</span><span style="color: #007700">)&nbsp;==&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exception&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$errors</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exception</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">request&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$errors</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">request</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}
</span>
</span></code></pre>
<p>The error handler in ZF will catch any exceptions and route them to the error action in the error controller. This then sets the correct HTTP response code, logs the error and optionally displays it if a config setting is set.</p>
<p>Obviously on our production boxes, we don't display the exceptions, but we do on our local development machines.</p>
<p>IIS has the concept of custom error pages that it displays when the app returns a 4xx or 5xx status code:<br />
<img src="http://akrabat.com/wp-content/uploads/2010-03-Screen-shot-2010-03-04-at-10.07.41.png" alt="Screen shot 2010-03-04 at 10.07.41.png" border="0" width="627" height="334" /></p>
<p>There is also some settings for this page:<br />
<img src="http://akrabat.com/wp-content/uploads/2010-03-Screen-shot-2010-03-04-at-10.28.06.png" alt="Screen shot 2010-03-04 at 10.28.06.png" border="0" width="398" height="367" /></p>
<p>By default this is set so that if you access the site using the <em>localhost</em> domain, then you'll get the ZF error page and if you access the site remotely then you'll get the IIS custom page and won't see the error.</p>
<p>If, like me, you are developing with your IIS in a VM and using the host OS's browser and developer tools, then you need to change the setting to "Detailed":</p>
<p><img src="http://akrabat.com/wp-content/uploads/2010-03-detailed-iis-errors.png" alt="detailed-iis-errors.png" border="0" width="403" height="369" /></p>
<p>Now you can see your exceptions and it doesn't look like PHP has crashed :)</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/zend-framework-iis-and-500-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework Tutorial for ZF 1.10</title>
		<link>http://akrabat.com/zend-framework/zend-framework-tutorial-for-zf-1-10/</link>
		<comments>http://akrabat.com/zend-framework/zend-framework-tutorial-for-zf-1-10/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 21:52:07 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=928</guid>
		<description><![CDATA[Zend Framework 1.10, was released a week or so ago. As a result, I have updated my Zend Framework tutorial so that it is completely current. The main change I made was to remove the _init methods in the Bootstrap as they are no longer needed. I also take advantage of the new features of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://framework.zend.com/">Zend Framework 1.10</a>, was released a week or so ago.</p>
<p>As a result, I have updated my <a href="http://akrabat.com/zend-framework-tutorial">Zend Framework tutorial</a> so that it is completely current. The main change I made was to remove the _init methods in the Bootstrap as they are no longer needed. I also take advantage of the new features of the <tt>zf</tt> tool to enable layouts and create forms. It's a shame that it gets the class name of the form wrong though!</p>
<p><img src="http://akrabat.com/wp-content/uploads/zf-tutorial_17-300x240.png" alt="Screen short of Zend Framework tutorial" title="Listing albums in Zend Framework tutorial" width="300" height="240" class="alignright" /></p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/zend-framework-tutorial-for-zf-1-10/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Determining if a ZF view helper exists</title>
		<link>http://akrabat.com/zend-framework/determining-if-a-zf-view-helper-exists/</link>
		<comments>http://akrabat.com/zend-framework/determining-if-a-zf-view-helper-exists/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 16:38:14 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=900</guid>
		<description><![CDATA[This is another one of those posts that exists as a record for me so I can find it again if i need it! If you need to know whether a view helper exists before you call it, one way is to write a simple view helper to tell you: class&#160;App_View_Helper_HelperExists&#160;extends&#160;Zend_View_Helper_Abstract { &#160;&#160;&#160;&#160;function&#160;helperExists($name)&#160;{ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return&#160;(bool)$this-&#62;view-&#62;getPluginLoader('helper')-&#62;load($name,&#160;false); &#160;&#160;&#160;&#160;} [...]]]></description>
			<content:encoded><![CDATA[<p>This is another one of those posts that exists as a record for me so I can find it again if i need it!</p>
<p>If you need to know whether a view helper exists before you call it, one way is to write a simple view helper to tell you:</p>
<pre class="phpcode"><span style="color: #0000BB">
</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">App_View_Helper_HelperExists&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_View_Helper_Abstract
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">helperExists</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(bool)</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getPluginLoader</span><span style="color: #007700">(</span><span style="color: #DD0000">'helper'</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">load</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">false</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</span>
</span></code></pre>
<p>You can then use it in a view scripts like this:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">helperExists</span><span style="color: #007700">(</span><span style="color: #DD0000">'doMagic'</span><span style="color: #007700">))&nbsp;{&nbsp;echo&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">doMagic</span><span style="color: #007700">();&nbsp;}&nbsp;</span><span style="color: #0000BB">?&gt;
</span>
</span></code></pre>
<p>As Jeremy mentions in the comments, this code came out of a discussion on the <a href="http://www.phpnw.org.uk/">PHPNW</a> IRC channel #phpnw</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/determining-if-a-zf-view-helper-exists/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Custom Zend_Application Resources</title>
		<link>http://akrabat.com/zend-framework/custom-zend_application-resources/</link>
		<comments>http://akrabat.com/zend-framework/custom-zend_application-resources/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 07:12:57 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=889</guid>
		<description><![CDATA[Sooner or later, you want to leverage Zend_Application better by creating your own resource plugins. This lets you reuse your initialisation work in multiple application that much easier and keeps your Boostrap class that much shorter! In my case, I wanted to create a resource for CouchDb that checked that the database was created and [...]]]></description>
			<content:encoded><![CDATA[<p>Sooner or later, you want to leverage <a href="http://weierophinney.net/matthew/archives/230-Quick-Start-to-Zend_Application_Bootstrap.html"><tt>Zend_Application</tt></a> better by creating your own resource plugins. This lets you reuse your initialisation work in multiple application that much easier and keeps your Boostrap class that much shorter!</p>
<p>In my case, I wanted to create a resource for <a href="http://couchdb.apache.org/">CouchDb</a> that checked that the database was created and if not, create it.</p>
<p>Creating your own plugin is easy enough. The obvious place is library/App/Application/Resource and a typical resource would look like this:</p>
<pre class="phpcode"><span style="color: #0000BB">
</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">App_Application_Resource_Couchdb&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_Application_Resource_ResourceAbstract
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defined&nbsp;by&nbsp;Zend_Application_Resource_Resource
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;Phly_Couch|null
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">init</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;do&nbsp;stuff&nbsp;here&nbsp;to&nbsp;init&nbsp;CouchDB
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$options&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getOptions</span><span style="color: #007700">();&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;$options&nbsp;contains&nbsp;everything&nbsp;under&nbsp;'resources.couchdb'&nbsp;in&nbsp;application.ini
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">}
}
</span>
</span></code></pre>
<p>You then need to tell Zend_Application about your new plugins. This is done with this line in application.ini:</p>
<pre class="phpcode"><span style="color: #0000BB">
pluginPaths</span><span style="color: #007700">.</span><span style="color: #0000BB">App_Application_Resource_&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"App/Application/Resource"
</span>
</span></code></pre>
<p>You can now have as many resource plugins as you like within the <tt>App_Application_Resource_</tt> class-space.</p>
<p>Also, Matthew Weier O'Phinney has also written an article on <a href="http://www.weierophinney.net/matthew/archives/230-Quick-Start-to-Zend_Application_Bootstrap.html">Zend_Application</a> which you should read too.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/zend-framework/custom-zend_application-resources/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
