<?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>Simon Wheatley</title>
	<atom:link href="http://simonwheatley.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://simonwheatley.co.uk</link>
	<description>WordPress development and the odd other thing</description>
	<lastBuildDate>Mon, 29 Apr 2013 16:21:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Spot the duplicates, using a Gravatar identicon hack</title>
		<link>http://simonwheatley.co.uk/2013/04/spot-the-duplicates-using-a-gravatar-identicon-hack/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=spot-the-duplicates-using-a-gravatar-identicon-hack</link>
		<comments>http://simonwheatley.co.uk/2013/04/spot-the-duplicates-using-a-gravatar-identicon-hack/#comments</comments>
		<pubDate>Mon, 29 Apr 2013 15:48:15 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2563</guid>
		<description><![CDATA[A project at work needed me to write a UI to find and delete duplicate attachments on a single post, from a client&#8217;s WordPress website. Creating a couple of queries where I could look over each post in turn, and check a hash for each file attached, then spot the duplicate hashes wasn&#8217;t too hard. [...]]]></description>
				<content:encoded><![CDATA[<p>A project <a title="WordPress developers" href="http://codeforthepeople.com/" target="_blank">at work</a> needed me to write a UI to find and delete duplicate attachments on a single post, from a client&#8217;s WordPress website. Creating a couple of queries where I could look over each post in turn, and check a <a title="File hashing article on Wikipedia" href="http://en.wikipedia.org/wiki/Hash_function">hash</a> for each file attached, then spot the duplicate hashes wasn&#8217;t too hard. Where I was struggling was making the rows with the duplicates stand out visually, file hashes, e.g. <code>bc38d8d8993b5e9f4617576d2adeb875</code>, are just not that easy to distinguish from other hashes, e.g. <code>dbe0256fe35b88ebd4e4e433604b7487</code>… see the problem?</p>
<p>What I wanted was some way of mapping a file hash to a colour, or something strongly visual. Which is when it occurred to me; Gravatar could do this!<span id="more-2563"></span></p>
<p>So I pretended all my filehashes were the local portion of email addresses, e.g. <code>dbe0256fe35b88ebd4e4e433604b7487@example.com</code>, and Gravatar auto-generates lovely identicon images for each, and there&#8217;s my visual differentiation. Here&#8217;s what I ended up with:</p>
<p><img class="alignnone size-full wp-image-2564" alt="Gravatar identicons for file hashes" src="http://simonwheatley.co.uk/wp-content/uploads/2013/04/Screenshot_29_04_2013_16_33.jpg" width="444" height="521" /></p>
<p>The <a title="Gravatar API documentation" href="https://en.gravatar.com/site/implement/images/" target="_blank">Gravatar identicon API</a> is really nice and easy to use; you just add an HTML IMG tag to the page and craft a special URL. Here&#8217;s an example:</p>
<pre class="brush: php; title: ; notranslate">&lt;img alt=&quot;&quot; src=&quot;http://www.gravatar.com/avatar/&lt;?php echo md5( &quot;{$hash}@example.com&quot; );&quot; /&gt;?d=identicon&amp;s=30&quot; class=&quot;file-identicon&quot; /&gt;</pre>
<p>The <code>d</code> URL parameter specifies <code>identicon</code>, as you can see, and the <code>s</code> parameter specifies a size of 30 pixels square.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2013/04/spot-the-duplicates-using-a-gravatar-identicon-hack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple Mail sending email from the wrong account</title>
		<link>http://simonwheatley.co.uk/2013/02/apple-mail-sending-email-from-the-wrong-account/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=apple-mail-sending-email-from-the-wrong-account</link>
		<comments>http://simonwheatley.co.uk/2013/02/apple-mail-sending-email-from-the-wrong-account/#comments</comments>
		<pubDate>Fri, 22 Feb 2013 17:33:48 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Apple Mail]]></category>
		<category><![CDATA[Google Apps email]]></category>
		<category><![CDATA[Google Apps outgoing mail server]]></category>
		<category><![CDATA[wrong sender]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2508</guid>
		<description><![CDATA[I&#8217;m currently running Apple Mail with the unified inbox option, so I can connect to my old company email address as well as my Code for the People address and see everything in one place. There&#8217;s settings in Mail to allow you to set the default sending address, and when you reply to a mail [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m currently running Apple Mail with the unified inbox option, so I can connect to my old company email address as well as my <a href="http://codeforthepeople.com/">Code for the People</a> address and see everything in one place. There&#8217;s settings in Mail to allow you to set the default sending address, and when you reply to a mail it should pick the correct account. Trouble was, I kept noticing that my mail was going out under the new account when I was sure I&#8217;d specified the new account to be the sending address. Infuriating and embarrassing.</p>
<p><span id="more-2508"></span></p>
<p>After a few weeks of getting increasingly annoyed with Apple Mail, the problem, as usual, turned out to be elsewhere. Both the old and the new email addresses are part of separate <a href="http://www.google.com/enterprise/apps/business/">Google Apps setups</a>. When I configured my mail accounts in Apple Mail, I hadn&#8217;t been careful when choosing my Outgoing Mail server… both of them were set to the old email account, and Google was silently switching my sender address inside the outgoing mail server.</p>
<p>To fix this, go to: <em>Preferences</em> > <em>Accounts</em> and then pick an account. In the drop down for <em>Outgoing Mail Server (SMTP)</em> choose <em>Edit SMTP Server List…</em>. Make sure that all your SMTP servers are named clearly and have the right credentials in them, you should have one SMTP for each of your Google Apps accounts. Then Click <em>OK</em> to close this dialog. You are now back on the Accounts preferences screen, now make sure the right outgoing server is selected in each of your accounts.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2013/02/apple-mail-sending-email-from-the-wrong-account/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replacing a Kidde Fyrnetics 123/9HI Smoke Alarm</title>
		<link>http://simonwheatley.co.uk/2013/02/replacing-a-kidde-fyrnetics-1239hi-smoke-alarm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=replacing-a-kidde-fyrnetics-1239hi-smoke-alarm</link>
		<comments>http://simonwheatley.co.uk/2013/02/replacing-a-kidde-fyrnetics-1239hi-smoke-alarm/#comments</comments>
		<pubDate>Sat, 02 Feb 2013 13:12:36 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[123/9HI]]></category>
		<category><![CDATA[DIY]]></category>
		<category><![CDATA[fitting]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[kidde]]></category>
		<category><![CDATA[kidde fyrnetics]]></category>
		<category><![CDATA[smoke alarm]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2483</guid>
		<description><![CDATA[The alarm in question looks like this: The red light indicates a fault, which is why I&#8217;ve finally confronted my inability to remove it (hopefully your smoke alarm fault-free). I&#8217;ve found the Kidde instructions on this to be infuriatingly vague on how you actually detach the unit from the base, so as I had to [...]]]></description>
				<content:encoded><![CDATA[<p>The alarm in question looks like this:</p>
<p><a href="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8483.jpg"><img src="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8483-300x224.jpg" alt="" title="IMG_8483" width="300" height="224" class="size-medium wp-image-2484" /></a></p>
<p>The red light indicates a fault, which is why I&#8217;ve finally confronted my inability to remove it (hopefully your smoke alarm fault-free).</p>
<p><span id="more-2483"></span></p>
<p>I&#8217;ve found the Kidde instructions on this to be infuriatingly vague on how you actually detach the unit from the base, so as I had to go through a lot of swearing to work it out, I figured some other people might have the same problem. Why are instruction manuals often so badly written?</p>
<p>The side of the alarm has the arrows to twist clockwise for &#8220;off&#8221; and anti-clockwise for &#8220;on&#8221;, but there is a small lug which prevents the unit from twisting. Here&#8217;s the lug:</p>
<p><a href="http://simonwheatley.co.uk/wp-content/uploads/2013/02/lug-2.png"><img src="http://simonwheatley.co.uk/wp-content/uploads/2013/02/lug-2-224x300.png" alt="A Kidde Fyrnetics 123/9HI Smoke Alarm" width="224" height="300" class="size-medium wp-image-2490" /></a></p>
<p>Use a small screwdriver, or other poking device, to push this lug towards the base of the smoke alarm, like so, and you will be able to twist the unit free of the base:</p>
<p><a href="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8486.jpg"><img src="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8486-224x300.jpg" alt="Locking lug on Kidde Fyrnetics 123/9HI Smoke Alarm" width="224" height="300" class="size-medium wp-image-2486" /></a></p>
<p>The unit will still be attached to the base by the power plug. The plug has two catches on either site, like this, squeeze them together:</p>
<p><a href="http://simonwheatley.co.uk/wp-content/uploads/2013/02/plug.png"><img src="http://simonwheatley.co.uk/wp-content/uploads/2013/02/plug-300x224.png" alt="Catches on plug within a Kidde Fyrnetics 123/9HI Smoke Alarm" width="300" height="224" class="size-medium wp-image-2491" /></a></p>
<p>You can see the catches in this photo:</p>
<p><a href="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8490.jpg"><img src="http://simonwheatley.co.uk/wp-content/uploads/2013/02/IMG_8490-300x224.jpg" alt="Plug within a Kidde Fyrnetics 123/9HI Smoke Alarm" width="300" height="224" class="size-medium wp-image-2492" /></a></p>
<p>The end. Remember to only remove your smoke alarms temporarily, and refit them as soon as possible!</p>
<p>(N.B: I believe this alarm is discontinued by Kidde.)</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2013/02/replacing-a-kidde-fyrnetics-1239hi-smoke-alarm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Protecting staging sites with Basic Authentication</title>
		<link>http://simonwheatley.co.uk/2013/01/protecting-staging-sites-with-basic-authentication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=protecting-staging-sites-with-basic-authentication</link>
		<comments>http://simonwheatley.co.uk/2013/01/protecting-staging-sites-with-basic-authentication/#comments</comments>
		<pubDate>Thu, 17 Jan 2013 12:35:18 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[Apache environment variables]]></category>
		<category><![CDATA[Deny]]></category>
		<category><![CDATA[htpasswd]]></category>
		<category><![CDATA[HTTP Basic Authentication]]></category>
		<category><![CDATA[Satisfy]]></category>
		<category><![CDATA[server admin]]></category>
		<category><![CDATA[SetEnvIf]]></category>
		<category><![CDATA[WP Engine]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2465</guid>
		<description><![CDATA[This approach was primarily devised for use with WP Engine staging sites, but will work in any situation where you have no access to Apache&#8217;s config and need to use a single .htaccess file for multiple domains (e.g. a multisite setup). We&#8217;ve recently had a couple of projects hosted on WPEngine where we need to [...]]]></description>
				<content:encoded><![CDATA[<p><em>This approach was primarily devised for use with WP Engine staging sites, but will work in any situation where you have no access to Apache&#8217;s config and need to use a single <var>.htaccess</var> file for multiple domains (e.g. a multisite setup).</em></p>
<p><a href="http://codeforthepeople.com/">We&#8217;ve</a> recently had a couple of projects hosted on <a href="http://wpengine.com/">WPEngine</a> where we need to have a staging site protected by <a href="http://httpd.apache.org/docs/current/howto/auth.html">Basic Authentication</a> so only authorised users can access it. Normally I would configure Basic Authentication in the Apache VirtualHost, but on WP Engine (for example) they handle all the server configuration for us, meaning we don&#8217;t have access to the Apache configuration. WPEngine also provide a <a href="http://git.wpengine.com/">Git push to deploy</a> facility, which we tend to take advantage of because Version Control Rools, OK? Because all the web files are within Git version control, we are using the same <var>.htaccess</var> file for the developer, staging and live sites. (We could Git ignore the <var>.htacess</var> file, but I prefer to version control more, rather than less.)</p>
<p><span id="more-2465"></span></p>
<p>The approach we&#8217;ve taken is to put the code into the <var>.htaccess</var> file and to detect the domain of the staging site, and require them to enter the Basic Authentication username and password before proceeding. Let&#8217;s look at both stages of that process.</p>
<p>First we need to detect the domain we want to require authentication for, we do this using the <var>SetEnvIf</var> directive from Apache&#8217;s <a href="http://httpd.apache.org/docs/current/mod/mod_setenvif.html">mod_setenvif</a> module to examine the <var>Host</var> using a <a href="http://www.regular-expressions.info/">regex</a>. If the <var>Host</var> matches the regex, then we set an Apache <a href="http://httpd.apache.org/docs/current/env.html">Environment Variable</a>, which acts as a flag for a later conditional check. Here&#8217;s that directive:</p>
<pre class="brush: bash; title: ; notranslate">
# Detect the domain host and set a variable telling us to use auth
SetEnvIf Host staging.wpengine.com$ CFTP_USE_AUTH
</pre>
<p>Now we&#8217;ve set the flag we can check for it, using <a href="http://httpd.apache.org/docs/current/mod/mod_access_compat.html">mod_access_compat</a>, and issue a <var><a href="http://httpd.apache.org/docs/current/mod/mod_access_compat.html#Deny">Deny</a></var> Directive for all visitors with the Environment Variable flag set. Because we have initially set the <var>Order</var> to <var>deny,allow</var>, this <var>Deny</var> means nobody with this Environment Variable set is allowed to visit the site… we&#8217;ll take care of that later down the code. Here&#8217;s the conditional <var>Deny</var> directive:</p>
<pre class="brush: bash; title: ; notranslate">
# Detect the variable telling us to use auth and deny
Deny from env=CFTP_USE_AUTH
</pre>
<p>The next line uses the <var>Satisfy</var> directive to allow any visitors which pass one or other of the access requirements; in this case <em>either</em> they do not have the <var>CFTP_USE_AUTH</var> Environment Variable set (because the host does not match), <em>or</em> they have entered valid authentication details.</p>
<pre class="brush: bash; title: ; notranslate">
Satisfy any
</pre>
<p>Then there&#8217;s the Basic Authentication rules, which are fairly standard:</p>
<pre class="brush: bash; title: ; notranslate">
# Basic authentication
AuthType Basic
AuthName &quot;Nothing to see here. Move along, please&quot;
Require valid-user
</pre>
<p>…until you get the the location of the <var>AuthUserFile</var>, which is only worthy of mention in that you need to provide a path to it. I decided to <a href="http://httpd.apache.org/docs/current/programs/htpasswd.html">generate the .htpasswd file</a> on my development server and keep it in the document root, which is under version control, because Version Control Rools, OK? We do some jiggery pokery later to ensure that nobody can view the <var>.htpasswd</var> file over HTTP or HTTPS.</p>
<pre class="brush: bash; title: ; notranslate">
# N.B. This path will be specific to your server setup
AuthUserFile /the/path/to/the/document/root/.htpasswd
</pre>
<p>We use a <var><a href="http://httpd.apache.org/docs/2.4/mod/core.html#files">Files</a></var> directive to <var>Deny</var> access to any files called <var>.htpasswd</var> to anyone and everyone (note the <code>Satisfy All</code>, that&#8217;s important):</p>
<pre class="brush: bash; title: ; notranslate">
# Don't allow the .htpassword file to be shown to web users
&lt;Files .htpasswd&gt;
   Order allow,deny
   Deny from all
   Satisfy All 
&lt;/Files&gt; 
</pre>
<p>The complete rules are below…</p>
<pre class="brush: bash; title: ; notranslate">
Order deny,allow

# Detect the domain host and set a variable telling us to use auth
SetEnvIf Host staging.wpengine.com$ CFTP_USE_AUTH

# Detect the variable telling us to use auth and deny
Deny from env=CFTP_USE_AUTH

Satisfy any

# Basic authentication
AuthType Basic
AuthName &quot;Nothing to see here. Move along, please&quot;
Require valid-user

# N.B. This path will be specific to your server setup
AuthUserFile /the/path/to/the/document/root/.htpasswd

# Don't allow the .htpassword file to be shown to web users
&lt;Files .htpasswd&gt;
   Order allow,deny
   Deny from all
   Satisfy All 
&lt;/Files&gt; 
</pre>
<p>Just one more thing… what if you want to allow unrestricted access to some URLs in the site? To accomplish this you can identify them with more <var>SetEnvIf</var> directives, and set a different flag which allows the authentication to be bypassed. Here&#8217;s a set of rules which shows this in action:</p>
<pre class="brush: bash; title: ; notranslate">
Order deny,allow

# Detect the domain host and set a variable telling us to use auth
SetEnvIf Host staging.wpengine.com$ CFTP_USE_AUTH

# Detect some link structure and set a bypass variable
SetEnvIf Request_URI ^/whatever/[0-9]+/?$ CFTP_BYPASS_AUTH

# Detect the variable telling us to use auth and deny
Deny from env=CFTP_USE_AUTH

# Allow the redirects we've detected
Allow from env=CFTP_BYPASS_AUTH

Satisfy any

# Basic authentication
AuthType Basic
AuthName &quot;Nothing to see here. Move along, please&quot;
Require valid-user

# N.B. This path will be specific to your server setup
AuthUserFile /the/path/to/the/document/root/.htpasswd

# Don't allow the .htpassword file to be shown to web users
&lt;Files .htpasswd&gt;
   Order allow,deny
   Deny from all
   Satisfy All 
&lt;/Files&gt; 
</pre>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2013/01/protecting-staging-sites-with-basic-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Not New York, Manchester</title>
		<link>http://simonwheatley.co.uk/2012/12/not-new-york-manchester/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=not-new-york-manchester</link>
		<comments>http://simonwheatley.co.uk/2012/12/not-new-york-manchester/#comments</comments>
		<pubDate>Sat, 22 Dec 2012 15:00:18 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Bikes]]></category>
		<category><![CDATA[Fire Escape]]></category>
		<category><![CDATA[graffiti]]></category>
		<category><![CDATA[photo]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2447</guid>
		<description><![CDATA[.]]></description>
				<content:encoded><![CDATA[<p>.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/12/not-new-york-manchester/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A plugin to clear recalcitrant caches from inside WP Engine</title>
		<link>http://simonwheatley.co.uk/2012/11/wpengine-clear-url-cache/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wpengine-clear-url-cache</link>
		<comments>http://simonwheatley.co.uk/2012/11/wpengine-clear-url-cache/#comments</comments>
		<pubDate>Thu, 29 Nov 2012 12:07:05 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cache clearance]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[http purge]]></category>
		<category><![CDATA[non-200 cache]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2429</guid>
		<description><![CDATA[We&#8217;re using WP Engine to host various clients, notably the Rolling Stones site, and we&#8217;ve been very pleased with both the service and the performance of their hosting platform. There&#8217;s always something though, isn&#8217;t there? I don&#8217;t think I&#8217;d really be happy if there wasn&#8217;t. In this case it&#8217;s the fact the Varnish caching layer [...]]]></description>
				<content:encoded><![CDATA[<p>We&#8217;re using <a href="http://bit.ly/cftp-wpengine" title="Code for the People's affiliate link to WP Engine" target="_blank">WP Engine</a> to host various clients, notably <a href="http://www.rollingstones.com/" target="_blank">the Rolling Stones</a> site, and we&#8217;ve been very pleased with both the service and the performance of their hosting platform. There&#8217;s always something though, isn&#8217;t there? I don&#8217;t think I&#8217;d really be happy if there wasn&#8217;t. In this case it&#8217;s the fact the Varnish caching layer that sits between the site and the visitors caches &#8220;non-200&#8243; responses for 24 hours. So what does all that mean? What&#8217;s the actual problem here?<span id="more-2429"></span></p>
<p><em>What is Varnish caching?</em> Well, &#8220;Varnish is a reverse proxy cache&#8221; <em>…but what is a reverse proxy cache, you say?</em> A reverse proxy cache sits between your website and the broader internet (where all the people and things that want to see your site are) and, according to a set of rules, caches responses somehow and serves them back super quick to the requests for URLs at your site. So your site generates a response, which might take some time due to database queries, requests to Twitter for the latest tweets, etc, etc, then the reverse proxy cache (Varnish, in this case) saves the response and returns it for requests without bothering the site to create the response from scratch… hey presto, much faster responses!</p>
<p>WP Engine have their Varnish configured to cache responses for 24 hours for non-200 responses. <em>What are &#8220;non-200 responses&#8221;, you say?</em> Every response to a request for a URL is assigned a response code, you can read <a title="HTTP 1.1 Status Code Definitions" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">them all</a> over at the W3C (or you can read the much more amusing <a href="http://www.httpstatusrappers.com/" target="_blank">HTTP $tatu$ Rapper$</a>). The main response codes we&#8217;re concerned with are <var>200</var> (&#8220;OK&#8221; – the request has succeeded) and <var>404</var> (&#8220;not found&#8221; – the requested resource has, errrr, not been found), there&#8217;s also various redirection codes <var>301</var> or <var>302</var>.</p>
<p>The upshot of all this is that once a <var>404</var>, <var>301</var> or <var>302</var> response is issued by a website on WP Engine, it remains in use for 24 hours unless something clears it deliberately. The major scenario of having a <var>404</var> response and then publishing something at that URL is covered, as you&#8217;d expect the cache gets automatically cleared, however there are the odd situations where I&#8217;ve needed to clear a cache for whatever reason (perhaps to replace a <var>404</var> with a redirect of some kind) and then I&#8217;ve been stuck staring at the 24 hour cached response and grinding my teeth.</p>
<p>Enter the <a href="https://github.com/simonwheatley/WPEngine-Clear-URL-Cache" target="_blank">WP Engine Cache Sniper plugin</a> (actually I&#8217;ve called it &#8220;WPEngine Clear URL Cache&#8221;, which is quite a bit more boring). This plugin provides a simple &#8220;Clear URL Cache&#8221; link under the &#8220;Tools&#8221; menu in the admin area, here you can enter a URL and have the cache cleared on that URL. Problem solved.</p>
<p>Caveats: The plugin is specific to WP Engine, and won&#8217;t work on other services. If you try and install it on a non-WP Engine hosting service it will put a whinging notice throughout the admin, advising you to uninstall. If you try to <em>use</em> it on a non-WP Engine hosting service then it <em>will</em> kill a kitten, you may not see the kitten die and it may not be your kitten… but really, do you want that on your conscience? Oh and you might trigger an error in your site, who knows.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/11/wpengine-clear-url-cache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What happened at the WordPress Community Summit (presentation)</title>
		<link>http://simonwheatley.co.uk/2012/11/wordpress-community-summit-2012/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress-community-summit-2012</link>
		<comments>http://simonwheatley.co.uk/2012/11/wordpress-community-summit-2012/#comments</comments>
		<pubDate>Thu, 22 Nov 2012 14:19:39 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Georgia]]></category>
		<category><![CDATA[Manchester WordPress User Group]]></category>
		<category><![CDATA[MWUG]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[Tybee Island]]></category>
		<category><![CDATA[WordPress Community Summit]]></category>
		<category><![CDATA[WPCS]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2426</guid>
		<description><![CDATA[Here&#8217;s the presentation I gave to Manchester WordPress User Group last night on the first WordPress Community Summit in 2012. Here&#8217;s Jane Wells&#8217; initial post explaining the thinking behind the summit. If you want to learn more about what&#8217;s going on, you can see the summaries posted on the day for the morning and the [...]]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s the presentation I gave to <a title="MWUG" href="http://mwug.info/2012/11/november-meeting-wednesday-21st-6-30-9pm-madlab/" target="_blank">Manchester WordPress User Group</a> last night on the first <a title="WordPress Community Summit site" href="http://make.wordpress.org/summit/" target="_blank">WordPress Community Summit</a> in 2012. Here&#8217;s Jane Wells&#8217; initial post explaining <a href="http://make.wordpress.org/summit/2012/08/07/the-wordpress-community-summit-is-a-by-invitation/" target="_blank">the thinking behind the summit</a>.</p>
<p><iframe allowfullscreen="true" allowtransparency="true" frameborder="0" height="532" id="talk_frame_24580" mozallowfullscreen="true" src="//speakerdeck.com/player/f6aea220164e0130129912313b101676" style="border:0; padding:0; margin:0; background:transparent;" webkitallowfullscreen="true" width="625"></iframe></p>
<p>If you want to learn more about what&#8217;s going on, you can see the summaries posted on the day for the <a title="summary of the WordPress Community Summit morning discussions" href="http://make.wordpress.org/summit/2012/10/29/summary-of-morning-discussions/" target="_blank">morning</a> and the <a title="summary of the WordPress Community Summit afternoon discussions" href="http://make.wordpress.org/summit/2012/10/29/summary-of-afternoon-discussions/" target="_blank">afternoon</a>, and watch the <a title="WordPress Community Summit Notes" href="http://make.wordpress.org/summit/category/notes/" target="_blank">&#8220;notes&#8221; category archive</a> as the session notes are going up now.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/11/wordpress-community-summit-2012/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting HTTP Basic Authentication based on the host name</title>
		<link>http://simonwheatley.co.uk/2012/10/hostname-http-basic-authentication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hostname-http-basic-authentication</link>
		<comments>http://simonwheatley.co.uk/2012/10/hostname-http-basic-authentication/#comments</comments>
		<pubDate>Tue, 09 Oct 2012 17:54:28 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[HTTP Basic Authentication]]></category>
		<category><![CDATA[SetEnvIf]]></category>
		<category><![CDATA[staging]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2408</guid>
		<description><![CDATA[For many of our projects, the .htaccess file is under version control… but at the same time, I need to put HTTP Basic Authentiation on just the staging site. Unfortunately the host weren&#8217;t able to do this for me, but with a little .htaccess trickery I was able to detect the staging site URL and [...]]]></description>
				<content:encoded><![CDATA[<p>For many of our projects, the <var>.htaccess</var> file is under version control… but at the same time, I need to put HTTP Basic Authentiation on just the staging site. Unfortunately the host weren&#8217;t able to do this for me, but with a little .htaccess trickery I was able to detect the staging site URL and trigger the authentication.</p>
<p>Why do I want to do this? Well, pretty often the client is keen to see how some new, embargoed, content is going to fit together, whether that&#8217;s a group of new pages or a new masthead, etc. I don&#8217;t want just anyone guessing my staging site URL and wandering around getting information they shouldn&#8217;t!<span id="more-2408"></span></p>
<p>The key, as is often the case, was in a <a href="http://stackoverflow.com/questions/4068975/domain-name-specific-code-blocks-in-htaccess">Stack Overflow post</a>. Let me walk you through the specifics:</p>
<pre class="brush: bash; title: ; notranslate">
# Detect the domain host and set an environment var for staging
SetEnvIf Host staging\.somewhere\.com$ TRS_IS_STAGING
Order deny,allow
# Detect the staging environment var
Deny from env=TRS_IS_STAGING
Satisfy any
AuthType Basic
AuthName &quot;Nothing to see here. Move along, please&quot;
# We rely on this rule only being applied on staging,
# as it will break everywhere else
AuthUserFile /nas/wp/www/staging/promotone/.htpasswd
Require valid-user

# Hide the htpasswd file
&lt;Files .htpasswd&gt;
	Order allow,deny
	Deny from all
	Satisfy All
&lt;/Files&gt;
</pre>
<p>The first block of the file uses a simple regex to check if the <code>Host</code> environment variable ends with <var>staging.somewhere.com</var>, and if it does it sets a further environment variable called <var>TRS_IS_STAGING</var>. The config is then set to <code>Deny</code> any request where the <var>TRS_IS_STAGING</var> environment variable is set. Because <code>Satisfy any</code> is present, Apache will then attempt to use the Basic Authentication set in the next few lines with <code>AuthType</code>, <code>AuthName</code>, <code>AuthUserFile</code>.</p>
<p>Note that the <code>AuthUserFile</code> directive needs a filepath which is either absolute or relative to the <var>ServerRoot</var>, either way it&#8217;s pretty specific to the server setup. That&#8217;s fine in this case, but you would need to differentiate between each server setup and the path for it if you wanted to add authentication to more than one server.</p>
<p>Lastly, I&#8217;m hiding the <var>.htpasswd</var>; it&#8217;s not ideal that it&#8217;s web available (i.e. in the <var>DocumentRoot</var>) but that&#8217;s the limitations of the hosting environment I&#8217;m dealing with.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/10/hostname-http-basic-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Competition in open source</title>
		<link>http://simonwheatley.co.uk/2012/10/competition-in-open-source/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=competition-in-open-source</link>
		<comments>http://simonwheatley.co.uk/2012/10/competition-in-open-source/#comments</comments>
		<pubDate>Sun, 07 Oct 2012 11:19:47 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Quotes]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2407</guid>
		<description><![CDATA[&#8220;Cooperate on a technical level and compete on a business level.&#8221; Jeffrey McGuire, Acquia Seen on a slide at PHPNW12, I like this summary of how companies interrelate in open source.]]></description>
				<content:encoded><![CDATA[<blockquote><p>&#8220;Cooperate on a technical level and compete on a business level.&#8221;<br />
<cite>Jeffrey McGuire, Acquia</cite></p></blockquote>
<p>Seen on a slide at PHPNW12, I like this summary of how companies interrelate in open source.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/10/competition-in-open-source/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHPNW12: Application logging</title>
		<link>http://simonwheatley.co.uk/2012/10/phpnw12-application-logging/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=phpnw12-application-logging</link>
		<comments>http://simonwheatley.co.uk/2012/10/phpnw12-application-logging/#comments</comments>
		<pubDate>Sun, 07 Oct 2012 11:00:56 +0000</pubDate>
		<dc:creator>simonwheatley</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[application logging]]></category>
		<category><![CDATA[error_log]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[Monolog]]></category>
		<category><![CDATA[PHPNW]]></category>
		<category><![CDATA[PHPNW12]]></category>

		<guid isPermaLink="false">http://simonwheatley.co.uk/?p=2406</guid>
		<description><![CDATA[Ben Waine&#8217;s (@bwaine) talk at PHPNW12 on application logging. As usual, these are my thoughts, misunderstandings and mishearings…corrections welcome in the comments. So, can logging be cool? Why log? Patterns and trends, information after the fact. tail -f FTW About the Skybet application log: Signposts everything when it happens. Good way to learn the path [...]]]></description>
				<content:encoded><![CDATA[<p><em>Ben Waine&#8217;s (<a href="http://Twitter.com/bwaine">@bwaine</a>) talk at PHPNW12 on application logging. As usual, these are my thoughts, misunderstandings and mishearings…corrections welcome in the comments. </em></p>
<p>So, can logging be cool?</p>
<p><span id="more-2406"></span></p>
<p>Why log? Patterns and trends, information after the fact.</p>
<p>tail -f FTW</p>
<p>About the Skybet application log:</p>
<ul>
<li>Signposts everything when it happens. Good way to learn the path through the layers.</li>
<li>Good visible errors. </li>
<li>Logs the start and end of request, including memory consumed, so you can spot waiting and memory trends.</li>
</ul>
<p><strong>Moving on to methods of logging</strong></p>
<p>error_log. (Can be sent to stdout for situations when running in the CLI):<br />
Pros: native<br />
Cons: ini can be overwritten</p>
<p>Various logging libraries,  ZendLog and monolog. Prefer: Monolog. Well maintained, good feature set. </p>
<p>Fingers crossed handler: logs to memory, but only to disk if condition X occurs.</p>
<p>Allows different levels of logging: error, notice, info, etc.<br />
Different log writers: file, email, firebug, etc, etc, can write your own.</p>
<p><strong>Your application logger</strong></p>
<p>Handy to set a unique request ID. Can spot an issue, and grep the log for all activity on that request. </p>
<p>Logger is passed MLogger on construction.</p>
<p>Different logs: application log and security log. Different information logged (cleary).</p>
<p><strong>Event logging</strong></p>
<p>Things which happen (in your system) get logged. </p>
<p>Graphite + statsd – Statsd has buckets which periodically get sent to Graphite. Your application logger can have a method to increment statsd, statsd sometimes sends to Graphite and graphs appear magically.</p>
<p>Can get more efficient than sending data from your app.</p>
<p><strong>Strategy</strong></p>
<ul>
<li>Choose a consistent logging style</li>
<li>Centrally deal with formatting</li>
<li>Consistency, consistency, consistency</li>
</ul>
<p><strong>Log:</strong></p>
<ul>
<li>Request start and end</li>
<li>Transitions between layers</li>
<li>DB queries</li>
<li>Biz events (separate log)</li>
<li>Message queue activity</li>
<li>Errors and notices from PHP</li>
</ul>
<p>Avoid leaving crazy debug lines in that others have to filter out. Make sure content is greppable.</p>
<p>Log aggregation: rsyslog, logstash.net (really handy, can also send to statsd lots of inputs, filters, outputs).</p>
<p>Hosted: splunk, loggly, new relic. </p>
<p>The only question: Is an event based logger a good plan? Yes, avoids dependencies on classes.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonwheatley.co.uk/2012/10/phpnw12-application-logging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
