<?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>Josh on the Web &#187; Uncategorized</title>
	<atom:link href="http://joshduck.com/blog/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://joshduck.com/blog</link>
	<description>It's a blog about the web, by Josh. Geddit?</description>
	<lastBuildDate>Thu, 17 Feb 2011 11:57:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Jumping On the Bandwagon</title>
		<link>http://joshduck.com/blog/2011/02/17/jumping-on-the-bandwagon/</link>
		<comments>http://joshduck.com/blog/2011/02/17/jumping-on-the-bandwagon/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 11:51:51 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=306</guid>
		<description><![CDATA[Nokia and Microsoft&#8217;s deal has been getting a lot of press in the last week. Nokia Plan B (which has now been revealed as a hoax) got a lot of attention on Hacker News and spawned a bunch of knock offs which I was taking a look through on my morning train ride. By the [...]]]></description>
			<content:encoded><![CDATA[<p>Nokia and Microsoft&#8217;s deal has been getting a lot of press in the last week. <a href="http://nokiaplanb.com/">Nokia Plan B</a> (which has now been revealed as a hoax) got a lot of attention on Hacker News and spawned a bunch of <a href="http://nokiaplans.com/">knock offs</a> which I was taking a look through on my morning train ride. By the time I&#8217;d got to work I&#8217;d decided to contribute my own poor sense of humour to the mix and set off on the quickest web page launch I&#8217;d ever done. The result was <a href="http://nokiaplanxp.com/">Nokia Plan XP</a> which was put together in the time it usually takes me to get my morning coffee.<span id="more-306"></span></p>
<p>I tweeted the link to <a href="http://twitter.com/ricardovice">@ricardovice</a> who was nice enough to add my page to his canonical list of wasted domains. There wasn&#8217;t really a point to the page but I was kind of interested to see how much traffic I could get from riding the coat tails of funnier people than myself. The traffic I did receive wasn&#8217;t extraordinary but in twelve hours I got 3,800 hits. 95% of that was purely from Ricardo&#8217;s list. The remaining was from Hacker News (I shared the link in a comment thread) and my meager 100 Twitter followers. Only 24 people followed the link through to my website.</p>
<p>I&#8217;m not going to pretend that there are any great lessons to be learned from this. It was fun to be able to launch a concept including purchasing the domain and some dodgy Photoshop hackery in twenty minutes. Getting traffic is always nice too. As a side note I actually own a Windows Phone 7 device and think the Nokia chose was a decent one, especially considering how much Microsoft is throwing money at them.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2011/02/17/jumping-on-the-bandwagon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inheritance and Mootools Mixins</title>
		<link>http://joshduck.com/blog/2011/02/11/inheritance-and-mootools-mixins/</link>
		<comments>http://joshduck.com/blog/2011/02/11/inheritance-and-mootools-mixins/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 03:26:07 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=275</guid>
		<description><![CDATA[I was playing with Mootools&#8217; Class implementation today. It has a few nice features like mixins, easy inheritance and sane parent method calling. I did run into issues combining mixins (through the Implements keyword) with parent method calling. The following code fails with the message: The method &#8220;setOptions&#8221; has no parent. var Car = new Class&#40;&#123; Extends: [...]]]></description>
			<content:encoded><![CDATA[<p>I was playing with Mootools&#8217; Class implementation today. It has a few nice features like mixins, easy inheritance and sane parent method calling. I did run into issues combining mixins (through the <em>Implements</em> keyword) with parent method calling. The following code fails with the message: <strong>The method &#8220;setOptions&#8221; has no parent.</strong><span id="more-275"></span></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Car <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> <span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">Extends</span><span style="color: #339933;">:</span> Vehicle<span style="color: #339933;">,</span>
	Implements<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>Options<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
	options<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		wheels<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	setOptions<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">wheels</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;That's not a car.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">parent</span><span style="color: #009900;">&#40;</span>options<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;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Apparently mixin methods like <em>setOptions</em> don&#8217;t act like inherited functions in Mootools&#8217; class implementation. The obvious fix is to make the class inherit from the mixin directly.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Car <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> <span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">Extends</span><span style="color: #339933;">:</span> Options<span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Code omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This works, but we&#8217;ve lost the ability to create a sane object hierarchy. Thankfully the <em>Options</em> variable I added to the <em>Implements</em> array is just a reference to the class used to implement the mixin. So it is possible to call the parent method manually, just like I would without Mootool&#8217;s magic <em>this.parent</em> method.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Car <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> <span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Code omitted</span>
&nbsp;
	setOptions<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">wheels</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;That's not a car.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			Options.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setOptions</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> options<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;">&#125;</span></pre></div></div>

<p>This works exactly like I hoped. The same approach would obviously work for other mixins like <em>Events </em> and <em>Chain</em>.</p>
<p>As a side note, it&#8217;s worth mentioning that <em>Options.prototype.setOptions</em> is actually pointing to a wrapper method which does a bit of Mootools-specific magic and validation; like ensuring the function is not protected. Fortunately the wrapper is written in a sane enough way that calling it from another object like this works OK.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2011/02/11/inheritance-and-mootools-mixins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top trends of 2011</title>
		<link>http://joshduck.com/blog/2011/01/31/top-trends-of-2011/</link>
		<comments>http://joshduck.com/blog/2011/01/31/top-trends-of-2011/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 09:13:29 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=268</guid>
		<description><![CDATA[Brightlabs, my employer, regularly publishes a web-focused newsletter for small businesses called enlighten. The latest edition contains and article I wrote detailing &#8220;Five trends that will change the web in 2011&#8220;. The web ceased long ago of being a mere tool for sharing text documents. Images, sound and interactivity via JavaScript have all shifted the [...]]]></description>
			<content:encoded><![CDATA[<p>Brightlabs, my employer, regularly publishes a web-focused newsletter for small businesses called <em>enlighten</em>. The latest edition contains and article I wrote detailing &#8220;<a href="http://www.brightlabs.com.au/page/Web-Design-Blog/Website_Trends_2011/">Five trends that will change the web in 2011</a>&#8220;.</p>
<blockquote><p>The web ceased long ago of being a mere tool for sharing text documents. Images, sound and interactivity via JavaScript have all shifted the web towards the multimedia future we have long been promised. At the same time the iPhone and its App Store have raised consumers expectations of what their web enabled devices are capable of. Web developers are striving to meet these new expectations and are taking their lead from the desktop to create more interactive web applications.</p></blockquote>
<p><a href="http://www.brightlabs.com.au/page/Web-Design-Blog/Website_Trends_2011/">Read the article on Brightlabs</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2011/01/31/top-trends-of-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter will eat your URLs</title>
		<link>http://joshduck.com/blog/2010/08/28/twitter-will-eat-your-urls/</link>
		<comments>http://joshduck.com/blog/2010/08/28/twitter-will-eat-your-urls/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 04:26:54 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=231</guid>
		<description><![CDATA[My HTML periodic table has been getting a lot of attention on Twitter over the last few days. Because the page has a relatively short URL a lot of people have been tweeting the actual URL rather that using a URL shortening service. This has been good for me because shorteners remove the HTTP referrer [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://joshduck.com/periodic-table.html">HTML periodic table </a> has been getting a lot of attention on Twitter over the last few days. Because the page has a relatively short URL a lot of people have been tweeting the actual URL rather that using a  URL shortening service. This has been good for me because shorteners remove the HTTP referrer and stop me from seeing where my Twitter traffic comes from. </p>
<p>A peek at my error logs did reveal one potential problem though. I&#8217;ve had well over a thousand hits to invalid URLs like <a href="http://joshduck.com/perio">http://joshduck.com/perio</a>. These are obviously URLs which have run up against Twitter&#8217;s infamous 140 character limit and have been truncated. This results in wasted traffic for me and a waste of time for my visitors so I decided to push a quick fix. <span id="more-231"></span></p>
<p>I was already redirecting 404&#8242;s to a custom PHP page, so I added a check which redirects anyone who gets a 404 after accessing a truncated URL to the correct page. To stop similar problems from happening in the future I&#8217;ve added a short script that looks at static pages and blog posts on my site and tries to match them against any the requested URL when serving a 404 page. These URLs are then used to display a list of suggested links to the user. The script also does a little regex magic (read: hackery) to find the titles of the suggested links. Now URLs like <a href="http://joshduck.com/photo">http://joshduck.com/photo</a> or <a href="http://joshduck.com/blog/201">http://joshduck.com/blog/201</a> will give visitors a push in the right direction.</p>
<p>The actual script I use is specific to the code I use for my own site, but I&#8217;ve supplied a generic version of the script below.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$request_path</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Special case: redirect anyone trying to get to periodic-table.html straight there.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request_path</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/periodic-table.html'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$request_path</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: /periodic-table.html'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">die</span><span style="color: #009900;">&#40;</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;">// Check static files.</span>
<span style="color: #000088;">$suggestions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">glob</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/*.html'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$file</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$request_path</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</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: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/&lt;title&gt;([^&lt;]+)/i'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$url</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000088;">$suggestions</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$title</span><span style="color: #339933;">;</span>	
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2010/08/28/twitter-will-eat-your-urls/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A PHP snippet for pluralizing strings</title>
		<link>http://joshduck.com/blog/2010/08/13/a-php-snipped-for-pluralizing-strings/</link>
		<comments>http://joshduck.com/blog/2010/08/13/a-php-snipped-for-pluralizing-strings/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 10:41:46 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=224</guid>
		<description><![CDATA[Every time I&#8217;m working on CRUD applications it seems like a lot of boilerplate code goes towards displaying appropriate messages when lists can contain zero, one or more than one element. I put together a quick function to speed up the process. The function takes a string with string fragments marked up inline as its [...]]]></description>
			<content:encoded><![CDATA[<p>Every time I&#8217;m working on CRUD applications it seems like a lot of boilerplate code goes towards displaying appropriate messages when lists can contain zero, one or more than one element. I put together a quick function to speed up the process.</p>
<p>The function takes a string with string fragments marked up inline as its main argument. It then formats the output based on the count passed into the function.<span id="more-224"></span></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$regex</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/\[(.*?)\]/'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$divider</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'|'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// If there are no end braces [] use whole input as option list.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$regex</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$search</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$fragments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$divider</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$search</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$text</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$fragments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$divider</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</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;">// We accept one (which is pointless...), two or three inline text fragments.</span>
	<span style="color: #666666; font-style: italic;">// If we've been given just two then case for zero should be same as two or more.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fragments</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$fragments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fragments</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$fragments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</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: #666666; font-style: italic;">// Normalize count.</span>
	<span style="color: #666666; font-style: italic;">// If value is array then use the number of elements as count.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</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;">// Choose the appropriate text fragment.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;=</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$replace</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$replace</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fragments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Replace markup with chosen option.</span>
	<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$search</span><span style="color: #339933;">,</span> <span style="color: #000088;">$replace</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Place our count into output (allows user to put %d inline to get count).</span>
	<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%d'</span><span style="color: #339933;">,</span> <span style="color: #990000;">number_format</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$text</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The tests show example usage.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;There [are no pages|is 1 page|are <span style="color: #009933; font-weight: bold;">%d</span> pages]&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are no pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are no pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There is 1 page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are 2 pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are 1,000 pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are no pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'There are 3 pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1 page|<span style="color: #009933; font-weight: bold;">%d</span> pages&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'0 pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>pluralize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'1 page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I am releasing this into the public domain so feel free to copy and redistribute the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2010/08/13/a-php-snipped-for-pluralizing-strings/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting started with Python and Django in 23 frustrating steps</title>
		<link>http://joshduck.com/blog/2010/02/27/getting-started-with-python-and-django-in-23-frustrating-steps/</link>
		<comments>http://joshduck.com/blog/2010/02/27/getting-started-with-python-and-django-in-23-frustrating-steps/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 00:52:19 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=70</guid>
		<description><![CDATA[Should I or shouldn&#8217;t I? Should I ditch my well-worn PHP and the frameworks I know so well to go with this new-fangled (silent-d)Jango thingy I hear the cool kids talking about? It&#8217;s a big decision, as this project is going to be the big one (you know, the one that will change the world [...]]]></description>
			<content:encoded><![CDATA[<p>Should I or shouldn&#8217;t I? Should I ditch my well-worn PHP and the frameworks I know so well to go with this new-fangled (silent-d)Jango thingy I hear the cool kids talking about? It&#8217;s a big decision, as this project is going to be the big one (you know, the one that will change the world and all that).</p>
<p>I&#8217;ve worked with PHP for over six years. It has it&#8217;s warts (and how) but it&#8217;s very much a known quantity at this point. On the other hand, when I have used Python it&#8217;s been a much more pleasant experience. The fact that this is a personal project makes the decision easier: let&#8217;s ditch old mate LAMPhp go with LAMPy. It&#8217;s almost dinner time and the latter sounds like it&#8217;d go well with an ale anyway. So, starting with a brand new dev box, where do I begin?<span id="more-70"></span></p>
<ol>
<li> Go to the Python website<br />
Of course. So P-Y-T-H-O-N-DOT-C-O-M, Enter. Er. Not exactly what I was looking for (and not what you should be looking for if your boss is anywhere nearby). Let&#8217;s try that again. Google to the rescue. Apparently I want DOT-O-R-G.</li>
<li>Choose a binary<br />
OK, so I know from listening to the fine folks over at proggit that there is an attempted Python 2 to 3 migration happening at the moment. There is no point investing my time in an outdated version so I&#8217;ll grab the 3.1 download.</li>
<li>Install Python<br />
C:\Python31. Hmm. Python, I know that you have a high opinion of yourself but you&#8217;re not that important to me just yet. You can go play nice in Program Files with all the other programs.</li>
<li>Download Django<br />
Now it&#8217;s Django&#8217;s turn. There&#8217;s the installer. Python 2.3 or higher, you say. Well logically 3 is higher than 2.3, but doesn&#8217;t Python 3 have problems with it&#8217;s younger siblings? Let me just check with a hit of the old Google&#8230; yup, as I thought. We&#8217;ll have to go with the older version.</li>
<li>Install Python<br />
Python 2! It&#8217;s not quite as fun when you know your downloading an outdated model.</li>
<li>Install Django<br />
So I&#8217;ve downloaded Django and now I&#8217;ve got an archive full of Python files. How do I install them?</li>
<li>Read the instructions<br />
But I hate doing that!</li>
<li>Run setup.py<br />
So I have to run the included setup.py file? If I launch the file from Explorer it prints something then immediately exits. Let&#8217;s open up the command line, cd to the correct location and run it again.</li>
<li>Run setup.py install<br />
OK, I forgot the &#8220;install&#8221; argument. You could have just told my with a popup; slept after printing the error; or heaven forbid, prompted me for an action. At least it&#8217;s working&#8230; can&#8217;t copy!? What do you mean?</li>
<li>Run setup.py install as an administrator<br />
Ah, of course you can&#8217;t copy to my Program Files. Time to launch a new command window as an administrator, renavigate to the archive and install.</li>
<li>Start a Django project<br />
You have to love the feeling you get when something works first time.</li>
<li>Define database settings<br />
Edit my project settings, easy enough.</li>
<li>Run the Django server<br />
Error: MySQLdb blah blah blah. What does that mean? Wait, Python does come with MySQL extensions right? Right!? It&#8217;s not like it&#8217;s one of the the most popular RDBMS on the planet.</li>
<li>Google it<br />
Hi Google. Yes, I&#8217;m back again. Do you know which module I want? Wow. That&#8217;s a lot of results. Are these the same? I&#8217;m looking for MySQLdb, not MySQL-Python. Ah, I see. They&#8217;re the same.</li>
<li>Go to SourceForge<br />
Why is this on SourceForge? Who&#8217;s distributing it? Ah, screw it. There is a big download button. I&#8217;m sure it&#8217;s safe. I mean, the button is green. Green is good. Red is bad. I didn&#8217;t get this far without learning a few things.</li>
<li>These are not the files you are looking for<br />
What do you mean they are the C files? I want a binary installer dammit. I&#8217;m a Windows user. I&#8217;m like a ten year old who still has training wheels on his bike; I don&#8217;t know anything about make files and building binaries.</li>
<li>Get the binary<br />
At least I know where the binaries can be downloaded&#8230; don&#8217;t I? Why do the binaries stop at Python 2.5 on the SourceForge page?</li>
<li>Google it!<br />
Yes, Google, I know I was just here. Just tell me where I can get a binary. Please stop laughing at me.</li>
<li>Download a binary<br />
There are a bunch of unofficial installers. Which one do I choose? bobs-super-awesome-mysql-python-for-2.6.exe looks reputable.</li>
<li>Install MySQLdb<br />
Great, a proper installer this time. It looks a bit &#8220;Windows 95&#8243; but beggers can&#8217;t be choosers. At least with an installer this should be eas&#8230; Hmmm, it&#8217;s frozen.</li>
<li>Think back<br />
Wait, the other installer didn&#8217;t like running as a non-priviledged user. Perhaps if I run as root. Ah-ha. That&#8217;s done it.</li>
<li>Install Python<br />
How silly of me. It should be obvious that all the C extensions only offer win32 versions. What exactly is the point of having a 64 bit binary then? Let&#8217;s reinstall Python. Joy of joys.</li>
<li>Enjoy<br />
Success at last. Time to revel in my new found smugness as a Pythonista:	&#8220;If the implementation is easy to explain, it may be a good idea.&#8221; You tell &#8216;em Guido.</li>
</ol>
<h2>The Takeaways</h2>
<p>Sarcasm is fun! Fixing things is hard. Nevertheless, there are quite a few frustrating hurdles that face those new to Python and Django.</p>
<ul>
<li>If the .com variant of your website is a porn site then you have problems. Developers might know to go to the right site but think of clueless managers.</li>
<li>The Python download page should spell out the benefits and drawbacks to each binary download. Be realistic. It&#8217;s better that the developer gets the version they need first time rather than having to come back later on for seconds, or thirds.</li>
<li>It&#8217;s not the 90&#8242;s any more. It&#8217;s not acceptable to expect to be  installed to C:\ root.</li>
<li>I didn&#8217;t mention it in the article but Python doesn&#8217;t add itself to my PATH. Having to dig around in my computer settings to be able to easily run Python from the command line is a pain.</li>
<li>Win64 has existed for a long time now. Shouldn&#8217;t it be supported by common modules?</li>
<li>Installers should be aware of restrictions introduced by Vista&#8217;s UAC model. This is basic stuff. Hanging on install without displaying errors is not acceptable.</li>
<li>The MySQL module should not be a second-class citizen maintained by some third party. If you want to poach PHP developers then you have to speak their language&#8230; er, database.</li>
<li>Setup tools could be a lot friendlier by prompting the user for an operation if an argument is not provided.</li>
<li>The Django download page should make it clear that Python 3 is not supported. Dropping backwards compatibility is not actually that common in other languages.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2010/02/27/getting-started-with-python-and-django-in-23-frustrating-steps/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cleaning up uncommitted subversion working folders</title>
		<link>http://joshduck.com/blog/2010/02/27/cleaning-up-antiquated-subversion-working-folders/</link>
		<comments>http://joshduck.com/blog/2010/02/27/cleaning-up-antiquated-subversion-working-folders/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 22:25:39 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=62</guid>
		<description><![CDATA[Today I stumbled across an unused working folder in a dark and dusty corner of one of our development servers. The directory had a couple of dozen un-checked in changes. Some were from barely a month ago while others dated back years. Not wanting to discard any important modifirations I cobbled together a bash command [...]]]></description>
			<content:encoded><![CDATA[<p>Today I stumbled across an unused working folder in a dark and dusty corner of one of our development servers. The directory had a couple of dozen un-checked in changes. Some were from barely a month ago while others dated back years. Not wanting to discard any important modifirations I cobbled together a bash command to show me when each file was last modified (the file&#8217;s mtime).<span id="more-62"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">for</span> CHANGED <span style="color: #000000; font-weight: bold;">in</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">svn</span> status <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">&quot;s/^.......//&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">&quot;/.\./&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$CHANGED</span>;
    <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$CHANGED</span>&quot;</span>;
<span style="color: #000000; font-weight: bold;">done</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&gt;</span> changes.txt</pre></div></div>

<p>The <code>sed </code> naively removes the first nine characters from the file status from the <code>svn status</code> output, which should just leave the file name.</p>
<p>The <code>awk</code> removes all files and paths without an extension &#8211; this was necessary because I later fed the output through <code>ls</code>, and I didn&#8217;t want any folder listings.</p>
<p>The <code>cat</code> allows me to direct the output to a file. If you aren&#8217;t piping to a file then you can omit that part.</p>
<p>Finally, <code>ls -l</code> shows the mtime of the file. To show the atime I could have used <code>ls -lu</code>, though the results of this were a little inconsistant for me (some times were after the mtime, which seemed counter-intuative). I used <code>ls</code> because I couldn&#8217;t seem to find a replacement for <code>stat</code> that was available on a vanilla Solaris install.</p>
<p>If you&#8217;re on a Linux box the following should work just as well (without trying to filter by extension):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">for</span> CHANGED <span style="color: #000000; font-weight: bold;">in</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">svn</span> status <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">&quot;s/^.......//&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #000000; font-weight: bold;">do</span>
   <span style="color: #c20cb9; font-weight: bold;">stat</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$CHANGED</span>&quot;</span>;
<span style="color: #000000; font-weight: bold;">done</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&gt;</span> changes.txt</pre></div></div>

<p>Of course, I&#8217;m still new to bash coding so if you have a script that simplifies this I&#8217;d love to hear about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2010/02/27/cleaning-up-antiquated-subversion-working-folders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Atom / RSS Reader for PHP</title>
		<link>http://joshduck.com/blog/2010/02/08/simple-atom-rss-reader-for-php/</link>
		<comments>http://joshduck.com/blog/2010/02/08/simple-atom-rss-reader-for-php/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 19:13:25 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/?p=46</guid>
		<description><![CDATA[I was recently looking for a simple RSS reader for PHP. There are a few out there, like Magpie RSS. These seem like adequate projects, but much too high level for the scripts I was throwing together. I need to read a couple of different feed formats: namely WordPress&#8217; RSS feed and Flickr&#8217;s Atom feeds. [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently looking for a simple RSS reader for PHP. There are a few out there, like <a href="http://magpierss.sourceforge.net/">Magpie RSS</a>. These seem like adequate projects, but much too high level for the scripts I was throwing together. I need to read a couple of different feed formats: namely WordPress&#8217; RSS feed and Flickr&#8217;s Atom feeds. I decided to put together a single-class implementation which didn&#8217;t do anything more than the bare minimum.</p>
<p><span id="more-46"></span>
<ul>
<li>Read both Atom and RSS feeds.</li>
<li>Easy initialisation and feed iteration (one line for each).</li>
<li>Cache URL contents (default is 60 minutes).</li>
<li>Graceful degradation: fail gracefully on errors (errors result in a 0 item feed which can be iterated through).</li>
<li>Single XML implementation for leaner code (SimpleXML).</li>
</ul>
<p>Firstly, my usage examples:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$feed</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Feed<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.example.com/feed.rss'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get items with next() or current()</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// &quot;Blog post 1&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// &quot;Blog post 2&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>        <span style="color: #666666; font-style: italic;">// &quot;Blog post 2&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Feed data returned</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>        <span style="color: #666666; font-style: italic;">// &quot;Blog post 2&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">date</span><span style="color: #339933;">;</span>         <span style="color: #666666; font-style: italic;">// int(1265569159)</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">description</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// &quot;Lorem ipsum dolar...&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #339933;">;</span>         <span style="color: #666666; font-style: italic;">// &quot;http://www.example.com/blog/2&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">image</span><span style="color: #339933;">;</span>        <span style="color: #666666; font-style: italic;">// &quot;http://www.example.com/blog/images/2.jpg&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get multiple items in single call</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>               <span style="color: #666666; font-style: italic;">// &quot;Blog post 3&quot; &quot;Blog post 4&quot; &quot;Blog post 5&quot;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Reset internal counter</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// &quot;Blog post 1&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get random items, without repeating</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>         <span style="color: #666666; font-style: italic;">// &quot;Blog post 4&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">;</span>         <span style="color: #666666; font-style: italic;">// &quot;Blog post 1&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Total number of items</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                 <span style="color: #666666; font-style: italic;">// int(10)</span></pre></div></div>

<p>The implementation is below. I failed on the single-class requirement, instead choosing to use the Template design pattern and break the actual XML DOM navigation out into a seperate class for each feed type. This keeps the overall design a lot cleaner.</p>
<div style="height: 40em; overflow: auto;">

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * Simple reader for RSS and Atom feeds. 
 * Requires: SimpleXML, fopen_wrappers
 * Limitations: Not content encoding support. 
 * 
 * Usage:
 *     $feed = new Feed('http://www.example.com/feed.rss');
 *
 *     //Get items with next() or current()
 *     echo $feed-&gt;next()-&gt;title;           // &quot;Blog post 1&quot;
 *     echo $feed-&gt;next()-&gt;title;           // &quot;Blog post 1&quot;
 *     echo $feed-&gt;next()-&gt;title;           // &quot;Blog post 2&quot;
 *     echo $feed-&gt;current()-&gt;title;        // &quot;Blog post 2&quot;
 *
 *     //Feed data returned
 *     echo $feed-&gt;current()-&gt;title;        // &quot;Blog post 2&quot;
 *     echo $feed-&gt;current()-&gt;date;         // int(1265569159)
 *     echo $feed-&gt;current()-&gt;description;  // &quot;Lorem ipsum dolar...&quot;
 *     echo $feed-&gt;current()-&gt;link;         // &quot;http://www.example.com/blog/2&quot;
 *     echo $feed-&gt;current()-&gt;image;        // &quot;http://www.example.com/blog/images/2.jpg&quot;
 *
 *     //Get multiple items in single call
 *     foreach ($feed-&gt;find(3) as $item) {
 *         echo $item-&gt;title;               // &quot;Blog post 3&quot; &quot;Blog post 4&quot; &quot;Blog post 5&quot;
 *     }
 *
 *     //Reset internal counter
 *     echo $feed-&gt;reset();
 *     echo $feed-&gt;next()-&gt;title;           // &quot;Blog post 1&quot;
 *
 *     //Get random items, without repeating
 *     echo $feed-&gt;random()-&gt;title;         // &quot;Blog post 4&quot;
 *     echo $feed-&gt;random()-&gt;title;         // &quot;Blog post 3&quot;
 *
 *     //Total number of items
 *     echo $feed-&gt;count();                 // int(10)
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Feed <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$url</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$reader</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$current</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$remaining</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$cacheTime</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3600</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Create Atom reader object.
	 *
	 * @param string $url
	 */</span>
	<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><span style="color: #000088;">$url</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;">url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$url</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Reset current item to first RSS item.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">reset</span><span style="color: #009900;">&#40;</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;">current</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remaining</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get the next item in the feed.
	 *
	 * @return stdClass Object representing the item. Will return null when the list is exhausted.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</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;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #339933;">++;</span>
			<span style="color: #000088;">$next</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getReader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$next</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get the current item in the feed.
	 *
	 * @return stdClass Object representing the item. Will return null when the list is exhausted.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">current</span><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;">getReader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">max</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</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: #009933; font-style: italic;">/**
	 * Get random item from the feed. Will not return an item more than once.
	 *
	 * @return stdClass Object representing the item. Will return null when the list is exhausted.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> random<span style="color: #009900;">&#40;</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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remaining</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;">remaining</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</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;">remaining</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</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;">remaining</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$picked</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remaining</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$index</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remaining</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$picked</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remaining</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$picked</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getReader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get X items from feed. Will advance pointer.
	 *
	 * @param int $count
	 * @return array of stdClass
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$items</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</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;">$items</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$items</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$items</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get the number of items in the feed.
	 *
	 * @return int
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">count</span><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;">getReader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get FeedReader object for the feed.
	 *
	 * @return FeedReader
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getReader<span style="color: #009900;">&#40;</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;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reader</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$xml</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getXML</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>RSSReader<span style="color: #339933;">::</span><span style="color: #004000;">canRead</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</span><span style="color: #009900;">&#41;</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;">reader</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RSSReader<span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>AtomReader<span style="color: #339933;">::</span><span style="color: #004000;">canRead</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</span><span style="color: #009900;">&#41;</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;">reader</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AtomReader<span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reader</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> NullReader<span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</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: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reader</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get XML element for the feed.
	 *
	 * @return SimpleXMLElement
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getXML<span style="color: #009900;">&#40;</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: #000088;">$xml</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCacheXML</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: #b1b100;">return</span> <span style="color: #000088;">$xml</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$xml</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getURLXML</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: #b1b100;">return</span> <span style="color: #000088;">$xml</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleXMLElement<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get XML element for the feed from cache.
	 *
	 * @return SimpleXMLElement or null if cache doesn't exist.
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getCacheXML<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Store URL data in local cache.</span>
		<span style="color: #000088;">$cacheFilename</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCacheFilename</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: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cacheFilename</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #990000;">filemtime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cacheFilename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cacheTime</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: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cacheFilename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleXMLElement<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</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;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get XML element from the feed from the live URL.
	 * Will cache XML data to disk.
	 *
	 * @return SimpleXMLElement or null if URL is unreachable.
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getURLXML<span style="color: #009900;">&#40;</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: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			try <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$xml</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleXMLElement<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #990000;">file_put_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCacheFilename</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #b1b100;">return</span> <span style="color: #000088;">$xml</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Name of the cache file for current URL.
	 *
	 * @return string
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getCacheFilename<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;">sys_get_temp_dir</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.feed.cache'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Interface for reading items from feed.
 */</span>
<span style="color: #000000; font-weight: bold;">interface</span> FeedReader <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Create reader from SimpleXMLElement.
	 *
	 * @param SimpleXMLElement $root
	 */</span>
	<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>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get single node.
	 *
	 * @return array or null.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> item<span style="color: #009900;">&#40;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Get number of items.
	 *
	 * @return int.
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Can this reader understand the XML file?
	 *
	 * @param SimpleXMLElement $root
	 * @return bool
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> canRead<span style="color: #009900;">&#40;</span>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Concrete implementation of FeedReader that will never return an item.
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> NullReader implements FeedReader <span style="color: #009900;">&#123;</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>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Nothing</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> <span style="color: #990000;">count</span><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: #009900; font-weight: bold;">null</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> item<span style="color: #009900;">&#40;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> canRead<span style="color: #009900;">&#40;</span>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Concrete implementation of FeedReader that will read an Atom feed.
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> AtomReader implements FeedReader <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$root</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>SimpleXMLElement <span style="color: #000088;">$root</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;">root</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$root</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> <span style="color: #990000;">count</span><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;">root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">entry</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> item<span style="color: #009900;">&#40;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">entry</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$item</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">description</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'image'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'link'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'date'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">published</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">//Iterate through link nodes getting content URL and images.</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</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: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'type'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'link'</span><span style="color: #009900;">&#93;</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;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'link'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'type'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'image'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'image'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>object<span style="color: #009900;">&#41;</span><span style="color: #000088;">$item</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> canRead<span style="color: #009900;">&#40;</span>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Check for Atom namespace.</span>
		<span style="color: #b1b100;">return</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.w3.org/2005/Atom'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNamespaces</span><span style="color: #009900;">&#40;</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>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Concrete implementation of FeedReader that will read an RSS feed.
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> RSSReader implements FeedReader <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$root</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>SimpleXMLElement <span style="color: #000088;">$root</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;">root</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$root</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> <span style="color: #990000;">count</span><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;">root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">channel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</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> item<span style="color: #009900;">&#40;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">channel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$index</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>object<span style="color: #009900;">&#41;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">description</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'url'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'image'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'date'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pubDate</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> static <span style="color: #000000; font-weight: bold;">function</span> canRead<span style="color: #009900;">&#40;</span>SimpleXMLElement <span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//RSS feeds name their root node 'rss'.</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$root</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'rss'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</div>
<p>There are a few things missing, namely any kind of encoding awareness and correct error handling. It also requires SimpleXML and <a href="http://uk2.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a> to be enabled. On the plus side the code is simple enough to hack in new features as they are needed.</p>
<p>I&#8217;m releasing this code under the <a href="http://creativecommons.org/licenses/BSD/">BSD License</a>, so feel free to take and modify it for any purposes.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2010/02/08/simple-atom-rss-reader-for-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter is CRUD</title>
		<link>http://joshduck.com/blog/2008/06/02/twitter-is-crud/</link>
		<comments>http://joshduck.com/blog/2008/06/02/twitter-is-crud/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 22:28:50 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[twitter bandwagon scaling]]></category>

		<guid isPermaLink="false">http://joshduck.com/blog/2008/06/02/twitter-is-crud/</guid>
		<description><![CDATA[Any technical person is interested in solving big challenges. How to scale well (and cheaply) is one of the really big ones; and something that no one really seems to get right. I&#8217;ve read some interesting posts discussing Twitter&#8217;s problems lately (I&#8217;m a little slow to jump on this bandwagon, but like that&#8217;s going to [...]]]></description>
			<content:encoded><![CDATA[<p>Any technical person is interested in solving big challenges. How to scale well (and cheaply) is one of the really big ones; and something that no one really seems to get right. I&#8217;ve read some interesting posts <a href="http://venturebeat.com/2008/05/29/twitter-dont-blame-ruby-blame-scoble/">discussing Twitter&#8217;s problems</a> lately (I&#8217;m a little slow to jump on this bandwagon, but like that&#8217;s going to stop me). I haven&#8217;t been a Twitter-er up until now, but it&#8217;s hard to miss talk of them in the blogosphere.</p>
<p><span id="more-14"></span>While my first, naive, assumptions were that Twitter was a simple read/write system that could be knocked up in a week, numerous people have pointed out the many challenges that the website faces. TechCrunch has revealed that <a href="http://www.techcrunch.com/2008/04/29/end-of-speculation-the-real-twitter-usage-numbers/">Twitter handles 3 million messages</a> a day, from 200,000 active users. Many people have pointed out the fact that some Twitter users have upwards of 30,000 followers, and are themselves following that number of members themselves. This lead to the general consensus that Twitter is really just a giant messaging system, not just your basic <a href="http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete">CRUD</a> setup.</p>
<p>I found this conclusion to be a lot more insightful than the the usual &#8220;Rails sucks&#8221; arguments that are floating around. The view was echoed by a Twitter obsessed friend the other day who asked my opinion on how a hypothetical Twitter clone could be built. He was also of the opinion that the difficult part would be creating a robust messaging system to distribute messages to storage shards and other distribution systems (SMS and any other &#8220;push&#8221; delivery mechanisms). Viewed from that perspective, it becomes an interesting engineering challenge. I&#8217;m sure that a stable system could be built without too many problems.</p>
<p>Based on this line of thought I was pretty surprised to read today that <a href="http://blog.twitter.com/2008/05/its-not-rocket-science-but-its-our-work.html">Twitter is running on a single master MySQL database</a> with just two slaves serving out reads. Ouch. If they ran smoothly then there would be no reason to doubt that the company know what they are doing. However, this is obviously not the case. Even more confusing is an <a href="http://dev.twitter.com/2008/05/youve-got-qs-weve-got-as.html">old blog post</a> in which Twitter developers reveal that their biggest problems occur when users with many followers post. I can&#8217;t really imagine what setup would account for that. It sounds like a denormalized database contained within a single physical server, which just sounds like lot of effort for little gain.</p>
<p>For a company that has just secured a second, $15 million, round of funding their performance is ridiculous. Out of a over <a href="http://www.techcrunch.com/2008/04/28/how-much-is-twitter-worth/">a dozen staff</a> they have only <a href="http://www.techcrunch.com/2008/05/15/blaine-cook-joins-todays-gillmor-gang-talks-twitter/">three or four tech guys</a>. If I were investing I&#8217;d be asking what the hell is going on. I&#8217;m not trying to pretend that Twitter would be an easy fix, I don&#8217;t envy the engineers. They have to maintain their current (failing) product while simultaneously pushing to build a completely different system behind the scenes. I&#8217;ve been there, and it&#8217;s not fun. Apart from having to siphon off precious developer time to keep the old system patched up, they have to face the uphill task of rebuilding <em>everything</em>. Having a huge user-base makes this even more difficult, as they need to get this right first try. No one is going to be happy if an updated version falls over, drops features, or is any way inferior to what they have now. It wouldn&#8217;t be surprising to see the new version of their back end systems continuously delayed far into the future.</p>
<p>It should be interesting to see how and if Twitter recovers from all of this. The user base seems to have been fairly forgiving up until now. Even I signed up knowing all the problems they have. Having many bloggers shouting their praise wont hurt them much. Even the many complaints are free press, really. I doubt an stable Twitter would have been written up on TechCrunch quite so much. They do face the threat of someone stealing their glory though. Each day they have outages is a gift to the dozens of Twitter clones that are undoubtedly out there. Just think Friendster; I&#8217;m sure they&#8217;ll be stable any time now.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshduck.com/blog/2008/06/02/twitter-is-crud/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

