<?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>Jesus Blog &#187; Coding Tips and Tutorials</title>
	<atom:link href="http://jesus-blog.com/category/coding-tips-and-tutorials/feed" rel="self" type="application/rss+xml" />
	<link>http://jesus-blog.com</link>
	<description>Jesus-blog.com</description>
	<lastBuildDate>Thu, 13 Jan 2011 19:07:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Buddypress: Preventing private message spam</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/buddypress-preventing-private-message-spam.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/buddypress-preventing-private-message-spam.html#comments</comments>
		<pubDate>Tue, 16 Mar 2010 17:58:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=122</guid>
		<description><![CDATA[A guide to preventing private message spam within BuddyPress]]></description>
			<content:encoded><![CDATA[<p>One of the sites I work on has recently been suffering private message spam, ranging from fake market research to child porn. Needless to say this needed solving, and since I couldn&#8217;t disable private messaging, there was only one option, and that was to only allow Buddypress friends to send private messages to each other.</p>
<p>The is a &#8220;bug&#8221; in Buddypress that allows any user to send a private message to any other user simply by entering the username in the &#8220;to&#8221; field of the compose message form. This isn&#8217;t an obvious flaw since the ajax function that shows the available users as you type in the box does indeed only show your friends.</p>
<p>I looked all over the web for a solution, but the only one I found, a hack at that, wasn&#8217;t compatible with the version of BuddyPress I&#8217;m using. There was only one thing for it, and that was to roll my sleeves up and sort it myself.</p>
<p>The solution I came up with, while not the most elegant, works.</p>
<p>This may vary slightly depending on your version of BuddyPress, so instead of offering line numbers, I&#8217;ll explain where in the code you need to look. Don&#8217;t worry, you only have to edit a single file with just a few lines.</p>
<p>The file you want is /wp-content/plugins/buddypress/bp-messages/bp-messages-classes.php</p>
<p>Annoyingly, because I hate doing this, there are a few classes in the same file, so you need to find &#8220;class BP_Messages_Message&#8221;</p>
<p>In there is the method, &#8220;send&#8221;.</p>
<p>Quite near to the top of that method is the line &#8220;if ( $this-&gt;thread_id ) {&#8221;</p>
<p>That is instructing the code to take a different path is the &#8220;message&#8221; already exists, i.e., somebody is replying to an existing thread. We don&#8217;t want to change this, so look for the else component of that if statement; it should be marked with the comment &#8220;// Create a new thread.&#8221;</p>
<p>Directly under that, paste this code.<br />
<code><br />
foreach ($this->recipients as $recipientName)<br />
		{<br />
			$recipientId = get_user_id_from_string( $recipientName );<br />
			if (!friends_check_friendship($bp->loggedin_user->id,$recipientId))<br />
			{<br />
				return false;<br />
			}<br />
		}<br />
</code></p>
<p>Save the file, upload it to your site, and you&#8217;re done. Users can now only send a message to their friends.</p>
<p>The only downside to this is that the failure message isn&#8217;t ever so elegant. Rather than giving the reason for the failure, it simply says that sending the message failed. This shouldn&#8217;t be a problem for normal users though, if anything it just makes the spammers life a little more confusing, which I&#8217;m sure we can all agree is a good thing.</p>
<p>So there you go, that&#8217;s how to prevent spam private messaging within BuddyPress.</p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/buddypress-preventing-private-message-spam.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Slow Query Log with WAMP</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/mysql-slow-query-log-with-wamp.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/mysql-slow-query-log-with-wamp.html#comments</comments>
		<pubDate>Tue, 02 Mar 2010 11:03:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=120</guid>
		<description><![CDATA[Although in hindsight this is DEAD easy, I&#8217;ve just had a bit of a hard time finding out how to do it, so I thought I&#8217;d make a quick post which will hopefully get indexed by Google and save some other folk the hard time I had. Thoughtful, eh.
So, to enable the slow query log [...]]]></description>
			<content:encoded><![CDATA[<p>Although in hindsight this is DEAD easy, I&#8217;ve just had a bit of a hard time finding out how to do it, so I thought I&#8217;d make a quick post which will hopefully get indexed by Google and save some other folk the hard time I had. Thoughtful, eh.</p>
<p>So, to enable the slow query log in WAMP is as simple as adding</p>
<p>log-slow-queries=PATH to your config file.</p>
<p>The config file is located in your wamp installation directory, under bin/mysql/mysql.version/my.ini</p>
<p>In there you will find an entry for standard logs, which will look something like <em>log-error=c:/wamp/logs/mysql.log</em></p>
<p>Add the slow query flag, and change the log file name to something like <em>log-slow-queries=c:/wamp/logs/mysqlslow.log</em></p>
<p>Restart wamp, and you&#8217;re done.</p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/mysql-slow-query-log-with-wamp.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wordpress is shit</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/wordpress-is.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/wordpress-is.html#comments</comments>
		<pubDate>Wed, 30 Sep 2009 17:20:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>
		<category><![CDATA[Opinions]]></category>
		<category><![CDATA[bad php code]]></category>
		<category><![CDATA[coding standards]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=106</guid>
		<description><![CDATA[This post goes beyond my opinion of Wordpress though, I want it to highlight a more fundimental problem with PHP development. People just don't seem to be very good at it, and it's giving PHP a bad name.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finally cracked, I can take it no more. I&#8217;m just going to have to blog about it.</p>
<p>Before I quit the world and disappeared sailing for 4 months this summer, I wrote a post titled &#8220;<a title="Drupal is shit" href="/opinions/drupal-is-shit.html">Drupal is shit</a>&#8220;, in it a ranted about how I couldn&#8217;t stand Drupal, and that I use either Wordpress or an MVC framework in its place. That post drew quite a bit of attention this summer after <a title="Webschuur" href="http://www.webschuur.com/publications/blogs/2009-08-04-reply_on_quotdrupal_is_shitquot_by">Webschuur</a> blogged a reply to my original post.</p>
<p>The time has now come for me to bitch about the very product I defended in that post; Wordpress.</p>
<p>Here, are you ready for it, I&#8217;m going to say it. Wordpress is shit!</p>
<p>Ok, it&#8217;s not on the face of things, I happen to love Wordpress, but I&#8217;ve been working on a contract rececntly which involves some fairly in depth Wordpress development. I&#8217;ve had to peer under its skirt and what I&#8217;ve found was not something you&#8217;d want to tell your friends about.</p>
<p>This post goes beyond my opinion of Wordpress though, I want it to highlight a more fundamental problem with PHP development. People just don&#8217;t seem to be very good at it, and it&#8217;s giving PHP a bad name.</p>
<p>I got a bit of a telling off in the Drupal thread for not giving examples of what I considered to be poor code, so I&#8217;m not going to allow that to happen again. Let&#8217;s take a look at a random snippet of Wordpress code.<br />
<code> </code></p>
<p>Can anybody tell me what that does? I doubt it, and that makes for bad code from the off. Thankfully, despite the atrocious function naming and cringe inducing syntax, it is doc tagged, so a mouse over in eclipse tell me that the_post() &#8220;iterates the post index in the loop&#8221;. I&#8217;m still not entirely sure what&#8217;s going on here, but I&#8217;ve got a better idea.</p>
<p><!--adsense--></p>
<p>Let&#8217;s dig a bit deeper, F3 in Eclipse open the declaration.<br />
<code><br />
/**<br />
* Iterate the post index in the loop.<br />
*<br />
* @see WP_Query::the_post()<br />
* @since 1.5.0<br />
* @uses $wp_query<br />
*/<br />
function the_post() {<br />
global $wp_query;</code></p>
<p>$wp_query-&gt;the_post();<br />
}</p>
<p>This hasn&#8217;t helped much, I still have no idea what&#8217;s going on, but it has invoked a sub rant about Globals.</p>
<p>Why do people use them? It&#8217;s such a dumb idea. You have no control over that variable, no idea where it comes from, and no idea who has fettled with it before it&#8217;s used in this function.</p>
<p>Now, at this point, I&#8217;d open declaration on the the_post() method, but I can&#8217;t since Eclipse has no idea what $wp_query is. I can&#8217;t even find it without a search through the code because Wordpress doesn&#8217;t do, is put classes in individual files. They are just mixed up where ever in an orgy of mouldy spaghetti code. Again, this is bad because it makes a developers life hard for no benefit.</p>
<p>Searching for &#8220;WP_Query&#8221; was of little benefit since it&#8217;s littered throughout the code. I had to try another tactic, let&#8217;s find the function itself with a search for &#8220;n the_post&#8221;.</p>
<p>Aha, found it in wp-includes/query.php which isn&#8217;t too bad I suppose, although I would have preferred the file be called the same as the class within it. wp_query.php. Makes it nice and obvious then doesn&#8217;t it.</p>
<p>Opening the file shows another horror story; a huge mix of procedural and OO code. I can understand why this may have happened, it was probably because they are trying to port it to OO yet retain backwards compatibility, at least I hope that was the reason, but this is just a bloody confusing mess.</p>
<p>Anyway, onward we go. Let&#8217;s open up the code for the_post() and see what&#8217;s going on.<br />
<code><br />
/**<br />
* Sets up the current post.<br />
*<br />
* Retrieves the next post, sets up the post, sets the 'in the loop'<br />
* property to true.<br />
*<br />
* @since 1.5.0<br />
* @access public<br />
* @uses $post<br />
* @uses do_action() Calls 'loop_start' if loop has just started<br />
*/<br />
function the_post() {<br />
global $post;<br />
$this-&gt;in_the_loop = true;<br />
$post = $this-&gt;next_post();<br />
setup_postdata($post);</code></p>
<p>if ( $this-&gt;current_post == 0 ) // loop has just started<br />
do_action(&#8216;loop_start&#8217;);<br />
}</p>
<p>I think this can be summarised with a simple, yet effective <strong>WTF</strong>!!!!???!!!</p>
<p>I don&#8217;t think I can bear to dig any deeper. What is wrong with using an iterator? There are well established design patterns for this sort of thing.</p>
<p>The bottom line is, Wordpress is like so many projects out there, a complete kludge of crap code. I will still defend Wordpress for being a good product, I can make it do things quickly (mostly) and for standard use it&#8217;s nice and easy to use, but my god do I pity you if you have to go beyond that.</p>
<p>HTML is also well and truly mixed in with the core code, which means to apply a specific design, you may well have to start hacking around within the functions of a plugin. This means that what should be a modular website with themes, quickly turns into a customised hunk of code that you can&#8217;t upgrade any more through fear of braking it all.</p>
<p>The above example reflects the vast majority of PHP code I&#8217;ve worked with, and it&#8217;s sadly a rare thing to stumble across well written and designed PHP software. The unshakable attachment to it&#8217;s roots as a hobiest language are all too apparent.</p>
<p>Come on folks, we can do better than this. When you turn up for work tomorrow, have a think about replacing those globals in your code with a static class or two, but more importantly, find out why you should. The PHP world will thank you for it, I promise.</p>
<p><!--adsense--></p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/wordpress-is.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Zend framework on 1and1 hosting.</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-on-1and1-hosting.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-on-1and1-hosting.html#comments</comments>
		<pubDate>Fri, 20 Feb 2009 12:38:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>
		<category><![CDATA[1and1 hosting]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=103</guid>
		<description><![CDATA[How to get Zend Framework running on 1and1 hosting.]]></description>
			<content:encoded><![CDATA[<p>I had a bit of a hard time getting Zend Framework to run on my 1&amp;1 hosting. It was all down to the .htaccess file in the end. The default htaccess configuration in the ZF getting started guide just doesn&#8217;t work, and neither did all the other posts I could fine on the subject around the internet, however, I&#8217;ve finally cracked it.</p>
<p>Presuming you&#8217;ve put your ZF index file in the webroot, here&#8217;s what the 1and1 htaccess file should look like.</p>
<p><code><br />
AddHandler x-mapp-php5 .php<br />
AddType x-mapp-php5 .php<br />
Options -MultiViews<br />
<ifModule mod_rewrite.c><br />
RewriteEngine On<br />
RewriteBase /<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule !\.(txt|swf|js|ico|gif|jpg|png|css|xml)$ /<br />
</ifModule><br />
</code></p>
<p><strong>Note:</strong> The same file will not work on my local dev machine, which is running only PHP5. You will need to comment out the first two lines (AddHandler, AddType) to get it to run on a stadard PHP5 installation.<br />
<!--adsense--></p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-on-1and1-hosting.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>TinyMCE not loading in Zend Framework</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/tinymce-not-loading-in-zend-framework.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/tinymce-not-loading-in-zend-framework.html#comments</comments>
		<pubDate>Fri, 20 Feb 2009 12:32:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[tinyMCE]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=101</guid>
		<description><![CDATA[I was having a bit of a problem with TinyMCE not loading in Zend Framework (ZF). It turns out the .htaccess file was not configured correctly. It was redirecting .js to the index bootstrap and causing the page to fail to load.
The solution was the htaccess file as so&#8230;

Options -MultiViews
RewriteEngine On
RewriteBase /website
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} [...]]]></description>
			<content:encoded><![CDATA[<p>I was having a bit of a problem with TinyMCE not loading in Zend Framework (ZF). It turns out the .htaccess file was not configured correctly. It was redirecting .js to the index bootstrap and causing the page to fail to load.</p>
<p>The solution was the htaccess file as so&#8230;</p>
<p><code><br />
Options -MultiViews</code></p>
<p>RewriteEngine On<br />
RewriteBase /website<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule !\.(txt|swf|js|ico|gif|jpg|png|css|xml)$ /website/</p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/tinymce-not-loading-in-zend-framework.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework multi page forms</title>
		<link>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-multi-page-forms.html</link>
		<comments>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-multi-page-forms.html#comments</comments>
		<pubDate>Wed, 01 Oct 2008 12:38:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding Tips and Tutorials]]></category>
		<category><![CDATA[Nathan Whitworth]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[zend framework multipage forms]]></category>

		<guid isPermaLink="false">http://blog.nathanwhitworth.co.uk/?p=47</guid>
		<description><![CDATA[I&#8217;ve started using Zend Framework for a project I&#8217;m under taking here at TradeDoubler. I&#8217;m building a new part of Searchware that is essentially standalone, so figured that this is a great oportunity to push for framework support. Better form validation, less scope for creating errors in trivial donkey work coding because it&#8217;s already done [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve started using Zend Framework for a project I&#8217;m under taking here at TradeDoubler. I&#8217;m building a new part of Searchware that is essentially standalone, so figured that this is a great oportunity to push for framework support. Better form validation, less scope for creating errors in trivial donkey work coding because it&#8217;s already done for you, and ultimately a better experience for the user.</p>
<p>The problem I soon discovered with ZF, is that the documentation is not as good as I would of hoped. Their introductory videos are absolutely amazing, but when it comes to getting a real project started, they leave you feeling a bit left out in the cold.</p>
<p><!--adsense--></p>
<p><strong>Multi Page Forms</strong></p>
<p>A good example of this, and something I&#8217;ve just been working on, is multi page forms. Zend Form is a great start and will go places, but right now, I think it&#8217;s not quite there. I discovered that subforms are the recommended way to implement multi page forms, but the example in the documentation again doesn&#8217;t quite explain how to do it, it just points you in a direction and expects you to figure the rest out for yourself. All very good, but some of us are fairly busy and would rather just read a comprehensive example.</p>
<p><strong>A comprehensive example <img src='http://jesus-blog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong></p>
<p>This is how I decided to make a multi page form based on Zend Form subforms. I don&#8217;t know if this is the best way of doing it, and I am a complete newbie to ZF, but since I couldn&#8217;t find any other examples, and this does work, I&#8217;ll just have to presume it is until I&#8217;m corrected by one of you kind readers :p. This example will show you how to setup the required classes, build a simple form, validate, and then store the information and make it available to subsequent forms for decision making.</p>
<p><strong>Note: </strong>This is not a beginners guide to Zend Framework or MVC. If you&#8217;re not quite sure how ZF works, or what MVC is, please check out the <a href="http://framework.zend.com/docs/screencasts" target="_blank">introductory vids</a> on the Zend site. They are very good.</p>
<p>So, to kick things off we&#8217;re going to need to load up all the classes required for our forms. To do this, add the following lines to your boot strap file.</p>
<pre><code>
DEFINE('APPLICATION_PATH','/data/web/yourApplication');

Zend_Loader::loadClass("Zend_Form");
Zend_Loader::loadClass("Zend_Session");
Zend_Loader::loadClass("Zend_Session_Namespace");

// And any validation classes you will be using, for example
Zend_Loader::loadClass("Zend_Validate_NotEmpty");
</code></pre>
<p>This will set up our bootstrap file with everything we need to build a form, so the next job is editing your controller class. Add the following methods into your controller. They are used to store and read validated form values, but more on that later.</p>
<pre><code>
	private function storeFormValues(Zend_Form $form)
	{
		$formSession = new Zend_Session_Namespace('yourAppForm');

		foreach ($form-&gt;getValues() as $key =&gt; $value)
		{
			$formSession-&gt;$key = $value;
		}
	}

	private function getFormValues()
	{
		$formSession = new Zend_Session_Namespace('yourAppForm');

		$data = array();
		foreach ($formSession-&gt;getIterator() as $key =&gt; $value)
		{
			$data[$key] = $value;
		}
		return $data;
	}</code></pre>
<p>You will also need to add the following method in your controller class.</p>
<pre><code>
	 protected function getForm($formName)
	 {
	 	// you will need to edit this later, but leave it for now.
	 	require_once APPLICATION_PATH . '/forms/parentForm.php';

	 	$mainForm = new Form_ParentForm($this-&gt;getFormValues());

	 	if ($formName == 'main')
	 	{
	 		$form = $mainForm;
	 	}
	 	else
	 	{
	 		$form = $mainForm-&gt;getSubForm($formName);
	 		$form-&gt;addElement('hidden','currentFormStage',array('value' =&gt; $formName));
	 	}

	 	return $form;
	 }
</code></pre>
<p>So, I&#8217;ll take a little time to explain that one since it&#8217;s not instantly obvious.</p>
<p>First off</p>
<pre><code>require_once APPLICATION_PATH . '/forms/parentForm.php';</code></pre>
<p>is the path to your form classes. I&#8217;ll explain how to create those later but for now, decide where you will want to store your forms, and point this there. Remember the constant APPLICATION_PATH was set in the bootstrap file.</p>
<p>The next line is</p>
<pre><code>$mainForm = new Form_AddAccount($this-&gt;getFormValues());</code></pre>
<p>This instantiates our parent form and passes to it any form data we have in our session.</p>
<p>The next part is</p>
<pre><code>if ($formName == 'main')
{
	$form = $mainForm;
}</code></pre>
<p>This is used later on in the controller to check whether the entire form (i.e. all of it&#8217;s sub pages are validated). The controller asks for the sub form name, but if this is &#8216;main&#8217;, then the parent class is sent back.</p>
<p><strong>Creating our forms</strong><br />
So far we&#8217;ve built the required scaffolding for our multi page form that will be used by the controller. The next step is to create the forms themselves. As I&#8217;ve already mentioned the overall multi page form consists of a parent container form, and a collection of sub forms. For the sake of making it easy to read, I&#8217;m going to use VERY crude examples of forms, but please consult the Zend Form docs for more details about creating various form elements. That part of things is fairly well documented.</p>
<p>The entire parent class looks like this&#8230;</p>
<pre>
<code>
class Form_ParentForm extends Zend_Form
{
	private $formValues;

	public function __construct($formValues)
	{
		$this->formValues = $formValues;
		parent::__construct();
	}

	public function getFormValue($name)
	{

		if (isset($this->formValues[$name]))
		{
			return $this->formValues[$name];
		}
		else
		{
			return null;
		}

	}

	public function init()
	{

		$this->setAction('index');
		$this->setMethod('post');

		require_once APPLICATION_PATH . '/forms/SubFormPageOne.php';
		require_once APPLICATION_PATH . '/forms/SubFormPageTwo.php';

		$pageOne = new Form_SubFormPageOne($this);
		$pageTwo = new Form_SubFormPageTwo($this);

		$this->addSubForm($pageOne,'pageOne');
		$this->addSubForm($pageTwo,'pageTwo');

	}

}
</code>
</pre>
<p>The only bit you need to be concerned about editing here is the init() method. Change setAction() and setMethod() as you see fit, but they will probably be ok as they are in most cases.<br />
The next bit, the requires, is important. Remember in the controller class we edited the getForm() method. There was an include path in there that pointed to the parent form. You need to make sure that, obviously, this parent form is saved to the same place. You could put the subforms in other directories, but I don&#8217;t see any benefit of doing so, so I&#8217;d recommend you keep then all bundled together in the same directory.</p>
<p>Once you have included then, you instantiate the subforms (actually, they are instances of Zend_Form and not SubForm, but that is ok), and then pass them to addSubForm. Hopefully this is quite easy to follow so I&#8217;m not going to explain it any further. If you get stuck, please feel free to ask me a question.</p>
<p>So then, our final step in building the forms is to create the sub forms. The subform class looks like this.</p>
<pre>
<code>
class Form_SubFormPageOne extends Zend_Form
{
	private $parentForm;

	public function __construct(Zend_Form $parentForm)
	{
		$this->parentForm = $parentForm;
		parent::__construct();
	}

	public function init()
	{

		// engine dropdown
		$engineSelect = $this->createElement('select','engine');

		$engineSelect->addMultiOption('','Please Choose...');
		$engineSelect->addMultiOption('google','Google');
		$engineSelect->addMultiOption('yahoo','Yahoo');
		$engineSelect->addMultiOption('msn','MSN');

		$engineSelect->setRequired(true);

		$this->addElement($engineSelect);

		// create submit button
		$this->addElement('submit', 'btnNext', array( 'label' => 'Next'));

	}

}
</code>
</pre>
<p>Apart from changing the class name to suit your needs, the only other thing you should need to edit is the init() method. In here you create the form elements, apply validation, decorators and so on. This work in exactly the same way as a single page form, so please consult one of the many Zend Form examples for details on adding elements. As you can see our example form simply gives a dropdown list of search engines and a submit button.</p>
<p><strong>Plugging it all together</strong><br />
So we&#8217;ve got our scaffolding, and we&#8217;ve got our forms. The only thing left to do now is to stick it all together, and this happens in the &#8216;action&#8217; method of the controller. In most cases, and certainly this one, it will be the index action.</p>
<p>This method is a bit longer than the others so rather than me blabbering on here, I&#8217;ll let the comments to the talking. <img src='http://jesus-blog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre>
<code>
public function indexAction()
{
	$request = $this->getRequest();

	// is this a post back, i.e was the form submitted or is it a first visit.
	if ($request->isPost())
	{
		/*
		Get an instance of the current form.
		Remember currentFormStage was appended
		to the form as a hidden field in the getForm method.
		*/
		$form = $this->getForm($_POST['currentFormStage']);

		// does is pass validation?
		if ($form->isValid($_POST))
		{
			// yes, so save the values to our session.
			$this->storeFormValues($form);

			/*
			So, we've just check a subform and it was valid.
			Does this now make our entire form collection valid?
			Let's check by getting in instance of the parent form.
			*/
			if ($this->getForm('main')->isValid($this->getFormValues()))
			{
				/*
				The form is complete, so redirect to the
				finish action (you will need to create this)
				*/
				$this->_redirect("index/finish");
			}

			/*
			A crude but workable method of choosing which form to go to next.
			*/
			switch ($_POST['currentFormStage'])
			{
				case 'pageOne':
					$newForm = 'pageTwo';
					break;
				default:
					$newForm = 'pageOne';
				break;
			}
			/* get an instance of our new form.
			having passed page one, this would be now page two.
			*/
			$form = $this->getForm($newForm);

		}

	}
	else
	{
		/*
		If this is the first time the page is loaded
		i.e. no forms submitted, let's make sure the session is
		empty.
		*/
		$formSession = new Zend_Session_Namespace('yourAppForm');
		$formSession->unsetAll();

		// and then load the first form page.
		$form = $this->getForm('pageOne');
	}

	$this->view->printForm = $form;

}
</code>
</pre>
<p>And there it is, you&#8217;re done. You have a working multi page form in the Zend framework. One final note, the last line $this->view->printForm = $form; is simply to pass the form to the view. The view file for this controller/action, would contain <?= $this->printForm; ?></p>
<p>I hope that helped clear things up, and if anybody has any questions, please feel free to post them.</p>
<p><!--adsense--></p>
]]></content:encoded>
			<wfw:commentRss>http://jesus-blog.com/coding-tips-and-tutorials/zend-framework-multi-page-forms.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

