<?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>Rich&#039;s stuff</title>
	<atom:link href="http://www.richsage.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.richsage.co.uk</link>
	<description>ramblings, musings, web stuff</description>
	<lastBuildDate>Wed, 25 Jan 2012 21:10:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Experimentation with ZeroMQ</title>
		<link>http://www.richsage.co.uk/2012/01/25/experimentation-with-zeromq/</link>
		<comments>http://www.richsage.co.uk/2012/01/25/experimentation-with-zeromq/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 21:10:15 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=222</guid>
		<description><![CDATA[At the weekend I was experimenting with ZeroMQ (0MQ for short here) for handling requests for items in an online shop.  The idea behind it was simple - schedule requests for items to be added to a shopping cart, and don't allow overselling of said stock items.  The legacy code handles requests ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2012%2F01%2F25%2Fexperimentation-with-zeromq%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2012%2F01%2F25%2Fexperimentation-with-zeromq%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>At the weekend I was experimenting with <a href="http://www.zeromq.org/" title="ZeroMQ">ZeroMQ</a> (0MQ for short here) for handling requests for items in an online shop.  The idea behind it was simple &#8211; schedule requests for items to be added to a shopping cart, and don&#8217;t allow overselling of said stock items.  The legacy code handles requests by wrapping in a transaction and checking for the amount of items currently available (sales + in existing carts), then adding/rejecting as appropriate.</p>
<p>If however there is significant traffic, this can result in oversells as the number of items available can be reported the same to more than 1 user.  If both users request the final item, your oversell happens.  I wanted to remove the likelihood of this happening, and so I turned to a queueing system to see how this could make a difference. I&#8217;d seen the video of Ian Barber&#8217;s <a href="http://www.phpconference.co.uk/talk/zeromq-answer">presentation at PHP UK last year</a>, and liked the apparent simplicity of 0MQ coupled with the lightweight in-memory approach so decided to experiment a bit.</p>
<p>After <a href="http://www.zeromq.org/intro:get-the-software">downloading</a> and installing the 0MQ library, and the <a href="http://www.zeromq.org/bindings:php">pecl extension</a> for PHP, I was all set to go.</p>
<p>The idea seemed simple:</p>
<ul>
<li>Take all requests for items, and pop them into a queue</li>
<li>If a response from the queue isn&#8217;t available immediately, the customer should be shown a page which polls periodically for the result.</li>
<li>When the result is available, redirect the customer to their cart (success) or back to the item page (failure)</li>
</ul>
<p>The <a href="http://zguide.zeromq.org/page:all">0MQ documentation</a> at first seemed thorough, but reading through I realised it was a bit too verbose for my liking. I can appreciate the use of metaphors and friendly language, but it seemed to hinder understanding of what 0MQ could offer, coupled with everything being on the same page.  Slightly overwhelming!  In contrast, RabbitMQ&#8217;s <a href="http://www.rabbitmq.com/getstarted.html">tutorial pages</a> seemed to be a lot clearer.  For a developer new to queueing system, this was definitely a win for RabbitMQ &#8211; a case of which-image-represents-best-what-I-want *click* etc.  However, I stuck with 0MQ for now for the reasons outlined above.</p>
<p>I settled on the Push-Pull methodology, &#8220;<a href="http://zguide.zeromq.org/page:all#toc9">Divide and Conquer</a>&#8221; in the 0MQ docs.  This would satisfy the requirements above of being able to dump a request into a queue and periodically (via another mechanism) check for a result.  I&#8217;ve shamelessly ripped off the accompanying image from their docs here in order to illustrate my point :-)</p>
<p><a href="http://www.richsage.co.uk/wp-content/uploads/2012/01/fig5.png"><img src="http://www.richsage.co.uk/wp-content/uploads/2012/01/fig5.png" alt="" title="0MQ&#039;s Push-Pull model" width="456" height="582" class="aligncenter size-full wp-image-231" /></a></p>
<p>In the above image, the part labelled &#8220;Ventilator&#8221; can be equated to the user requesting a quantity of items to add to a shopping cart, and my queue handler is a single instance of a worker.  In my implementation, I went for something like the following process:</p>
<ul>
<li>User requests 1 of item A via form</li>
<li>Memcache entry is created with a unique key for the user&#8217;s request</li>
<li>0MQ request is created, &#8220;allocate me 1 of item A, for my session ID X and unique key ABC&#8221;</li>
<li><em>&#8230; polling happens here &#8230;</em></li>
<li>0MQ worker receives message and performs relevant checks</li>
<li>Memcache value for supplied unique key is updated with response</li>
<li>Polling for this updated value causes a redirect for the user accordingly</li>
</ul>
<p>Polling checked the memcache key for a successful response.  I decided to use <a href="http://memcached.org/">memcache</a> for this as it was quick to get going and I only technically needed a key-value setup.  I also wanted to avoid unnecessary hits on a database if possible, preferring to keep this for transactional data.  Plus I also wanted to play with memcache a bit ;-)</p>
<h2>Testing</h2>
<p>In tests, this setup seemed to work well, and the updated memcache value ended up being a serialized array with a success/error code, and some additional information eg &#8220;Sold out&#8221;, &#8220;Item is unavailable&#8221;, &#8220;You requested 2 but only 1 is available&#8221;.  This enabled better feedback for the user when their request was unsuccessful.</p>
<p>Running this in small-scale tests was great.  It was good to be able to start and stop the queue handler, and see the user being automatically bounced to the &#8220;please wait&#8221; polling page whenever the queue handler wasn&#8217;t running or had a backlog of messages to process. Fire up the handler, checks take place and the user is then redirected accordingly.</p>
<p>When running this under heavier loads however, we hit instances where occasionally (due to intentionally-bad <a href="http://httpd.apache.org">Apache</a> settings), the server processes ran out of memory and required a restart of Apache.  This was done deliberately to see how the queue could recover from different scenarios.  As a result, restarting Apache would cause a flood of messages to be sent to the queue handler in one go, presumably because they&#8217;d been blocked somehow previously with the large load.  This was confusing and unexpected behaviour to me, however I presumed this was because Apache (with mod_php) had been struggling to send the messages out under the load, and a restart caused a flush of some sorts.  I also presume this isn&#8217;t down to any fault of 0MQ.  It does however pose the question of what to do in a scenario where messages can potentially be lost, but this could be solved by a message queue that persists messages somewhere until completion.</p>
<p>Despite this teething issue which wasn&#8217;t really down to any fault of 0MQ, the system works great.  Being new to queueing like this, I&#8217;m not entirely sure how this would scale and still keep the ability to not oversell an item &#8211; database transactions from multiple workers would need to be synchronised somehow to ensure that figures are kept up to date.  But overall, I&#8217;m very happy with it as a starting point for a replacement solution.</p>
<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=222&amp;md5=8c2ca9636d9b23d72ded219b18b122b9" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2012/01/25/experimentation-with-zeromq/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steps to release a PEAR package (for lead devs)</title>
		<link>http://www.richsage.co.uk/2012/01/05/steps-to-release-a-pear-package-for-lead-devs/</link>
		<comments>http://www.richsage.co.uk/2012/01/05/steps-to-release-a-pear-package-for-lead-devs/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 09:36:33 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[pear]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=216</guid>
		<description><![CDATA[Mini post. I can never find this information on the PEAR site, so this is just a reference for me really :-)

After all code changes have been made and pushed into the repository, do the following

# pfm
* Follow instructions here, eg update version number, release notes
* Regenerate Contents
* Save &#038; Exit
# git add package.xml
# ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2012%2F01%2F05%2Fsteps-to-release-a-pear-package-for-lead-devs%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2012%2F01%2F05%2Fsteps-to-release-a-pear-package-for-lead-devs%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>Mini post. I can never find this information on the PEAR site, so this is just a reference for me really :-)</p>
<p>After all code changes have been made and pushed into the repository, do the following</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>rich<span style="color: #000000; font-weight: bold;">@</span>localhost<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># pfm</span>
<span style="color: #000000; font-weight: bold;">*</span> Follow instructions here, eg update version number, release notes
<span style="color: #000000; font-weight: bold;">*</span> Regenerate Contents
<span style="color: #000000; font-weight: bold;">*</span> Save <span style="color: #000000; font-weight: bold;">&amp;</span> Exit
<span style="color: #7a0874; font-weight: bold;">&#91;</span>rich<span style="color: #000000; font-weight: bold;">@</span>localhost<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># git add package.xml</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>rich<span style="color: #000000; font-weight: bold;">@</span>localhost<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># git commit</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>rich<span style="color: #000000; font-weight: bold;">@</span>localhost<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># git tag &quot;RELEASE-x.y.z&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>rich<span style="color: #000000; font-weight: bold;">@</span>localhost<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># pear package</span>
<span style="color: #000000; font-weight: bold;">*</span> Package <span style="color: #c20cb9; font-weight: bold;">file</span> is created, release this through PEAR website <span style="color: #c20cb9; font-weight: bold;">as</span> normal</pre></div></div>

<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=216&amp;md5=d03721363093bc0667ac00da81f047c0" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2012/01/05/steps-to-release-a-pear-package-for-lead-devs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rendering emails with Twig in Symfony2</title>
		<link>http://www.richsage.co.uk/2011/12/16/rendering-emails-with-twig-in-symfony2/</link>
		<comments>http://www.richsage.co.uk/2011/12/16/rendering-emails-with-twig-in-symfony2/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 17:09:55 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=204</guid>
		<description><![CDATA[I've been experimenting with sending emails but rendering the content with Twig.  This allows emails to extend a standard layout where required, but also gives us the flexibility to insert other content into the template which may be required.  In the first instance, we're interested in supplying the email subject here.

The concept ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F16%2Frendering-emails-with-twig-in-symfony2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F16%2Frendering-emails-with-twig-in-symfony2%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been experimenting with sending emails but rendering the content with <a href="http://twig.sensiolabs.org/">Twig</a>.  This allows emails to extend a standard layout where required, but also gives us the flexibility to insert other content into the template which may be required.  In the first instance, we&#8217;re interested in supplying the email subject here.</p>
<p>The concept is simple &#8211; within <a href="http://symfony.com">Symfony2</a>, firstly get Twig from the container or inject it accordingly.  You can then render the template as a whole, and also extract any other items required.  My example is taken from a listener class I&#8217;ve been using, but the concepts can be applied appropriately depending on where you want to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MyListener
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$mailer</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$twig</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>\Swift_Mailer <span style="color: #000088;">$mailer</span><span style="color: #339933;">,</span> \Twig_Environment <span style="color: #000088;">$twig</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mailer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$mailer</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">twig</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$twig</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onMyevent<span style="color: #009900;">&#40;</span><span style="color: #000088;">$myEvent</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$emailTo</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$myEvent</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getEmailTo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Load the template in</span>
        <span style="color: #000088;">$templateFile</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;MyBundle:emails:myEmailTemplate.twig&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$templateContent</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">twig</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$templateFile</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Render the whole template including any layouts etc</span>
        <span style="color: #000088;">$body</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$templateContent</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;someParam&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Get the subject block out</span>
        <span style="color: #666666; font-style: italic;">// If the block doesn't exist, use a default</span>
        <span style="color: #000088;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$templateContent</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasBlock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;subject&quot;</span><span style="color: #009900;">&#41;</span>
            ? <span style="color: #000088;">$templateContent</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderBlock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;subject&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;param1&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$someInformation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">foo</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;Default subject here&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$subject</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Send email</span>
        <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> \Swift_Message<span style="color: #339933;">::</span><span style="color: #004000;">newInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setSubject</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$subject</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFrom</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;info@example.com&quot;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$emailTo</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setBody</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$body</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mailer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">send</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This means we can put something like the following in our template file:</p>

<div class="wp_syntax"><div class="code"><pre class="twig" style="font-family:monospace;"><span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">extends</span> <span style="color: #ff0000;">&quot;MyBundle:emails:emailLayout.twig&quot;</span> <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">{# This block is rendered in emailLayout.twig #}</span>
<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">block</span> body <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span>
Hello, world. This is your email content here
<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">endblock</span> <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span>
&nbsp;
<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">block</span> subject <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span>
Your subject line goes here
<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">endblock</span> <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span></pre></div></div>

<p>I was hoping to use the Twig <code>{% spaceless %}</code> tag, but it appears that it&#8217;s only available for HTML (sadly <a href="https://github.com/fabpot/Twig/pull/433">this PR</a> has been closed; shame as it would have been useful).  Hence the <code>trim()</code> call when retrieving the subject.</p>
<p>Of course, you can extend the above to inject in default email-FROM-addresses and names, template names and so on where appropriate.</p>
<p><strong>Update</strong>: Thanks to Fabien for pointing out (comments below) that you can remove whitespace by using the following (hyphens at the end of the opening <code>block</code> tag and at the start of <code>endblock</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="twig" style="font-family:monospace;"><span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%</span> <span style="color: #0600FF;">block</span> subject <span style="color: #D36900;">-%</span><span style="color: #D36900;">&#125;</span>
Your subject line goes here
<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">%-</span> <span style="color: #0600FF;">endblock</span> <span style="color: #D36900;">%</span><span style="color: #D36900;">&#125;</span></pre></div></div>

<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=204&amp;md5=ecca1a59894dbe7e83ae90bfd91d95e0" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/12/16/rendering-emails-with-twig-in-symfony2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>First steps into conference speaking</title>
		<link>http://www.richsage.co.uk/2011/12/08/first-steps-into-conference-speaking/</link>
		<comments>http://www.richsage.co.uk/2011/12/08/first-steps-into-conference-speaking/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 09:07:29 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[conference]]></category>
		<category><![CDATA[presentation]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=202</guid>
		<description><![CDATA[I've been thinking about next year's New Year's Resolutions again.  One which I'm going to repeat from this year was to blog more (inspired by Lorna's post about blogging more back in January), but also a new one I want to achieve is to speak at a conference.

I've presented papers at a couple ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F08%2Ffirst-steps-into-conference-speaking%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F08%2Ffirst-steps-into-conference-speaking%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been thinking about next year&#8217;s New Year&#8217;s Resolutions again.  One which I&#8217;m going to repeat from this year was to blog more (inspired by Lorna&#8217;s <a href="http://www.lornajane.net/posts/2011/make-blogging-your-new-years-resolution">post about blogging more</a> back in January), but also a new one I want to achieve is to speak at a conference.</p>
<p>I&#8217;ve presented papers at a <a href="http://www.eva-london.org/">couple</a> of non-web related <a href="http://www2.ph.ed.ac.uk/acoustics/MAN/bradfordmeeting2006.html">conferences</a> a number of years ago, but nothing in the web field, and I&#8217;m unsure as to the correct approach to take with this.  My main reason for wanting to speak is that I want to be able to share knowledge I&#8217;ve learnt in the hope that this may be of interest to at least one person.  I&#8217;m also passionate about the technology I use in day-to-day development and would most probably like to include this.  My main concern however is &#8220;would it be interesting enough?&#8221;, which I&#8217;m inclined to feel is a catch-22 situation &#8211; I won&#8217;t know until presenting it, but then I won&#8217;t get a chance to present it unless I submit.</p>
<p>Calls for papers are continuously springing up, and I&#8217;m wondering about the best approach here to get my foot in the door so to speak.  Is it a case of writing up something that I feel is interesting and would benefit others, and just taking the leap? Finding local Uncons/user groups and trying the material out there?</p>
<p>I&#8217;d be interested to hear any tips and pointers :-)</p>
<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=202&amp;md5=b12b24a8fe98ef69d015c71f0b2eea3e" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/12/08/first-steps-into-conference-speaking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Symfony2 data collectors</title>
		<link>http://www.richsage.co.uk/2011/12/05/symfony2-data-collectors/</link>
		<comments>http://www.richsage.co.uk/2011/12/05/symfony2-data-collectors/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 16:38:47 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=196</guid>
		<description><![CDATA[NB: Cross-posted on our work blog at White October :-)

I spent some time last week working on automated MailChimp integration with one of our Symfony2 sites.  The project uses Behat and Mink extensively for BDD testing, so I wanted to be able to test that when users registered on our site, they were ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F05%2Fsymfony2-data-collectors%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F12%2F05%2Fsymfony2-data-collectors%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>NB: </strong>Cross-posted on our <a href="http://www.whiteoctober.co.uk/blog/">work blog</a> at <a href="http://www.whiteoctober.co.uk/">White October</a> :-)</p>
<p>I spent some time last week working on automated <a href="http://www.mailchimp.com/" title="MailChimp">MailChimp</a> integration with one of our <a href="http://symfony.com" title="Symfony">Symfony2</a> sites.  The project uses <a href="http://behat.org/">Behat</a> and <a href="http://mink.behat.org/" title="Mink">Mink</a> extensively for BDD testing, so I wanted to be able to test that when users registered on our site, they were automatically added to the client&#8217;s MailChimp distribution list.  Unsubscription could happen via a checkbox in the user&#8217;s account settings and this needed to work the same way behind the scenes.</p>
<p>I opted to use one of the <a href="https://github.com/jirafe/MailChimpBundle">available MailChimp bundles</a> to aid integration and with a bit of tweaking this worked great.  The bundle comes with a stub connection which is able to collate requests sent and make them available for inspection.  I wanted to be able to utilise this neatly inside a set of tests, and potentially also make it available in the dev environment.  A bit of skimming the Symfony2 cookbook led me to the entry on <a href="http://symfony.com/doc/current/cookbook/profiler/data_collector.html">Symfony2 data collectors</a>.</p>
<p>The concept is simple &#8211; a data collector is registered and is able to, well, collect data!  For example, the number of queries during a request, or the number of emails sent.  This can then be accessed via the profiler in the relevant environment (dev, test etc).  In my case I wanted to collect and subsequently inspect all requests sent to MailChimp.</p>
<p>First step &#8211; create me a data collector:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #000000; font-weight: bold;">namespace</span> Jirafe\Bundle\MailChimpBundle\DataCollector<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Symfony\Component\HttpKernel\DataCollector\DataCollector<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Symfony\Component\HttpFoundation\Request<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Symfony\Component\HttpFoundation\Response<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Jirafe\Bundle\MailChimpBundle\Connection\ConnectionInterface<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MailChimpDataCollector <span style="color: #000000; font-weight: bold;">extends</span> DataCollector
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$connection</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>ConnectionInterface <span style="color: #000088;">$connection</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connection</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$connection</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> collect<span style="color: #009900;">&#40;</span>Request <span style="color: #000088;">$request</span><span style="color: #339933;">,</span> Response <span style="color: #000088;">$response</span><span style="color: #339933;">,</span> \Exception <span style="color: #000088;">$exception</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'requests'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connection</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequests</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getRequestCount<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'requests'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getRequests<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'requests'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'mail_chimp'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <code>collect()</code> method is the interesting part here &#8211; this is called whenever data collection is required &#8211; usually once per request.  We collect the requests from the connection supplied to the constructor.</p>
<p>Next step, register this during the bundle&#8217;s <code>load()</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Add connection to data collector</span>
<span style="color: #000088;">$definition</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$container</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDefinition</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mail_chimp.data_collector'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$definition</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addArgument</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Reference<span style="color: #009900;">&#40;</span><span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mail_chimp.connection.%s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'connection'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The above uses the connection type specified in the bundle&#8217;s configuration option and previously registered as a service in the same method.  If you&#8217;re creating your own custom collector, this is just the normal parameters you&#8217;d pass in to your service when it&#8217;s instantiated.</p>
<p>Finally, I added a method and subsequent implementation to the interface and related connection classes within the bundle, so that MailChimp request objects were collected in an array, and made available to the data collector upon request. This is the <code>getRequests()</code> method listed above in the data collector; called in the <code>collect()</code> method. Quick &#8216;n&#8217; dirty here, since there would only ever be a single MailChimp request (possibly 2) made in any one request.</p>
<p>Once all this was in place, I could then test correctly.  Note that I&#8217;d rather have done the other way round (test and then develop) but since this was experimentation, I figured it was OK ;-) In my Behat scenarios, I added the <code>getSymfonyProfiler()</code> method detailed in a Behat/Mink <a href="http://docs.behat.org/cookbook/using_the_profiler_with_minkbundle.html">cookbook entry</a>, and proceeded to write my step (Behat 1.x-style):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Then</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^my email address is unsubscribed from the relevant MailChimp list$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000088;">$profiler</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSymfonyProfiler</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$profiler</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> \RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Symfony2 profiler not present for tests, wrong driver?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$mcDataCollector</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$profiler</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCollector</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mail_chimp&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$listID</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">container</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mailchimp_list_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Check the requests made to make sure we have an unsubscribe</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mcDataCollector</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequestCount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$requests</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$mcDataCollector</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequests</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$req1</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$requests</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;listUnsubscribe&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$req1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$req1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParams</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000088;">$listID</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Fire the redirect on the client</span>
    <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDriver</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">followRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The final line here is as a result of disabling redirects in a previous step since the data collector operates on a per-request basis.  If you&#8217;re subscribing eg via a form POST, then you&#8217;ll need to disable redirects prior to submitting the form, otherwise your data collector will be empty when you check it.  Disable them and then redirect after you&#8217;ve carried out your checks.</p>
<p>The implementation for the above is up on our Github MailChimpBundle fork <a href="https://github.com/whiteoctober/MailChimpBundle">here</a>; I&#8217;m not particularly fond of having to hack about the connection classes, and ideally it would be nice to layer the data collector on top without having to adjust existing code. That said, it does the job fine here, and it&#8217;s good to use even more features of Symfony2 ;-)</p>
<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=196&amp;md5=c0ec9fa62668e244db37cd8d47be6b2e" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/12/05/symfony2-data-collectors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twig extensions &#8211; name them correctly!</title>
		<link>http://www.richsage.co.uk/2011/09/20/twig-extensions-name-them-correctly/</link>
		<comments>http://www.richsage.co.uk/2011/09/20/twig-extensions-name-them-correctly/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 14:17:56 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=189</guid>
		<description><![CDATA[Came across this one today whilst integrating some new code into my current Symfony2 project.  The project has 2 custom Twig extensions - one with some filters in, one with some custom methods.  When creating the latter, I'd copied the class from the former and tweaked to suit.  In doing so, ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F09%2F20%2Ftwig-extensions-name-them-correctly%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F09%2F20%2Ftwig-extensions-name-them-correctly%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>Came across this one today whilst integrating some new code into my current <a href="http://symfony2.com/">Symfony2</a> project.  The project has 2 custom <a href="http://twig.sensiolabs.org">Twig</a> extensions &#8211; one with some filters in, one with some custom methods.  When creating the latter, I&#8217;d copied the class from the former and tweaked to suit.  In doing so, I&#8217;d left these lines in:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #009933; font-style: italic;">/**
     * Name of this extension
     *
     * @return string
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">&quot;myfirstextension&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The Twig documentation states that all extensions should be named uniquely, unless you need to replace any existing extensions, in which case you should name them the same.  <a href="http://twig.sensiolabs.org/doc/extensions.html#overriding-default-filters">See here</a> for a better explanation :-)  Great for extensibility and adjusting extensions that maybe you don&#8217;t have control over. Not so good when both extensions do something different and you don&#8217;t quite understand why it&#8217;s not working&#8230;.</p>
<p>Anyway, quick question in the #symfony IRC channel and <a href="http://twitter.com/Stof70">Stof</a> came to the rescue. Give that man a medal :-) and name your extensions uniquely if you don&#8217;t want them to overwrite others!</p>
<p class="wp-flattr-button"></p> <p><a href="http://www.richsage.co.uk/?flattrss_redirect&amp;id=189&amp;md5=bd7de3c08afa5bcc9e8172371e243de9" title="Flattr" target="_blank"><img src="http://www.richsage.co.uk/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/09/20/twig-extensions-name-them-correctly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logging out a user programmatically in Symfony2</title>
		<link>http://www.richsage.co.uk/2011/08/25/logging-out-a-user-programmatically-in-symfony2/</link>
		<comments>http://www.richsage.co.uk/2011/08/25/logging-out-a-user-programmatically-in-symfony2/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 14:03:03 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=182</guid>
		<description><![CDATA[Quick post this, as I know I'll forget/lose this code otherwise... Sometimes you need the ability to force a logout of a user.  The example I'll use here is a user requesting their account be deactivated - you assume that upon confirmation of the deactivation the user's model is marked as such, and ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F08%2F25%2Flogging-out-a-user-programmatically-in-symfony2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F08%2F25%2Flogging-out-a-user-programmatically-in-symfony2%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>Quick post this, as I know I&#8217;ll forget/lose this code otherwise&#8230; Sometimes you need the ability to force a logout of a user.  The example I&#8217;ll use here is a user requesting their account be deactivated &#8211; you assume that upon confirmation of the deactivation the user&#8217;s model is marked as such, and the user is subsequently logged out and shown a confirmation page:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Update your model here. Example:</span>
<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> clone <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;security.context&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setEnabled</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Log the user out</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;request&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">invalidate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;security.context&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Flash var to enable the user to see the deactivation success page</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;session&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'deactivate_account.success'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// and redirect to success page</span>
<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> RedirectResponse<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;router&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;deactivate_account_success&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Your deactivation page should allow viewing without requiring authentication (anonymous users can view it).  The above code should be self-explanatory &#8211; invalidate the current session, and set the security token to null (rather than the previously-authenticated token).  The flash variable I set so that viewing of the success page is one-shot rather than being permanently viewable.  Just my preference :-)</p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/08/25/logging-out-a-user-programmatically-in-symfony2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Greyscale printing on a Canon MP270 in Linux</title>
		<link>http://www.richsage.co.uk/2011/08/06/greyscale-printing-on-a-canon-mp270-in-linux/</link>
		<comments>http://www.richsage.co.uk/2011/08/06/greyscale-printing-on-a-canon-mp270-in-linux/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 10:53:54 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[print]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=174</guid>
		<description><![CDATA[Just came across this article on ubuntuforums.org which describes how to add a greyscale printing option when using a Canon MP270 printer under Ubuntu. Reprinting here in case the original disappears. Dead simple!:


After reading the manual from Canon, I have made the grayscale printing working too. For those who need it, here is the ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F08%2F06%2Fgreyscale-printing-on-a-canon-mp270-in-linux%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F08%2F06%2Fgreyscale-printing-on-a-canon-mp270-in-linux%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>Just came across <a href="http://ubuntuforums.org/showpost.php?p=8971846&#038;postcount=21">this article</a> on <a href="http://ubuntuforums.org">ubuntuforums.org</a> which describes how to add a greyscale printing option when using a <a href="http://www.canon.co.uk/For_Home/Product_Finder/Multifunctionals/Inkjet/PIXMA_MP270/">Canon MP270</a> printer under Ubuntu. Reprinting here in case the original disappears. Dead simple!:</p>
<blockquote><p>After reading the manual from Canon, I have made the grayscale printing working too. For those who need it, here is the fast tip:</p>
<p>Under System&#8211;>Administration&#8211;>Printing</p>
<p>right click MP250 that you have already setup, then select Properties from the popup menu, go to Job Options, scroll down to the bottom, add this option in:</p>
<p>CNGrayscale</p>
<p>click the Add button to add the option to the list.</p>
<p>Beside the CNGrayscale option, type in TRUE in the textfield, then click Apply, and close the Properties dialog.</p>
<p>By doing this, this printer is setup to be Grayscale printing by default. You can definitely have another copy of printer setup, pointing to the same printer, but for color printing. This is what i have done.
</p></blockquote>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/08/06/greyscale-printing-on-a-canon-mp270-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding non-entity fields to your Symfony2 forms</title>
		<link>http://www.richsage.co.uk/2011/07/20/adding-non-entity-fields-to-your-symfony2-forms/</link>
		<comments>http://www.richsage.co.uk/2011/07/20/adding-non-entity-fields-to-your-symfony2-forms/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 08:21:27 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=164</guid>
		<description><![CDATA[I've had a case recently whereby I needed to implement a registration form in my current Symfony2 application, based on a Mandango model.  This form consisted of selected fields from my model, along with a separate "I accept the terms and conditions" checkbox; pretty standard.  In Symfony 1, it was straightforward to ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F07%2F20%2Fadding-non-entity-fields-to-your-symfony2-forms%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F07%2F20%2Fadding-non-entity-fields-to-your-symfony2-forms%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve had a case recently whereby I needed to implement a registration form in my current <a href="http://symfony.com/">Symfony2</a> application, based on a <a href="http://www.mandango.org/">Mandango</a> model.  This form consisted of selected fields from my model, along with a separate &#8220;I accept the terms and conditions&#8221; checkbox; pretty standard.  In Symfony 1, it was straightforward to add in non-model fields, however in Symfony2 the <a href="http://symfony.com/doc/current/book/forms.html">convention for forms</a> is to create a domain model which represents your form, which then gets populated with the data.</p>
<p>Initially I went with extending from the Mandango model (in my case, <code>Model\MyOwnBundle\User</code> being the original model) and adding in a separate <code>get/setTermsAndConditions()</code> method, but this caused problems when saving the model down, as Mandango couldn&#8217;t find the document class (since I&#8217;d extended it and called it <code>UserRegistration</code>).</p>
<p>After a bit of digging and experimentation however, the following code does what I need it to, without having to extend my existing model or create a new one (which I&#8217;d then have to use to populate my actual Mandango model):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> RegisterFormType <span style="color: #000000; font-weight: bold;">extends</span> AbstractType
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Constructs our registration form
     * 
     * @param \Symfony\Component\Form\FormBuilder $builder
     * @param array $options
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> buildForm<span style="color: #009900;">&#40;</span>FormBuilder <span style="color: #000088;">$builder</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Build the form</span>
        <span style="color: #000088;">$builder</span><span style="color: #339933;">-&gt;</span>
            <span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;firstName&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;text&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>
            <span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;lastName&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;text&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>
            <span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;emailAddress&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;email&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>
            <span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;t_and_c&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">&quot;checkbox&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                    <span style="color: #0000ff;">&quot;property_path&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                <span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// &quot;True&quot; validator on the form for t&amp;c</span>
        <span style="color: #000088;">$builder</span><span style="color: #339933;">-&gt;</span>
            <span style="color: #004000;">addValidator</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> CallbackValidator<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>FormInterface <span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;t_and_c&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addError</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> FormError<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Please accept the terms and conditions in order to register'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The above adds the <code>t_and_c</code> field but using <code>"property_path" => false</code> means it&#8217;s not validated against the model and therefore no need to implement separate <code>get/set()</code> methods. Instead we use a callback validator on the form to check the value of the <code>t_and_c</code> field and ensure it&#8217;s been checked. Et voila :-)</p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/07/20/adding-non-entity-fields-to-your-symfony2-forms/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Getting into Behat with Symfony2</title>
		<link>http://www.richsage.co.uk/2011/06/15/getting-into-behat-with-symfony2/</link>
		<comments>http://www.richsage.co.uk/2011/06/15/getting-into-behat-with-symfony2/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 07:52:19 +0000</pubDate>
		<dc:creator>rich</dc:creator>
				<category><![CDATA[symfony]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://www.richsage.co.uk/?p=157</guid>
		<description><![CDATA[NB: This was originally posted over at the White October blog but I figured it would fit in nicely here too :-)

I've spent the past week starting a new sprint on our latest large project, and as we're keen to get our clients as involved as possible during sprints, we decided to get down ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F06%2F15%2Fgetting-into-behat-with-symfony2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richsage.co.uk%2F2011%2F06%2F15%2Fgetting-into-behat-with-symfony2%2F&amp;source=rich_81&amp;style=normal&amp;service=is.gd" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>NB:</strong> This was originally posted over at the <a href="http://www.whiteoctober.co.uk/blog/2011/06/15/getting-into-behat-with-symfony2/">White October blog</a> but I figured it would fit in nicely here too :-)</p>
<p>I&#8217;ve spent the past week starting a new sprint on our latest large project, and as we&#8217;re keen to get our clients as involved as possible during sprints, we decided to get down with some <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behaviour-Driven Development</a> (BDD) which allows them to contribute to writing the actual acceptance criteria for the user stories.  We&#8217;re pretty big on <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test-Driven Developmen</a>t here at WO Towers but sometimes it&#8217;s necessary to strike a balance between testing every minute detail and no testing.  BDD seems to meet that balance whilst providing good code coverage with tests.  Note: here I speak of functional tests rather than unit tests.</p>
<p>The beauty of BDD is that it&#8217;s written in plain everyday language, and this can be directly translated to code snippets.  Therefore the client is happy working &#8220;in plain english&#8221;, and the developer can crack on with writing the actual code to test these parts.</p>
<p>We&#8217;ve chosen to use <a href="http://symfony.com/">Symfony2</a> for the project (more on that in a separate post) and for the BDD aspect we&#8217;ve gone with <a href="http://behat.org/">Behat</a> (coupled with <a href="https://github.com/Behat/Mink">Mink</a>); both of which have bundles available for Symfony2. Essentially, BDD boils down to <strong>Features</strong>, consisting of a number of <strong>Scenarios</strong>, which in turn consist of a number of <strong>Steps</strong>.  Here&#8217;s an example:</p>
<pre>Feature: Login to the admin area
	As an administrator
	I want to be able to log into an admin area
	So I can administer MyApp

	Scenario: Joe Bloggs logs into the admin area
	  Given I visit the admin area
	  When I am shown the login form
	  And I click login with my correct credentials
	  Then I should be on /admin/home
</pre>
<p>This could translate to code such as the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Given</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^I visit the admin area$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">visit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPathTo</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/admin&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">When</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^I am shown the login form$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000088;">$doc</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    assertTrue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$doc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_username&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertTrue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$doc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_password&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">And</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^I click login with my correct credentials$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000088;">$doc</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$doc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fillField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_username&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;joe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$doc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fillField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_password&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;bloggs&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$doc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clickButton</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Log in&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Then</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^(?:|I )should be on (?P&lt;page&gt;.+)$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    assertEquals<span style="color: #009900;">&#40;</span>
        <span style="color: #990000;">parse_url</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPathTo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> PHP_URL_PATH<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #990000;">parse_url</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCurrentUrl</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> PHP_URL_PATH<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>page<span style="color: #339933;">&gt;</span></pre></div></div>

<p>The beauty of Behat is that the step definitions are reusable, meaning that if you stick to a standard way of describing your steps, the amount of code you need to write is vastly reduced, compared with normal functional TDD.  Steps that aren&#8217;t implemented yet are given default code as per:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Given</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^I visit the admin area$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> \Behat\Behat\Exception\PendingException<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>which will translate into the output shown as a step needing to be implemented.  Behat also takes note of the Pending exception being thrown and automatically skips any steps following this in the scenario, notifying you of this at the end of the test run.</p>
<p>Behat also comes with a number of standard step definitions built-in, although these are somewhat buried in the code and not in the docs :-(  So for example the following steps are part of the included ones:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">I go to <span style="color: #339933;">/</span>my<span style="color: #339933;">/</span>url<span style="color: #339933;">:</span>
&nbsp;
<span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">When</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^(?:|I )go to (?P&lt;page&gt;.+)$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">visit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPathTo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>page<span style="color: #339933;">&gt;</span></pre></div></div>

<p>and</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">I fill in <span style="color: #0000ff;">&quot;username&quot;</span> with <span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #339933;">:</span>
&nbsp;
<span style="color: #000088;">$steps</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">When</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^(?:|I )fill in &quot;(?P&lt;field&gt;[^&quot;]*)&quot; with &quot;(?P&lt;value&gt;[^&quot;]*)&quot;$/'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$world</span><span style="color: #339933;">,</span> <span style="color: #000088;">$field</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$world</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fillField</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>value<span style="color: #339933;">&gt;&lt;/</span>field<span style="color: #339933;">&gt;</span></pre></div></div>

<p>which translates as even less code to write. Bonus!</p>
<h2>Tips &#8216;n&#8217; tricks</h2>
<p>The Mink (browser emulator abstraction layer) setup comes with a Symfony2 driver which is great for just testing normal usage.  In our project however we&#8217;re integrating Facebook authentication using the FOS <a href="https://github.com/FriendsOfSymfony/FacebookBundle">FacebookBundle</a>, and we needed a way to test that the user was being bounced to Facebook in order to log in.  The solution for this was simple &#8211; switch to using <a href="https://github.com/fabpot/Goutte">Goutte</a> as the driver, as per the BehatBundle docs, and voila, you can test the current URL contains eg facebook.com or whatever.  The actual testing of the authentication itself I&#8217;ll write up in a separate blog post as it&#8217;s a bit epic for here.</p>
<p>The documentation mentions using a separate front controller for testing, with a separate environment configuration.  This is definitely recommended, particularly if you&#8217;re using Goutte.  If you need services to be available, for example your entity manager, pop something like this in your env.php file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$kernel</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AppKernel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$kernel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadClassCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$service</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$kernel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getContainer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;your.service.here&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can also use the <code>env.php</code> file for setting up fixtures that need to be reset for each Scenario that you create, eg pre-defined user states and so on.</p>
<h2>Caveats</h2>
<p>Unless you&#8217;re using <a href="https://github.com/Behat/SahiClient">Sahi</a>, you obviously can&#8217;t test things such as Javascript popups effectively.  I&#8217;m in two minds as to whether this should be handled by a new type of Exception which can be thrown e.g. a <code>TestInRealBrowserException()</code>.  That way it could be caught and notified to the user running the tests, or flagged as part of an automated build process for manual testing.</p>
<p>Overall, getting into BDD has been a fun and rewarding experience.  At times the lack of docs make it somewhat frustrating, but this is easily solved by a) digging into the code and b) probably me getting off my ass and submitting some docs back.  The ease of which the steps can be written though is a massive time saver when writing your tests, coupled with the reusability of the code.  Big thumbs-up from me!</p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://www.richsage.co.uk/2011/06/15/getting-into-behat-with-symfony2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

