<?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>The Code Train &#187; php</title>
	<atom:link href="http://thecodetrain.co.uk/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://thecodetrain.co.uk</link>
	<description>Where Neil Crosby talks about coding on the train...</description>
	<lastBuildDate>Sun, 03 Apr 2011 18:15:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Adding a vCard to your iPhone Address Book from a web page</title>
		<link>http://thecodetrain.co.uk/2009/11/adding-a-vcard-to-your-iphone-address-book-from-a-web-page/</link>
		<comments>http://thecodetrain.co.uk/2009/11/adding-a-vcard-to-your-iphone-address-book-from-a-web-page/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 00:43:52 +0000</pubDate>
		<dc:creator>Neil Crosby</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[addressbook]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobilesafari]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scratching an itch]]></category>
		<category><![CDATA[vcard]]></category>

		<guid isPermaLink="false">http://thecodetrain.co.uk/?p=334</guid>
		<description><![CDATA[<p>It can&#8217;t be done. Well, not obviously anyway.</p>

<p>A couple of weeks ago, I realised that <a href="http://neilcrosby.com/vcard">my public vCard</a> was less useful than it might be.  One of the specific reasons that I created it was to make it easy for people to add a bunch of my contact information to their address books when I met them, rather than them having to manually type in a whole load of stuff that was on a business card.  It turns out that this is great when that person&#8217;s sat at their own computer, but if they&#8217;re (for example) using an iPhone then things become a little more difficult.</p>

<p>You see, the iPhone doesn&#8217;t like to use MobileSafari to download files.  That&#8217;s fine in general &#8211; you don&#8217;t get a filesystem to peruse on the iPhone, so the only way that downloads would be useful is if the iPhone already knows what to do with them.  That&#8217;s why applications are allowed to register their own custom URL schemes. </p>

<p>Unfortunately, by default the iPhone only registers <a href="http://developer.apple.com/safari/library/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html">a few URL schemes</a> for use within web pages &#8211; <code>mailto:</code>, <code>tel:</code> and <code>sms:</code> as pseudo protocols, as well as specific URL structures for Google Maps, YouTube and iTunes links.  This makes it impossible to do things like adding an address to the Address Book or an event to the Calendar with a single click on a link in a webpage &#8211; you just get a message that reads &#8220;Download failed. Safari cannot download this file&#8221;.</p>

<p>This is clearly a pain. As a phone, it seems reasonable that you should be able to easily add contacts to your Address Book. Unfortunately, either Apple thinks you shouldn&#8217;t be able to do this from a webpage or they just didn&#8217;t consider it as a usecase.</p>

<p>It turns out that they did consider that you might like to open email attachments though. If someone sends you an email that contains a VCF file then you <em>are</em> able to open it and see its contents. If you then scroll down to the bottom of the file you&#8217;re greeted with two options, allowing you to &#8220;Create New Contact&#8221; or &#8220;Add to Existing Contact&#8221;.  Suddenly a world full of contact adding goodness is opened up to you.</p>

<p>So, what I&#8217;ve decided to do with my vCard is a little bit of user agent sniffing in my PHP. Currently I assume that every other device in the world other than the iPhone will do something sensible with the normal VCF file (or the microformatted data that&#8217;s on the page itself), so I listen out for the iPhone&#8217;s user agent. If I see it then I swap out the link to download the VCF file with one that takes the user to a page containing a form allowing them to enter their email address. Once they do, the VCF file is immediately emailed to them and they can add my card to their address book.</p>

<p>Right now the look and feel of the <a href="http://neilcrosby.com/vcard/via-email/">the email form</a> that iPhone users are directed to could be described as rudimentary at best, but it works.  At some point in the future I&#8217;ll get round to making it look a bit more pretty.</p>

<p>As a solution, I&#8217;m fairly happy with this.  Whilst it&#8217;s nowhere near as nice as being able to simply click on a link and add a contact to your address book, it does at least mean that it becomes possible to add a contact from a web page.  Certainly it&#8217;s a better solution than not allowing users access to the content at all.  It&#8217;s also entirely possible that this solution would work for other filetypes, such as calendar events.</p>

<p>My only concern is that this problem may be in existence in other devices other than the iPhone as well.  It would almost certainly make sense to make the email option available to users of other devices as well.</p>

<p>So there you have it &#8211; to allow a user to add a contact to their Address Book from a webpage on the iPhone don&#8217;t try and get them to download it, let them receive it via email instead. </p>
<div style="display:block"><small><em><a href="http://neilcrosby.com">Neil Crosby</a> also blogs at about t-shirts at <a href="http://iwearcotton.com">I Wear Cotton</a>, writes <a href="http://thetenwordreview.com/users/workingwithme">Ten Word Reviews</a>, and uploads <a href="http://www.flickr.com/photos/thevoicewithin/">photos</a> to flickr.  You can follow a combined feed of posts at <a href="http://neilcrosby.com/">NeilCrosby.com</a>.</em></small></div>]]></description>
			<content:encoded><![CDATA[<p>It can&#8217;t be done. Well, not obviously anyway.</p>

<p>A couple of weeks ago, I realised that <a href="http://neilcrosby.com/vcard">my public vCard</a> was less useful than it might be.  One of the specific reasons that I created it was to make it easy for people to add a bunch of my contact information to their address books when I met them, rather than them having to manually type in a whole load of stuff that was on a business card.  It turns out that this is great when that person&#8217;s sat at their own computer, but if they&#8217;re (for example) using an iPhone then things become a little more difficult.</p>

<p>You see, the iPhone doesn&#8217;t like to use MobileSafari to download files.  That&#8217;s fine in general &#8211; you don&#8217;t get a filesystem to peruse on the iPhone, so the only way that downloads would be useful is if the iPhone already knows what to do with them.  That&#8217;s why applications are allowed to register their own custom URL schemes. </p>

<p>Unfortunately, by default the iPhone only registers <a href="http://developer.apple.com/safari/library/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html">a few URL schemes</a> for use within web pages &#8211; <code>mailto:</code>, <code>tel:</code> and <code>sms:</code> as pseudo protocols, as well as specific URL structures for Google Maps, YouTube and iTunes links.  This makes it impossible to do things like adding an address to the Address Book or an event to the Calendar with a single click on a link in a webpage &#8211; you just get a message that reads &#8220;Download failed. Safari cannot download this file&#8221;.</p>

<p>This is clearly a pain. As a phone, it seems reasonable that you should be able to easily add contacts to your Address Book. Unfortunately, either Apple thinks you shouldn&#8217;t be able to do this from a webpage or they just didn&#8217;t consider it as a usecase.</p>

<p>It turns out that they did consider that you might like to open email attachments though. If someone sends you an email that contains a VCF file then you <em>are</em> able to open it and see its contents. If you then scroll down to the bottom of the file you&#8217;re greeted with two options, allowing you to &#8220;Create New Contact&#8221; or &#8220;Add to Existing Contact&#8221;.  Suddenly a world full of contact adding goodness is opened up to you.</p>

<p>So, what I&#8217;ve decided to do with my vCard is a little bit of user agent sniffing in my PHP. Currently I assume that every other device in the world other than the iPhone will do something sensible with the normal VCF file (or the microformatted data that&#8217;s on the page itself), so I listen out for the iPhone&#8217;s user agent. If I see it then I swap out the link to download the VCF file with one that takes the user to a page containing a form allowing them to enter their email address. Once they do, the VCF file is immediately emailed to them and they can add my card to their address book.</p>

<p>Right now the look and feel of the <a href="http://neilcrosby.com/vcard/via-email/">the email form</a> that iPhone users are directed to could be described as rudimentary at best, but it works.  At some point in the future I&#8217;ll get round to making it look a bit more pretty.</p>

<p>As a solution, I&#8217;m fairly happy with this.  Whilst it&#8217;s nowhere near as nice as being able to simply click on a link and add a contact to your address book, it does at least mean that it becomes possible to add a contact from a web page.  Certainly it&#8217;s a better solution than not allowing users access to the content at all.  It&#8217;s also entirely possible that this solution would work for other filetypes, such as calendar events.</p>

<p>My only concern is that this problem may be in existence in other devices other than the iPhone as well.  It would almost certainly make sense to make the email option available to users of other devices as well.</p>

<p>So there you have it &#8211; to allow a user to add a contact to their Address Book from a webpage on the iPhone don&#8217;t try and get them to download it, let them receive it via email instead. </p>
]]></content:encoded>
			<wfw:commentRss>http://thecodetrain.co.uk/2009/11/adding-a-vcard-to-your-iphone-address-book-from-a-web-page/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Displaying your current remote iTunes Playlist on your local Mac&#8217;s Dashboard</title>
		<link>http://thecodetrain.co.uk/2009/11/displaying-your-current-remote-itunes-playlist-on-your-local-macs-dashboard/</link>
		<comments>http://thecodetrain.co.uk/2009/11/displaying-your-current-remote-itunes-playlist-on-your-local-macs-dashboard/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 12:16:33 +0000</pubDate>
		<dc:creator>Neil Crosby</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[itunes]]></category>
		<category><![CDATA[mamp]]></category>
		<category><![CDATA[osascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scratching an itch]]></category>

		<guid isPermaLink="false">http://thecodetrain.co.uk/?p=315</guid>
		<description><![CDATA[<p>In my last blog entry, I wrote about &#8220;<a href="http://thecodetrain.co.uk/2009/10/controlling-itunes-across-multiple-computers-with-the-keyboard/">Controlling iTunes across multiple computers with the keyboard</a>&#8221; (snappy title, huh?).  In it, I promised that the next step was to work out how to get the current playlist displaying on the dashboard.  So, here goes&#8230;</p>

<p><a class="sidenote" href="http://www.flickr.com/photos/thevoicewithin/4102944794/" title="Remote viewing the currently playing iTunes playlist by Neil Crosby, on Flickr"><img src="http://farm3.static.flickr.com/2475/4102944794_483cf765f4.jpg" width="500" height="313" alt="Remote viewing the currently playing iTunes playlist" /></a></p>

<p>The first thing to be aware of is that if Safari can display something on a webpage, then Dashboard can display it as well.  If you visit a page in Safari and right-click somewhere on the background of the page then you should see a menu item titled <code>Open in Dashboard...</code>. If you select this then you&#8217;ll be able to drag to select an area of the page to turn into a dashboard widget.  Click the <code>Add</code> button at the top of the window once you&#8217;re done, and you&#8217;ll magically have created a widget.  Now, any time you open up your Dashboard that widget will be reloaded and you&#8217;ll see fresh data.</p>

<p>So, that&#8217;s how we&#8217;ll display the playlist as a Dashboard Widget &#8211; we&#8217;ll create a webpage that contains the data and then use that as the widget.</p>

<p>If you read the last entry, you&#8217;ll know that I like to use AppleScript as a quick glue language on my Mac.  It&#8217;s pretty easy to use (once you know what you&#8217;re doing), and you can hook into many of the apps you use on a day to day basis and do interesting things with them.  So, it should be no surprise to hear that I&#8217;ll be using AppleScript to get the playlist data out of iTunes.  Given that I&#8217;ll be displaying this data on a webpage though I&#8217;ll be using PHP (because it&#8217;s what I know) to write a quick and dirty page that displays the data that the AppleScript provides.</p>

<p>The AppleScript is a little more involved than the one liners we used last time.  We need to grab the current playlist and then grab information about its UID, Title, Artist and Album, and before finally finding out what the currently playing track is.  Here&#8217;s how we do that.</p>

<pre><code>set tracks_list to {}

tell application "iTunes"
    tell current playlist
        tell tracks
            set tracks_list to get {persistent ID, name, artist, album}
        end tell
    end tell

    set tracks_list to tracks_list  {persistent ID of current track}
end tell

get tracks_list
</code></pre>

<p>In this script we first we create an empty list to put all our data in, then we add lists of track IDs, names, artists and albums to it, then we add a single item of the currently playing track&#8217;s ID.  It&#8217;s not the most elegant of data structures to use once we get to play with it in PHP, but it&#8217;ll do.  Running this from the commandline using <code>osascript -s s playlist.scpt</code> (the <code>-s s</code> means &#8220;print the output in a recompilable form&#8221;) gives us something like the following (respaced for clarity):</p>

<pre><code>{
    {
        "0D7D716D221B623B", 
        "688E193B9F7F7EE3", 
        "05BFA94137C9691F"
    }, 
    {
        "Fashion Is Danger", 
        "Fabulous", 
        "Never Gonna Give You Up"
    }, 
    {
        "Flight of the Conchords", 
        "High School Musical Cast", 
        "Rick Astley"
    }, 
    {
        "I Told You I Was Freaky", 
        "High School Musical 2", 
        "Fantastic 80s"
    }, 
    "688E193B9F7F7EE3"
}
</code></pre>

<p>Now that we have a data structure, we can actually do something with it in PHP.  Unfortunately, as far as I&#8217;m aware there&#8217;s nothing built into PHP that&#8217;ll read this structure. Fortunately though, this structure is pretty damn close to JSON.  If we were to replace the twiddly brackets with square ones then PHP&#8217;s <code>json_decode</code> would return a data structure and we could do something with the data.  Hooray. It&#8217;s a hack, but it works, and it&#8217;s what I did.  A simple <code>str_replace</code> later and I had data.  You can see the code, such as it is, in my <a href="http://github.com/NeilCrosby/itunes-helpers">github repository</a>.</p>

<p>The eagle eyed amongst you will notice that I&#8217;m not directly calling <code>osascript</code> from my PHP script though, and am instead going through an intermediary shell script that nukes <code>DYLD_LIBRARY_PATH</code> before running the AppleScript.  The reason for this is that on the machine I&#8217;m running the script on I&#8217;m using MAMP for my web stack, and that does funny things with <code>DYLD_LIBRARY_PATH</code> under Snow Leopard apparently.  So, I have to nuke it.</p>

<p>And that&#8217;s all there is to it.  Visit the webpage you&#8217;ve created to display the data, let it show you what&#8217;s playing and then turn it into a dashboard component using Safari.  I get to control iTunes on a remote machine and I don&#8217;t have to keep a VNC connection on it.  This makes me happy.</p>
<div style="display:block"><small><em><a href="http://neilcrosby.com">Neil Crosby</a> also blogs at about t-shirts at <a href="http://iwearcotton.com">I Wear Cotton</a>, writes <a href="http://thetenwordreview.com/users/workingwithme">Ten Word Reviews</a>, and uploads <a href="http://www.flickr.com/photos/thevoicewithin/">photos</a> to flickr.  You can follow a combined feed of posts at <a href="http://neilcrosby.com/">NeilCrosby.com</a>.</em></small></div>]]></description>
			<content:encoded><![CDATA[<p>In my last blog entry, I wrote about &#8220;<a href="http://thecodetrain.co.uk/2009/10/controlling-itunes-across-multiple-computers-with-the-keyboard/">Controlling iTunes across multiple computers with the keyboard</a>&#8221; (snappy title, huh?).  In it, I promised that the next step was to work out how to get the current playlist displaying on the dashboard.  So, here goes&#8230;</p>

<p><a class="sidenote" href="http://www.flickr.com/photos/thevoicewithin/4102944794/" title="Remote viewing the currently playing iTunes playlist by Neil Crosby, on Flickr"><img src="http://farm3.static.flickr.com/2475/4102944794_483cf765f4.jpg" width="500" height="313" alt="Remote viewing the currently playing iTunes playlist" /></a></p>

<p>The first thing to be aware of is that if Safari can display something on a webpage, then Dashboard can display it as well.  If you visit a page in Safari and right-click somewhere on the background of the page then you should see a menu item titled <code>Open in Dashboard...</code>. If you select this then you&#8217;ll be able to drag to select an area of the page to turn into a dashboard widget.  Click the <code>Add</code> button at the top of the window once you&#8217;re done, and you&#8217;ll magically have created a widget.  Now, any time you open up your Dashboard that widget will be reloaded and you&#8217;ll see fresh data.</p>

<p>So, that&#8217;s how we&#8217;ll display the playlist as a Dashboard Widget &#8211; we&#8217;ll create a webpage that contains the data and then use that as the widget.</p>

<p>If you read the last entry, you&#8217;ll know that I like to use AppleScript as a quick glue language on my Mac.  It&#8217;s pretty easy to use (once you know what you&#8217;re doing), and you can hook into many of the apps you use on a day to day basis and do interesting things with them.  So, it should be no surprise to hear that I&#8217;ll be using AppleScript to get the playlist data out of iTunes.  Given that I&#8217;ll be displaying this data on a webpage though I&#8217;ll be using PHP (because it&#8217;s what I know) to write a quick and dirty page that displays the data that the AppleScript provides.</p>

<p>The AppleScript is a little more involved than the one liners we used last time.  We need to grab the current playlist and then grab information about its UID, Title, Artist and Album, and before finally finding out what the currently playing track is.  Here&#8217;s how we do that.</p>

<pre><code>set tracks_list to {}

tell application "iTunes"
    tell current playlist
        tell tracks
            set tracks_list to get {persistent ID, name, artist, album}
        end tell
    end tell

    set tracks_list to tracks_list  {persistent ID of current track}
end tell

get tracks_list
</code></pre>

<p>In this script we first we create an empty list to put all our data in, then we add lists of track IDs, names, artists and albums to it, then we add a single item of the currently playing track&#8217;s ID.  It&#8217;s not the most elegant of data structures to use once we get to play with it in PHP, but it&#8217;ll do.  Running this from the commandline using <code>osascript -s s playlist.scpt</code> (the <code>-s s</code> means &#8220;print the output in a recompilable form&#8221;) gives us something like the following (respaced for clarity):</p>

<pre><code>{
    {
        "0D7D716D221B623B", 
        "688E193B9F7F7EE3", 
        "05BFA94137C9691F"
    }, 
    {
        "Fashion Is Danger", 
        "Fabulous", 
        "Never Gonna Give You Up"
    }, 
    {
        "Flight of the Conchords", 
        "High School Musical Cast", 
        "Rick Astley"
    }, 
    {
        "I Told You I Was Freaky", 
        "High School Musical 2", 
        "Fantastic 80s"
    }, 
    "688E193B9F7F7EE3"
}
</code></pre>

<p>Now that we have a data structure, we can actually do something with it in PHP.  Unfortunately, as far as I&#8217;m aware there&#8217;s nothing built into PHP that&#8217;ll read this structure. Fortunately though, this structure is pretty damn close to JSON.  If we were to replace the twiddly brackets with square ones then PHP&#8217;s <code>json_decode</code> would return a data structure and we could do something with the data.  Hooray. It&#8217;s a hack, but it works, and it&#8217;s what I did.  A simple <code>str_replace</code> later and I had data.  You can see the code, such as it is, in my <a href="http://github.com/NeilCrosby/itunes-helpers">github repository</a>.</p>

<p>The eagle eyed amongst you will notice that I&#8217;m not directly calling <code>osascript</code> from my PHP script though, and am instead going through an intermediary shell script that nukes <code>DYLD_LIBRARY_PATH</code> before running the AppleScript.  The reason for this is that on the machine I&#8217;m running the script on I&#8217;m using MAMP for my web stack, and that does funny things with <code>DYLD_LIBRARY_PATH</code> under Snow Leopard apparently.  So, I have to nuke it.</p>

<p>And that&#8217;s all there is to it.  Visit the webpage you&#8217;ve created to display the data, let it show you what&#8217;s playing and then turn it into a dashboard component using Safari.  I get to control iTunes on a remote machine and I don&#8217;t have to keep a VNC connection on it.  This makes me happy.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodetrain.co.uk/2009/11/displaying-your-current-remote-itunes-playlist-on-your-local-macs-dashboard/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting the CSS Validator running as a website</title>
		<link>http://thecodetrain.co.uk/2009/03/getting-the-css-validator-running-as-a-website/</link>
		<comments>http://thecodetrain.co.uk/2009/03/getting-the-css-validator-running-as-a-website/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 10:48:57 +0000</pubDate>
		<dc:creator>Neil Crosby</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[feci]]></category>
		<category><![CDATA[jigsaw]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[validator]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[web-server]]></category>

		<guid isPermaLink="false">http://thecodetrain.co.uk/?p=222</guid>
		<description><![CDATA[<p>A week or so I wrote about <a href="http://thecodetrain.co.uk/2009/02/running-the-w3c-css-validator-locally-from-the-command-line/">running the W3C CSS Validator on the command-line</a>.  Yes, I know I said I didn&#8217;t need to run it as a website, but as it turns out the command-line version doesn&#8217;t seem to want to validate local files — only files being served from a  web-server.</p>

<p>So, I went back to scratch and tried installing it on a web-server.  Since my normal stack is Apache, MySQL and PHP I didn&#8217;t have any of the Java-based web-servers suggested by the W3C.  My first attempt at getting the validator working was to use <a href="http://www.w3.org/Jigsaw/">Jigsaw</a> &#8211; the same web-server as the W3C uses to run their version on.  Unfortunately, it didn&#8217;t work for me.  Bugger.</p>

<p>So, I tried <a href="http://tomcat.apache.org/">Tomcat</a>.  After following <a href="http://wiki.apache.org/tomcat/TomcatOnMacOS#head-3bfa4851688758d9bd07a188d4f552806af8b30f">Basil Bourque&#8217;s instructions</a> on <a href="http://wiki.apache.org/tomcat">Apache&#8217;s Tomcat wiki pages</a>, I got Tomcat working.  I then followed the rest of the <a href="http://jigsaw.w3.org/css-validator/DOWNLOAD.html">CSS Validator installation instructions</a> for Tomcat, and the validator worked in my browser.  Excellent.</p>

<p>There was a fly in the ointment though.  Whilst the validator worked in my browser, the same could not be said of my attempts to get it working via cURL calls from PHP using POST data.  I was using the same code as I&#8217;d used to validate against the W3C&#8217;s HTML validator, so I knew that I was able to successfully push POST data across to servers.  If I tried using GET requests to send the data to my local validator, then that worked. I verified the same thing was happening on the live CSS validator to make sure the problem wasn&#8217;t with my installation.  I know you&#8217;re thinking &#8220;well, if GET worked, why not just make requests that way?&#8221;  Unfortunately, I know that later I&#8217;ll be asking to validate much larger CSS rulesets — ones that will be far too large to fit on a URL.  So, I needed to use POST.</p>

<p>After a fair bit of poking, I realised that the in-browser version of the CSS Validator was setting an <code>enc</code> attribute value of <code>multipart/form-data</code> on the form when it was uploading files or sending textual data.  Conversely, it turns out that PHP was sending <code>application/x-www-form-urlencoded</code> as the encoding type instead, and the W3C CSS Validator just isn&#8217;t set up to accept that.  After a long time of trying to work out how to send things in <code>multipart/form-data</code> format using PHP&#8217;s cURL functions, I happened upon <a href="http://us2.php.net/manual/en/function.curl-setopt.php#84916">a comment on PHP&#8217;s curl_setopt function</a> which told me that if I gave PHP an array instead of a string it would automagically start using <code>multipart/form-data</code>.  As if by magic, my problem was solved.</p>

<p>My problems setting up my programmatic connection to the CSS Validator could easily have been solved by clearer documentation.  Nowhere that I could find in the Validator&#8217;s documentation was there any mention of needing to make POST requests using <code>multipart/form-data</code>.  If this had been stated somewhere I would at least I have known the path I needed to be looking down.  Likewise, lack of anything other than user-generated documentation for the PHP <code>CURLOPT_POSTFIELDS</code> cURL option made life far more difficult than it should have been.</p>

<p>Still, in the end I have a local version of the W3C&#8217;s CSS validator running on my laptop, and I&#8217;m able to connect to it programmatically to run tests.  Which is nice.</p>
<div style="display:block"><small><em><a href="http://neilcrosby.com">Neil Crosby</a> also blogs at about t-shirts at <a href="http://iwearcotton.com">I Wear Cotton</a>, writes <a href="http://thetenwordreview.com/users/workingwithme">Ten Word Reviews</a>, and uploads <a href="http://www.flickr.com/photos/thevoicewithin/">photos</a> to flickr.  You can follow a combined feed of posts at <a href="http://neilcrosby.com/">NeilCrosby.com</a>.</em></small></div>]]></description>
			<content:encoded><![CDATA[<p>A week or so I wrote about <a href="http://thecodetrain.co.uk/2009/02/running-the-w3c-css-validator-locally-from-the-command-line/">running the W3C CSS Validator on the command-line</a>.  Yes, I know I said I didn&#8217;t need to run it as a website, but as it turns out the command-line version doesn&#8217;t seem to want to validate local files — only files being served from a  web-server.</p>

<p>So, I went back to scratch and tried installing it on a web-server.  Since my normal stack is Apache, MySQL and PHP I didn&#8217;t have any of the Java-based web-servers suggested by the W3C.  My first attempt at getting the validator working was to use <a href="http://www.w3.org/Jigsaw/">Jigsaw</a> &#8211; the same web-server as the W3C uses to run their version on.  Unfortunately, it didn&#8217;t work for me.  Bugger.</p>

<p>So, I tried <a href="http://tomcat.apache.org/">Tomcat</a>.  After following <a href="http://wiki.apache.org/tomcat/TomcatOnMacOS#head-3bfa4851688758d9bd07a188d4f552806af8b30f">Basil Bourque&#8217;s instructions</a> on <a href="http://wiki.apache.org/tomcat">Apache&#8217;s Tomcat wiki pages</a>, I got Tomcat working.  I then followed the rest of the <a href="http://jigsaw.w3.org/css-validator/DOWNLOAD.html">CSS Validator installation instructions</a> for Tomcat, and the validator worked in my browser.  Excellent.</p>

<p>There was a fly in the ointment though.  Whilst the validator worked in my browser, the same could not be said of my attempts to get it working via cURL calls from PHP using POST data.  I was using the same code as I&#8217;d used to validate against the W3C&#8217;s HTML validator, so I knew that I was able to successfully push POST data across to servers.  If I tried using GET requests to send the data to my local validator, then that worked. I verified the same thing was happening on the live CSS validator to make sure the problem wasn&#8217;t with my installation.  I know you&#8217;re thinking &#8220;well, if GET worked, why not just make requests that way?&#8221;  Unfortunately, I know that later I&#8217;ll be asking to validate much larger CSS rulesets — ones that will be far too large to fit on a URL.  So, I needed to use POST.</p>

<p>After a fair bit of poking, I realised that the in-browser version of the CSS Validator was setting an <code>enc</code> attribute value of <code>multipart/form-data</code> on the form when it was uploading files or sending textual data.  Conversely, it turns out that PHP was sending <code>application/x-www-form-urlencoded</code> as the encoding type instead, and the W3C CSS Validator just isn&#8217;t set up to accept that.  After a long time of trying to work out how to send things in <code>multipart/form-data</code> format using PHP&#8217;s cURL functions, I happened upon <a href="http://us2.php.net/manual/en/function.curl-setopt.php#84916">a comment on PHP&#8217;s curl_setopt function</a> which told me that if I gave PHP an array instead of a string it would automagically start using <code>multipart/form-data</code>.  As if by magic, my problem was solved.</p>

<p>My problems setting up my programmatic connection to the CSS Validator could easily have been solved by clearer documentation.  Nowhere that I could find in the Validator&#8217;s documentation was there any mention of needing to make POST requests using <code>multipart/form-data</code>.  If this had been stated somewhere I would at least I have known the path I needed to be looking down.  Likewise, lack of anything other than user-generated documentation for the PHP <code>CURLOPT_POSTFIELDS</code> cURL option made life far more difficult than it should have been.</p>

<p>Still, in the end I have a local version of the W3C&#8217;s CSS validator running on my laptop, and I&#8217;m able to connect to it programmatically to run tests.  Which is nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodetrain.co.uk/2009/03/getting-the-css-validator-running-as-a-website/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WikiSlurp: Slurping Data from Wikipedia for Fun and Profit</title>
		<link>http://thecodetrain.co.uk/2008/09/wikislurp-slurping-data-from-wikipedia-for-fun-and-profit/</link>
		<comments>http://thecodetrain.co.uk/2008/09/wikislurp-slurping-data-from-wikipedia-for-fun-and-profit/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 14:00:29 +0000</pubDate>
		<dc:creator>Neil Crosby</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[barcamp]]></category>
		<category><![CDATA[barcamplondon5]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[isneilannoyedby]]></category>
		<category><![CDATA[mediawiki]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scratching an itch]]></category>
		<category><![CDATA[thetenwordreview]]></category>
		<category><![CDATA[wikipedia]]></category>
		<category><![CDATA[wikislurp]]></category>

		<guid isPermaLink="false">http://thecodetrain.co.uk/?p=15</guid>
		<description><![CDATA[<p>This last weekend I attended <a href="http://barcamp.org/BarCampLondon5">BarCamp London 5</a>, where I talked about WikiSlurp, my technique for accessing the wealth of data held within Wikipedia.  I currently use WikiSlurp on both <a href="http://isneilannoyedby.com">Is Neil Annoyed By</a> and <a href="http://thetenwordreview.com">The Ten Word Review</a> as a way to pull in additional information about the things described on individual pages.</p>

<p>These are the slides I put together for my talk:</p>

<div style="width:425px;text-align:left" id="__ss_622769"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/neilcrosby/mining-wikipedia-for-awesome-data-presentation?type=powerpoint" title="Mining Wikipedia For Awesome Data">Mining Wikipedia For Awesome Data</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mining-wikipedia-for-awesome-data-1222603282334492-9&#038;stripped_title=mining-wikipedia-for-awesome-data-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=mining-wikipedia-for-awesome-data-1222603282334492-9&#038;stripped_title=mining-wikipedia-for-awesome-data-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/neilcrosby/mining-wikipedia-for-awesome-data-presentation?type=powerpoint" title="View Mining Wikipedia For Awesome Data on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/wikislurp">wikislurp</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/wikipedia">wikipedia</a>)</div></div>

<p>If you just want to <a href="http://thecodetrain.co.uk/downloads/wikislurp-0.1.zip">download the Code</a>, go right ahead.  If you want to know more about the project, read the <a href="http://thecodetrain.co.uk/code/wikislurp/">WikiSlurp Project page</a>.</p>
<div style="display:block"><small><em><a href="http://neilcrosby.com">Neil Crosby</a> also blogs at about t-shirts at <a href="http://iwearcotton.com">I Wear Cotton</a>, writes <a href="http://thetenwordreview.com/users/workingwithme">Ten Word Reviews</a>, and uploads <a href="http://www.flickr.com/photos/thevoicewithin/">photos</a> to flickr.  You can follow a combined feed of posts at <a href="http://neilcrosby.com/">NeilCrosby.com</a>.</em></small></div>]]></description>
			<content:encoded><![CDATA[<p>This last weekend I attended <a href="http://barcamp.org/BarCampLondon5">BarCamp London 5</a>, where I talked about WikiSlurp, my technique for accessing the wealth of data held within Wikipedia.  I currently use WikiSlurp on both <a href="http://isneilannoyedby.com">Is Neil Annoyed By</a> and <a href="http://thetenwordreview.com">The Ten Word Review</a> as a way to pull in additional information about the things described on individual pages.</p>

<p>These are the slides I put together for my talk:</p>

<div style="width:425px;text-align:left" id="__ss_622769"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/neilcrosby/mining-wikipedia-for-awesome-data-presentation?type=powerpoint" title="Mining Wikipedia For Awesome Data">Mining Wikipedia For Awesome Data</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mining-wikipedia-for-awesome-data-1222603282334492-9&#038;stripped_title=mining-wikipedia-for-awesome-data-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=mining-wikipedia-for-awesome-data-1222603282334492-9&#038;stripped_title=mining-wikipedia-for-awesome-data-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/neilcrosby/mining-wikipedia-for-awesome-data-presentation?type=powerpoint" title="View Mining Wikipedia For Awesome Data on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/wikislurp">wikislurp</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/wikipedia">wikipedia</a>)</div></div>

<p>If you just want to <a href="http://thecodetrain.co.uk/downloads/wikislurp-0.1.zip">download the Code</a>, go right ahead.  If you want to know more about the project, read the <a href="http://thecodetrain.co.uk/code/wikislurp/">WikiSlurp Project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodetrain.co.uk/2008/09/wikislurp-slurping-data-from-wikipedia-for-fun-and-profit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

