<?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>aleatory &#187; Tech Labours</title>
	<atom:link href="http://aleatory.clientsideweb.net/category/tech-labours/feed/" rel="self" type="application/rss+xml" />
	<link>http://aleatory.clientsideweb.net</link>
	<description></description>
	<lastBuildDate>Sat, 17 Jul 2010 00:32:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Browse with Confidence?</title>
		<link>http://aleatory.clientsideweb.net/2010/06/21/browse-with-confidence/</link>
		<comments>http://aleatory.clientsideweb.net/2010/06/21/browse-with-confidence/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 01:00:51 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/?p=251</guid>
		<description><![CDATA[

Perhaps, when attempting to convince users your browser is rock solid haxor-proof, it&#8217;d be advisable to demonstrate to them that your sites can detect which browser they&#8217;re currently running?
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/rutherfordinbelfast/4718752361/sizes/o/"><img alt="IE6 not detected on microsoft.com" src="http://farm5.static.flickr.com/4020/4718752361_ba55d809c5.jpg" title="IE8?" class="aligncenter" width="500" height="400" /></a></p>
<p>
Perhaps, when attempting to convince users your browser is rock solid haxor-proof, it&#8217;d be advisable to demonstrate to them that your sites can detect which browser they&#8217;re currently running?</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2010/06/21/browse-with-confidence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging &#8216;Responseless&#8217; HTTP Requests</title>
		<link>http://aleatory.clientsideweb.net/2010/06/14/debugging-responseless-http-requests/</link>
		<comments>http://aleatory.clientsideweb.net/2010/06/14/debugging-responseless-http-requests/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 22:19:02 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/?p=239</guid>
		<description><![CDATA[When developing AJAX or Facebook web apps a lot of the time requests are fire and forget i.e. they are awaiting no specific response information from the application.  Therefore we have no simple dump to screen solution for debugging our apps.

One workaround would be to save details to a db where they could be [...]]]></description>
			<content:encoded><![CDATA[<p>When developing AJAX or Facebook web apps a lot of the time requests are fire and forget i.e. they are awaiting no specific response information from the application.  Therefore we have no simple dump to screen solution for debugging our apps.</p>
<p>
One workaround would be to save details to a db where they could be retrieved for analysis at a later time.  This makes the data persistent but normally for debugging this is overkill.  Log frameworks exist but sometimes incorporating third party software in is just bloat, especially in single developer projects.<br />
<span id="more-239"></span><br />
The simplest alternative solution I can think of is to grab the request info needed and send it out to a mail address using PHP&#8217;s built in mail object:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$to</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'me@example.com'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$subj</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Request variables'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$msg</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Requested:\n'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_REQUEST</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$k</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$v</span> <span style="color: #009900;">&#41;</span>
 <span style="color: #000088;">$msg</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\t</span><span style="color: #006699; font-weight: bold;">$k</span> = <span style="color: #006699; font-weight: bold;">$v</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mail</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$to</span><span style="color: #339933;">,</span> <span style="color: #000088;">$subj</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>
Mailing debug output to a free mail provider such as gmail means you have a persistent copy of the data (in chronological order) in a few lines of code without needing to start building up sql or think about clogging up your host with yet more logs.   Is there a better way?</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2010/06/14/debugging-responseless-http-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trojans.  Not Stupid.</title>
		<link>http://aleatory.clientsideweb.net/2009/12/21/trojans-not-stupid/</link>
		<comments>http://aleatory.clientsideweb.net/2009/12/21/trojans-not-stupid/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 01:57:30 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/12/21/trojans-not-stupid/</guid>
		<description><![CDATA[I got held up recently by a particularly nasty Trojan infection that seemed to come from a flash vulnerability &#8211; or at least it installed itself in a Macromedia directory at a time when embedded flash would have been running on one of the web pages I had open.
No ordinary decent virus this one though. [...]]]></description>
			<content:encoded><![CDATA[<p>I got held up recently by a particularly nasty Trojan infection that seemed to come from a flash vulnerability &#8211; or at least it installed itself in a Macromedia directory at a time when embedded flash would have been running on one of the web pages I had open.</p>
<p><img src='http://aleatory.clientsideweb.net/wp-content/uploads/2009/12/trojan.jpg' alt='Trojan' style="float:left"/>No ordinary decent virus this one though.  It cleverly disabled my default browser &#8211; Chrome &#8211; coercing me into a specific set of steps that would ultimately place a rootkit on my OS.  As my browser seemingly inexplicably was rendered useless, even after multiple uninstall/reinstalls, something else was up.  Internet Explorer was attempting to connect to a &#8220;tolule.net&#8221; which on lookup resolved to a Chinese IP.  So a quick entry into my Sygate advanced rules and I had a large swathe of Chinese IPs blocked.  So I was safe for the time being giving me a chance to think about what was going on.  (The Trojan was quite busy &#8211; attempting to connect every 10 mins or so and to multiple domains &#8211; initially always tolule.net but also gusmon.net and somemon.net &#8211; each time resolving to an address in China).<br />
<span id="more-168"></span><br />
I ran a full AVG scan and two files were suspect &#8211; both resident in System Volume Information &#8211; the area where System Restore settings reside.  Delete wouldn&#8217;t work (looking into it further if system restore is turned on these files cannot be manipulated) so I went for seemingly the next best option &#8211; system restore to a point before Chrome stopped working.  Looking back this was a stupid thing to do but at the time seemed logical enough.  A thought process that no doubt the hackers had already wargamed out in their heads prior to deployment.  User sees app not working, reinstall doesn&#8217;t work, anti-virus identifies but can&#8217;t clear the Trojan, proceeds to system restore hence running the virus the hackers managed to plant somehow in Sys Vol Info.</p>
<p>Needless to say, the system restore failed, but now a plethora of hacked files had now successfully and relatively silently installed themselves on my OS.  The rig included their own embedded db instance of Sql Anywhere, the a.exe worm that amongst other things engages in Process Hijacking described above, a bunch of reg keys that pointed device drivers and startup configs to the original hacked Macromedia directory, a hidden rootkit type process that ensured these keys and the directory were not tampered with and the actual downloader Trojan itself, W32/Agent.GBS!tr.dldr.</p>
<p>The process hijacking was something else.  It would wait until I&#8217;d start an application and use the app&#8217;s virtual memory for it&#8217;s own devices.  Hence why I was getting the Sygate reports of IE getting a life of it&#8217;s own.  Wasn&#8217;t just browsers that were vulnerable, even MalwareBytes Anti-Malware software&#8217;s memory was hijacked.  Each time the stolen app tried unsuccessfully to phone home to China.</p>
<p>By now it was obvious to me I had been infected with a particularly nasty virus and ran AVG a 2nd time.  But now the Trojan was so well embedded AVG didn&#8217;t pick up anything more than a few measly HTTP cookies.  I did wonder about Sygate at this stage but it still seemed to be successfully blocking all malicious packets so I was still just interested in removal.  Spybot Search and Destroy was my next bet but it returned nothing.  What&#8217;s more that TeaTimer process monitor it installs is a real resource hog &#8211; 128meg of virtual memory.  That&#8217;s a bit more than a mere heartbeat in my book.  Especially on my netbook!  Got rid of that then was pointed to the MalwareBytes app by Matt @ BleepingComputer.com.  The hackers obviously see it as a threat &#8211; after I installed it I tried to update it&#8217;s malware db but was prevented from doing so, presumably by the a.exe worm.  It instead forced MBAM to attempt another connection to tolule.net.  Proceeded with the scan anyway.  Result?  Every malicious file was identified.</p>
<p>Although still not out of the woods &#8211; MBAM would freeze when attempting to quarantine the audio driver reg keys whose values had been changed from wdmaud.drv to a dll file in the fake Macromedia directory.  After I deleted a.exe and ran MBAM again, this time it succeeded in changing the reg keys after a restart.  I had tried manual deletion of the reg keys and fake Macromedia directory prior to this but as soon as I closed regedit the keys and files would reappear.  MBAM must have required the restart to remove whatever in-memory process had been running to protect the hacked data.</p>
<p>So that&#8217;s pretty much it.  Quite an organised payload that, and a very well thought out attack vector relying on unwitting end user participation as much as the original web vulnerability.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/12/21/trojans-not-stupid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The StackOverflow Rant</title>
		<link>http://aleatory.clientsideweb.net/2009/12/01/the-stackoverflow-rant/</link>
		<comments>http://aleatory.clientsideweb.net/2009/12/01/the-stackoverflow-rant/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 02:55:26 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[cool]]></category>
		<category><![CDATA[information media]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/12/01/the-stackoverflow-rant/</guid>
		<description><![CDATA[I should probably open my commentary on the SO community with a more wide-ranging piece on the effectiveness of self-moderation and social badge collecting in rapidly scaling a web community but hopefully by dumping this the second opinion will be more insightful whenever that may be.
Ok so really I&#8217;m just a petty net troll who [...]]]></description>
			<content:encoded><![CDATA[<p>I should probably open my commentary on the <a href="http://stackoverflow.com/" target="_blank">SO community</a> with a more wide-ranging piece on the effectiveness of self-moderation and social badge collecting in rapidly scaling a web community but hopefully by dumping this the second opinion will be more insightful whenever that may be.</p>
<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/12/internetforumtoughguy.jpg" alt="forum junkie" style="float: left" />Ok so really I&#8217;m just a petty net troll who completely overreacts to criticism online.  That aside, I still cannot understand how the answering army at stackoverflow come to the collective conclusion that every question on a close-to-the-bone programming issue requires some inane form of rephrasing or just outright blanking.</p>
<p><span id="more-161"></span>I get over the former as SO is a lightning quick method of accessing really knowledgeable people on demand &#8211; but I had to endure a case of the later a while back when someone obviously thought the answer to the question I asked was too blase and proceded to provide a solution for a completely separate issue.  And this despite me explaining exactly why I didn&#8217;t want his solution in the preamble.  So I went and got a workable answer myself, posted it and accepted it as the solution.  Job done.</p>
<p>Except this caused numbnuts to vote down my answer without explanation.  So I voted his down, and told him why.  Despite this, he questioned why I&#8217;d want to know what I wanted to know in the first place and voted down the question.  It was at that moment that I realised SO, while largely self-moderating, is still missing the last 20%<sup>TM</sup> required to remove the clinically insane from the process.  It gives me no pleasure to disclose the most efficient solution currently is to multiply your web leverage in traditional fashion; create multiple accounts and hit back with a bewildering array of counter-comments and down votes&#8230;</p>
<p>It is embarrassing though when apparently throwaway questions asked on your secondary accounts are rated higher than your allegedly thought-provoking and succinct real persona *whistles*</p>
<p>In true Bileblog style, programmers appear to be sarky contemptible bastards who like nothing more than jumping on the inaccuracies of accepted thought; hence phrasing a question along the lines of &#8216;My colleague says x is no longer a good way to do things&#8230;&#8217; will likely stir the hornet&#8217;s nest of pedantry as each contributor seeks to provide a more arcane answer as to why x sucks than the previous response.  Recurse until someone mentions lambda.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/12/01/the-stackoverflow-rant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google App Engine Datastore Gotchas</title>
		<link>http://aleatory.clientsideweb.net/2009/11/28/google-app-engine-datastore-gotchas/</link>
		<comments>http://aleatory.clientsideweb.net/2009/11/28/google-app-engine-datastore-gotchas/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 17:21:19 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[data]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/11/28/google-app-engine-datastore-gotchas/</guid>
		<description><![CDATA[
image courtesy johnson7
App Engine is generally a new paradigm for webapp developers; replacing sessions with memcache and a schemaless datastore just two elements requiring new thinking for old problems.  Unfortunately there are a few more hidden nuisances which have the potential to waste programming time relatively early on.  Here&#8217;s four of my personal [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/11/stormclouds.jpg" alt="stormclouds gather" /><br />
<span class="wp-caption" style="margin: 0pt; padding: 0pt; font-size: 10px">image courtesy <a href="http://www.flickr.com/photos/johnson7/1460568819/">johnson7</a></span></p>
<p>App Engine is generally a new paradigm for webapp developers; replacing sessions with memcache and a schemaless datastore just two elements requiring new thinking for old problems.  Unfortunately there are a few more hidden nuisances which have the potential to waste programming time relatively early on.  Here&#8217;s four of my personal head-bangers:</p>
<p><strong>1. the datastore doesn&#8217;t always store Properties</strong><br />
I&#8217;ve had trouble with it refusing to store arbitrary entity props unless I assign them in the entity constructor itself (these fields were optional btw).  Just setting prop values after initialisation then put() on the ds didn&#8217;t write them.</p>
<p><span id="more-160"></span><strong>2. fussy filter parsing</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;prop= &quot;</span>,propValue<span style="color: black;">&#41;</span>.<span style="color: black;">fetch</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>returns a NoneType error</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;prop=&quot;</span>,propValue<span style="color: black;">&#41;</span>.<span style="color: black;">fetch</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>silently fails to find expected.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;prop =&quot;</span>,propValue<span style="color: black;">&#41;</span>.<span style="color: black;">fetch</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Only the above will return the expected result.</p>
<p><strong>3. Only possible to execute inequality filters on one property per query</strong><br />
This is a pain in the arse if you want to query whether an input date is between two dates stored in a particular entity &#8211; officially there was a workaround whereby the date range is stored in a ListProperty (instead of two fields of type DateProperty) and you do the normal check if input is more than the list (greater than at least one element in the list) and less than the list (less than at least one element in the list).</p>
<p>However the App Engine team has now changed the behaviour in the cloud whereby both the &#8216;&gt;=&#8217; and &#8216;&lt;=&#8217; filters are operated on each individual list element and not a lazy test over the whole series i.e. where the existence of two list elements that bounded the input date would have been sufficient the following query now only returns the entity if one of the ListProperty elements is an exact match for it:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">WHERE</span> date_range &amp;gt;<span style="color: #66cc66;">=</span> :<span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> date_range &amp;lt;<span style="color: #66cc66;">=</span> :<span style="color: #cc66cc;">1</span></pre></div></div>

<p>Unfortunately this has not been removed from the dev_server datastore, hence it runs perfectly well locally.</p>
<p>4. And hopefully the <strong>1000 record query limit</strong> is well-known by this point.</p>
<p>On a more general note, why is it newfangled tech doesn&#8217;t build on top of the old stuff?  Re-use would get us to where we want to be a lot sooner.  I bitched about this <a href="http://twitter.com/rutherford/status/6055511385">on Twitter</a> at the time and I&#8217;ll repeat the message here too because it&#8217;s worth doing so frankly, I expect new stuff to do the same things old stuff does as well as any &#8220;hey that&#8217;s cool&#8221; new fandangomatrons it bolts on.</p>
<p>Wave&#8217;s another case in point.  Not &#8216;email invented today&#8217;, far from it &#8211; it&#8217;s left so much cutting-edge crowd-sourced participatory stuff out (as well as how to do IM, namely the KISS principle) &#8211; that it actually feels like a retrograde step in many ways.  Most in fact.</p>
<p>Bottom line &#8211; Google needs to make stuff better.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/11/28/google-app-engine-datastore-gotchas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apparatchiks Vs Technocrats?</title>
		<link>http://aleatory.clientsideweb.net/2009/10/25/apparatchiks-vs-technocrats/</link>
		<comments>http://aleatory.clientsideweb.net/2009/10/25/apparatchiks-vs-technocrats/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 20:32:28 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/10/25/apparatchiks-vs-technocrats/</guid>
		<description><![CDATA[This was sitting in draft form for a while now &#8211; I&#8217;m not sure why but probably until I fleshed it out a bit more.  Here it is in unbridled terseness
Let me begin by saying I don&#8217;t want this blog infected with politics.
Notwithstanding this fact I wish to proceed momentarily by injecting a healthy [...]]]></description>
			<content:encoded><![CDATA[<p><em>This was sitting in draft form for a while now &#8211; I&#8217;m not sure why but probably until I fleshed it out a bit more.  Here it is in unbridled terseness</em></p>
<p>Let me begin by saying I don&#8217;t want this blog infected with politics.</p>
<p>Notwithstanding this fact I wish to proceed momentarily by injecting a healthy dose of the political clap.</p>
<p><a href="http://www.propelprogramme.co.uk/programme.aspx" rel="external">We want entrepreneurs</a> vs <a href="http://news.bbc.co.uk/2/hi/uk_news/northern_ireland/7965580.stm" rel="external">we want more of the same</a>.</p>
<p><span id="more-144"></span>Approximate equal sums for both &#8211; but where is the greater need?  Embed another 30 political idealists in sufficient exposure to a narrow minded zero-sum status quo in order to espouse a continued malaise of divided nationalism or 15 entrepreneurs potentially showing more of the <a href="http://www.firstderivatives.com/pages/careers_whatwedo.asp" rel="external">ambition</a> and <a href="http://www.datactics.com/Customers" rel="external">smarts</a> that will begin redirecting the global capital flow home to NI?</p>
<p>Don&#8217;t feed the trolls &#8211; don&#8217;t give politics students money for watching how not to do things!</p>
<p>Giving them what amounts to a minimum wage would create more economic benefit if they were told to operate a car wash for the monies.  At least you&#8217;d have 30 skilled workers at the end of it.</p>
<p>This was a party political broadcast from the Politics-Is-Not-An-Industry Party</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/10/25/apparatchiks-vs-technocrats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Cathedral and the Barcamp</title>
		<link>http://aleatory.clientsideweb.net/2009/10/13/the-cathedral-and-the-barcamp/</link>
		<comments>http://aleatory.clientsideweb.net/2009/10/13/the-cathedral-and-the-barcamp/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 12:10:34 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[cool]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/10/13/the-cathedral-and-the-barcamp/</guid>
		<description><![CDATA[So I attended my first two tech events over the past few days. One good one bad &#8211; here&#8217;s why:
First the good one. I didn&#8217;t really know what to expect from Barcamp Derry and from the spiel delivered online was hoping that was the correct way to approach it. Half hour sessions organised in 3 [...]]]></description>
			<content:encoded><![CDATA[<p>So I attended my first two tech events over the past few days. One good one bad &#8211; here&#8217;s why:</p>
<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/10/barcamp.thumbnail.png" style="float: left" />First the good one. I didn&#8217;t really know what to expect from Barcamp Derry and from the spiel delivered online was hoping that was the correct way to approach it. Half hour sessions organised in 3 concurrent &#8217;streams&#8217; meant the first 5 minutes of each was largely spent loitering in the doorway of each until one grabbed enough attention take a pew.</p>
<p><span id="more-137"></span>Although I missed the morning sessions the later half still produced a nice variety of topics &#8211; web media, drupal, startup and a few more. It was refreshing to see stuff happening locally that you usually only read about in front of a screen. Effectively it takes the form of a &#8217;show &amp; tell&#8217; so you get to see stuff that is happening right now in NI. It is accessible and because of that you get an urge to participate and interact in a way you don&#8217;t get from say a lecture for example. You get the sense when people are talking they are thinking aloud and the wide variety of topics really gets you thinking.</p>
<p>The whole experience just seems more realtime.</p>
<p>I&#8217;m no expert on the philosophy of BarCamp but maybe it&#8217;d be an idea to have stream themes so less frantic checking of the timetable matrix would ensue between show &amp; tells. So I could sit down in a room for the day and know I&#8217;d be learning about e.g. bootstrapping, but without necessarily needing to know who is going to speak on it until they begin. It&#8217;d make for a more open minded audience I reckon since they would have little time to research a speakers angle.</p>
<p>Anyway I found the whole thing an engaging and unique experience and am very much looking forward to the next one on 6th November.</p>
<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/10/devgarageirl.thumbnail.jpg" style="float: left" />Now the bad one. Facebook Dev Garages are as I understand them a chance for people using/thinking about using the platform to tap into the phenomenol viral power of FB&#8217;s network. If you&#8217;re not into developing apps solely for the Facebook platform, you&#8217;re looking to shoehorn the power of the &#8216;tell your friends&#8217; social tsunami into your existing application.</p>
<p>The first point is it works. My 1st FB app was a simple little gamer gimic that reached 2k MAU (Monthly Active Users &#8211; the standard metric for FB app popularity) within a month, just by adding &#8216;invite your friends&#8217; and &#8216;publish to stream&#8217; components. This would not happen via say Google Gadget directory or dare I say it any of the current appstores. On Facebook, your app is actively pushed through your network by its users. Virality.</p>
<p>It&#8217;s a relatively new paradigm but unfortunately Facebook Inc has turned themselves into another M$, another cathedral: What we got at yesterday&#8217;s Garage was a staid marketing promo. It was a great disappointment &#8211; there is a rich dev ecosystem surrounding the FB platform &#8211; fbFund, the f8 conference and the Dev Garages elsewhere seem to have got the backing they deserved.</p>
<p>So the conversation began at a bird&#8217;s eye view and never really returned to earth.</p>
<p>It could have been so different: At the last minute James Leszczenski, one of the platform dev guys, was roped in. He provided an overview of FB&#8217;s crowdsourced translate app and how it could be used by developers to localise their own FB content. Good talk but again he skipped over the FBML and coding (aka the useful bits) I&#8217;m guessing to avoid glazing half the audience&#8217;s eyes over.</p>
<p>Also maybe it was the travel or whatever but I was expecting him to at least stand for some q&#8217;s at the end of his presentation. He just slunked into his seat. So with the other guys demo not coming off this was basically the end of the Belfast Dev Garage. Some marketing guy and a dev who didn&#8217;t really talk shop &amp; wasn&#8217;t too interested in engaging the audience.</p>
<p>[I asked the InvestNI girl afterwards if there'd be another one in future, maybe with a bit more to it and the response didn't sound too promising. Maybe there isn't the demand currently but surely it's up to the marketing people to get engaging content. Not come here to give a talk on the history of the company and how to create a FB page for your business. There's a tendency for tech firms opening up in Dublin to adopt the shrinkwrapped M$ model of dev engagement. There is very little understanding of what makes a dev ecosystem tick.]</p>
<p>Anyways fair play to the audience at this point, questions were inevitably pointed in his direction and although a percentage of them were irrelevant in a dev context at least it was interaction.</p>
<p>Not of much value though. His answer to the unreliability of the MAU stat availability was publicly &#8220;I&#8217;m sure there&#8217;s a thread on it on the forum&#8221; and privately &#8220;There&#8217;s no reason why you can&#8217;t do your own&#8221;. Which is a load of balls: I could invent the Rutherford Active User tomorrow and you know who would be interested? Nobody that&#8217;s who. Why would they take the time to discover this brand new metric when MAU exists as a platform standard in <em>every</em> app out there? Just fix your own buggy stats thankyouverymuch.</p>
<p>I&#8217;ll admit to getting it wrong on the photos api not being open. Since 2007 to make things worse. But I&#8217;m also going to shift the blame on platform dev docs being an absolute maze to work through. I&#8217;ll stop digging right there. And I was more just pissed off at all the marketing chatter of open this connected that. hmph.</p>
<p>Although Leszczenski did seem a nice guy in person and at least laughed &amp; agreed with my take on Google Wave still being &#8216;the app Google released the day Microsoft launched Bing&#8217;. Not the first time that&#8217;s happened he said, in his best FB disciple knowing look of indignation.</p>
<p>Cathedrals are everywhere.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/10/13/the-cathedral-and-the-barcamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ecosystems and Cajoling Participants</title>
		<link>http://aleatory.clientsideweb.net/2009/09/08/ecosystems-and-cajoling-participants/</link>
		<comments>http://aleatory.clientsideweb.net/2009/09/08/ecosystems-and-cajoling-participants/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 22:27:08 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[opportunity]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/09/08/ecosystems-and-cajoling-participants/</guid>
		<description><![CDATA[Back in 2005, I used to work for what was then DrKW in their Digital Markets division. DM was their investment banking answer to the web buzz of the early 2000s. Sean Park, the head of the division, had made a personal killing on several tech floatation deals and had drank the digital koolaid. Ably [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/09/revolutiondrkw.gif" alt="revolution" style="float:left;"/>Back in 2005, I used to work for what was then DrKW in their Digital Markets division. DM was their investment banking answer to the web buzz of the early 2000s. Sean Park, the head of the division, had made a personal killing on several tech floatation deals and had drank the digital koolaid. Ably assisted by an IT chief with a penchant for grand visions, he set about giving Dresdner&#8217;s corporate clients an investment banking answer to the consumer behemoths Betfair, Ebay, etc who were seemingly granting supernatural powers to anyone with an internet connection.</p>
<p>You can still view the <em>Googlezon</em>-inspired vision <a href="http://www.parkparadigm.com/amazonbay/amazonbay.swf">here</a>. I left the bank a year later, but kept an eye on the Revolution platform. It failed miserably. The trouble was they were providing a great integrated digital service that no one in the city knew they wanted yet. Banking is a notoriously fickle industry, and change only happens when trusted relationships introduce it. Revolution&#8217;s newly recruited marketing team was manned with former developers, admin staff &amp; inexperienced hires from other banks.</p>
<p><span id="more-130"></span>The Digital Markets idea was sold to IT, but it wasn&#8217;t sold to the business. So no one from the business sold it to clients. It died a death and now the only evidence I have left is the promo mousemat. Morgan Stanley jumped on the same <a href="http://www.readwriteweb.com/archives/morgan_stanleys_matrix_an_app_from_the_future.php">RIA-powered capital markets bandwagon</a> again, only it was 4 years down the line. Sean Park and his team were ahead of the demand curve, offering something clients would want, but the disconnect between the two prevented the success Revolution should have been.</p>
<p><strong>Looking Around Today</strong><br />
I see a similar scenario developing in a nascent Northern Irish startup culture. A myriad of new media outlets encouraging the growth of chatter about chatter. Strong characters at the helm driving rapid policy creation around buzzwords. The usual presence of the me-tooers and their on-message signal/noise, and as this is Northern Ireland, an avalanche of support structures all offering their wares to the potential idea industry (for those familiar with the Province and it&#8217;s current systemic faults, see the rise of the victims industry, where everyone needs help with their troubles and no one is to blame for causing it). A packed diary of events fills out the days and weeks. The blogosphere is alive with what seems at times self-referential posts about this thought leader and that movement. It all seems so &#8216;go&#8217;. But is it?</p>
<p><strong>So Far, So Revolution</strong><br />
I think it is fair to say today&#8217;s NI does not have an outstanding reputation for entrepreneurship. Recession notwithstanding, we are still relatively over-dependent on civil service jobs and require a grant culture to encourage business development whether it is for blue chips locating their service centres here or local companies making a go of it. Like hawking web 2.0 to the investment banking industry, encouraging entrepreneurship here in the midst of a recession is a tough sell.</p>
<p>After a while the traditional bank hierarchy in Dresdner closed ranks on the would-be usurpers in it&#8217;s Digital Markets division. InvestNI &amp; the rest of the NI statutory bodies could well do the same to local efforts to establish a VC culture. Or they could try to shoehorn their own corporate objectives into the series of funding initiatives underway aimed at ideas (as opposed to companies).</p>
<p>Such a move would be a mistake, but within corporate strategy meetings it could be construed as synergistic. At Dresdner Park railed against the numbers men who &#8220;didn&#8217;t get it&#8221; at the time in internal blog postings. I detect the <a href="http://nispconnect.wordpress.com/2009/07/27/northern-ireland-2050">same hostility against traditional avenues</a> in NI&#8217;s would-be VC community. More <a href="http://cimota.com/blog/2009/07/14/the-first-handshake/">thoughtful criticism</a> of the traditionalists is also online. Either way, they highlight a problem that isn&#8217;t going to be removed unless success, measured in figures, is found.</p>
<p>A lot depends on the type of idea the monies will flow to. On the <a href="http://www.artscouncil-ni.org/award/innovation.html">24th of this month</a> the 1st round of potential startups will be announced. It may be a watershed moment for tech culture here. Interesting times.</p>
<p>Addendum: What was Dresdner&#8217;s failure, became <a href="http://www.nauiokaspark.com/">Sean Park&#8217;s success</a>. And maybe a man <a href="http://www.parkparadigm.com/2009/09/01/re-inventing-venture-capital/">who could help NI out</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/09/08/ecosystems-and-cajoling-participants/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Indy Gaming &amp; Destroying a Platform</title>
		<link>http://aleatory.clientsideweb.net/2009/07/11/indy-gaming-destroying-a-platform/</link>
		<comments>http://aleatory.clientsideweb.net/2009/07/11/indy-gaming-destroying-a-platform/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 17:05:30 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Tech Labours]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[information media]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/07/11/indy-gaming-destroying-a-platform/</guid>
		<description><![CDATA[This post started off as a comparison of two of the most prominent methods of indy game distribution on the web today &#8211; app stores &#38; social networks &#8211; but has morphed into something of a warning shot to platforms who allow their open networks to be ridden roughshot over by games ruthlessly seeking distribution [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/07/zynga-twitter-add.PNG" alt="Zynga Twitter integration: Why on Earth?" style="float: left" />This post started off as a comparison of two of the most prominent methods of indy game distribution on the web today &#8211; app stores &amp; social networks &#8211; but has morphed into something of a warning shot to platforms who allow their open networks to be ridden roughshot over by games ruthlessly seeking distribution above all else.</p>
<p>I had hoped to discuss some numbers taking both leading <a href="http://www.techcrunch.com/2009/03/06/some-indie-facebook-developers-pulling-in-over-700000-a-month/">Facebook</a> &amp; <a href="http://www.wired.com/gadgetlab/2009/02/shoot-is-iphone/">App Store</a> games as a jumping off point. But one look at my Twitter homepage this morning aroused some angst.</p>
<p>To their credit the realtime stream networks have opened up their far-reaching update networks to 3rd party developers without holding much back. Photos on facebook and throttling search on twitter are by and large minor holdups which would presumably have grave performance issues to overcome first anyway.</p>
<p>But this power in the hands of developers doesn&#8217;t come without responsibilities.</p>
<p><span id="more-125"></span>Unfortunately there has already been what I would call a serious breach of both the twitter and facebook reason d&#8217;etre &#8211; communication amongst the network. Check out <a href="http://www.marketing-ninja.com/facebook-app/monetizing-facebook-applications/">this post from back in 2007</a> for a critique of what makes a good facebook app &#8211; and this from a marketeer of all things. Now fast forward to today&#8217;s Twitter and check out one of the trending topics &#8211; &#8216;pirates&#8217;. Not because of the ongoing web meme &#8211; no this Pirates refers to Zynga&#8217;s social network app available on FB &amp; MySpace.</p>
<p>The lead graphic shows the gorey details &#8211; users are now encouraged to cross post their in-game achievements onto their twitter accounts. And because a bazillion of us play these games (&amp; are willing to do anything to get special items, including filling out marketing forms on anything from insurance to mobile phones) this created enough buzz through either direct postings or the predictable but similarly idiotic &#8220;why is pirates trending?&#8221; postings now proping up numerous worthless &#8216;trends&#8217; on Twitter these days.</p>
<p>But the value of trending topics once they have got onto the user&#8217;s twitter homepage is for another day. As is the dubious lengths some social gaming apps will go to in <a href="http://www.lightbluetouchpaper.org/2009/06/09/how-privacy-fails-the-facebook-applications-debacle/">supplying advert networks</a> with Facebook user data. These automated updates from gaming platforms need to be nipped in the bud right now.</p>
<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/07/pirates.PNG" alt="garbage." style="float: left" />One such tweet on the left here. When I think of why I have a Twitter account &#8211; to connect with interesting individuals whom I have nor might ever physically meet and to follow breaking news in near-realtime &#8211; this guff frankly does not appeal to me. It&#8217;s polluting twitter no doubt about it. As you can see Zynga have created their own special client to deliver inane bs direct to your homepage.</p>
<p>Personally I have a policy of immediately unfollowing anyone who feels it necessary to add such content to their account. Dealing with manual spam especially connected around trending topics is a more nuanced problem.</p>
<p>But mass auto distribution by gaming platforms can be nipped in the bud right now.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/07/11/indy-gaming-destroying-a-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Step by Step Guide to Creating a First Facebook App</title>
		<link>http://aleatory.clientsideweb.net/2009/07/05/step-by-step-guide-to-creating-a-first-facebook-app/</link>
		<comments>http://aleatory.clientsideweb.net/2009/07/05/step-by-step-guide-to-creating-a-first-facebook-app/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 23:28:41 +0000</pubDate>
		<dc:creator>rutherford</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Tech Labours]]></category>

		<guid isPermaLink="false">http://aleatory.clientsideweb.net/2009/07/05/step-by-step-guide-to-creating-a-first-facebook-app/</guid>
		<description><![CDATA[I&#8217;ve seen some how-to guides for getting started writing facebook apps on the web but none really cover everything from start to finish.  Even Facebook&#8217;s own documentation is somewhat disappointing.  So to help others find their way around Facebook markup and the life cycle of a Facebook application here is a simple tutorial.It [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/07/facebook.jpg" alt="facebook" style="margin: 4px; float: left" />I&#8217;ve seen some how-to guides for getting started writing facebook apps on the web but none really cover everything from start to finish.  Even Facebook&#8217;s own documentation is somewhat disappointing.  So to help others find their way around Facebook markup and the life cycle of a Facebook application here is a simple tutorial.It is a very basic app which aims to display a web image of the user&#8217;s choice a) in miniature on their profile, and b) in full on the application&#8217;s own canvas page.  What is a canvas page?  Simply the main page of your application that the user sees each time they click on your app.</p>
<p><strong>Prereqs:</strong><br />
What you&#8217;ll need &#8211; an account on Facebook and a web hosting provider who will run php scripts and allows you to set up a database.  I use mysql in this guide, but you can safely leave out the db steps if all you want to learn is the facebook-specific work flow stuff.<br />
<span id="more-118"></span><br />
<strong>Step 1:  Setting things up on Facebook.com</strong><br />
A Few things here -<br />
1) Add the Facebook <a href="http://www.facebook.com/developers/">Developer Application</a> to your profile if not done so already.<br />
2) Set up new app, give it a name.  Enter in the following details:<br />
Canvas Callback URL &#8211; the full url of the canvas page to be stored on your server.<br />
Canvas Url &#8211; the unique name for your app @http://apps.facebook.com/<yourappnamehere>.  You can flesh it out with icons, descriptions, etc too.<br />
3) Once you get the hang of things it becomes obvious two app instances are needed for each separate application you create &#8211; one live and one test.  However for the sake of brevity I&#8217;ll continue with a single instance.</yourappnamehere></p>
<p>Now it&#8217;s time to create your viral hit.  Download the client libs of your choice and we&#8217;ll look at how to create a setup page for users that wish to add your app.  For this demo I&#8217;ll be using the <a href="http://wiki.developers.facebook.com/index.php/PHP">official PHP client</a>.What we&#8217;ll be doing is showing a simple image.  We&#8217;ll go through all use cases a user will walk through over the lifetime of a facebook app together with the main social networking elements that make the facebook platform such a powerful medium for app developers.</p>
<p><strong>Step 2:  Config on your side</strong><br />
Now for the config in your php script.  Go to the file you entered in as the Canvas Callback URL &#8211; this is the jump-off point for all calls from Facebook to your application.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Include the Facebook client library</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Set authentication variables</span>
<span style="color: #000088;">$appapikey</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;yourkeyhere&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$appsecret</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;yoursecrethere&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><span style="color: #000088;">$appapikey</span><span style="color: #339933;">,</span> <span style="color: #000088;">$appsecret</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// I also will be accessing my own database on almost every call so will set db up here</span>
<span style="color: #000088;">$username</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourusername&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$password</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourpassword&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$database</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourdb&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span>localhost<span style="color: #339933;">,</span><span style="color: #000088;">$username</span><span style="color: #339933;">,</span><span style="color: #000088;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">@</span><span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$database</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Unable to select database&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You are now ready to interact with the Facebook api.</p>
<p><strong>Step 3:  Where to begin?</strong><br />
This was the first &#8211; and most dogged &#8211; question I asked myself when creating my first Facebook application.  As it turns out the workflow is quite like any other web app, with a few bells and whistles tacked on.</p>
<p>Let&#8217;s imagine for a second that user A already has our completed app installed.  User Bthen comes across it on User A&#8217;s profile, so they click through to the app&#8217;s canvas screen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">$url = '';
if(!($_GET['user']==NULL||$_GET['user']=='')){
//user wants to see someone elses profile
$user = $_GET['user'];
if(preg_match('/^[0-9]+z/', $user)){
//use id to retrieve img url from db
$query = 'select * from turl where userid = '.$user;
$result=mysql_query($query) or die(&quot;Couldn't execute query&quot;);
$url=mysql_result($result,0,&quot;url&quot;);}?&gt;&lt;img src=&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$url</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; /&gt;</pre></div></div>

<p>The above code looks for a &#8216;user&#8217; variable in the http query.  If it finds it (i.e. not null) it looks up the image url stored for the user sought (User A in this case) and displays.</p>
<p>I should also tell you a bit about the database at this stage.  It is simply a single table (turl) holding two fields url and userid (as in facebook userid).</p>
<p>So we have one use case.  But what if it&#8217;s user A who is clicking through to their own canvas page?  Should we make any additions?  Yes &#8211; we should give them the option of adding the image to their profile if they haven&#8217;t done already.  Fortunately interactions like this that deal with Facebook UI and concepts such as profile can be easily taken care of declaratively through Facebook Markup Langauge (FBML).  Here we add:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">==</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api_client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">users_getLoggedInUser</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: #666666; font-style: italic;">//user is looking at their own profile</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span> <span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;section_button&quot;</span><span style="color: #339933;">&gt;&lt;</span>fb<span style="color: #339933;">:</span>add<span style="color: #339933;">-</span>section<span style="color: #339933;">-</span>button section<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;profile&quot;</span><span style="color: #339933;">&gt;&lt;/</span>fb<span style="color: #339933;">:</span>add<span style="color: #339933;">-</span>section<span style="color: #339933;">-</span>button<span style="color: #339933;">&gt;&lt;/</span>p<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>api_client<span style="color: #339933;">-&gt;</span><span style="color: #004000;">users_getLoggedInUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://apps.facebook.com/&lt;yourappname&gt;&quot;</span><span style="color: #339933;">&gt;</span>Add your web image<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;,</span> <span style="color: #b1b100;">if</span> you haven<span style="color: #0000ff;">'t already!}</span></pre></div></div>

<p>If the user is looking at their own web image but hasn&#8217;t yet displayed it on their profile (either in the boxes tab or on the left hand strip on their wall tab) they will see the add to profile image below:</p>
<p><img src="http://aleatory.clientsideweb.net/wp-content/uploads/2009/07/fb-addtoprofile.PNG" alt="Add to Profile" /></p>
<p>The else statement checks if it&#8217;s another users image page and if so a rudimentary viral feature appears &#8211; asking the viewer if they want to try the app out too.</p>
<p><strong>Step 4:  Allowing a new user to preview</strong><br />
OK so back to User B.  Having clicked through to User A&#8217;s web image they like what they see &#8211; now they want to try things out for themselves.  At this stage some FB devs like to force the user to install the app &#8211; with a call to $facebook-&gt;require_login() &#8211; before they can try it out for themselves.  I don&#8217;t know about you but personally I find this a very annoying feature of 99% of FB apps so as a developer I want to give my users the option to preview their app first.</p>
<p>There is a drawback though.</p>
<p>$user = $facebook-&gt;require_login() is a really simple way of getting the user id, something you will need for virtually all meaningful interactions with the platform API.  Otherwise there are all sorts of possible ways a user can land on your canvas page without their user id being specified in the various Facebook ID fields sent with each request.  For example a user could enter the app url directly into the browser address bar or open from an email link.</p>
<p>Because the platform isn&#8217;t an exact science as such, with features, availability, etc changing quite a bit I&#8217;ve hacked around something that appears to work for me, i.e. it gets user ids in most situations without forcing an install on the user:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">}else{
if(!(($_GET[&quot;fb_sig_canvas_user&quot;]==NULL) ||($_GET[&quot;fb_sig_canvas_user&quot;]==''))){
$user = $_GET[&quot;fb_sig_canvas_user&quot;];}
elseif(!(($_REQUEST[&quot;fb_sig_user&quot;]==NULL) ||($_REQUEST[&quot;fb_sig_user&quot;]==''))){
$user = $_REQUEST[&quot;fb_sig_user&quot;];}
else{
$user = $facebook-&gt;api_client-&gt;canvas_user;}
if(($user==NULL)||($user=='')){
//if not already, try redirect
if (!isset($_REQUEST['reload'])){
$facebook-&gt;redirect($app_base_url.'?reload');}
else{?&gt;&lt;span&gt;You must be logged into Facebook to access web image&lt;/span&gt;<span style="color: #000000; font-weight: bold;">&lt;?</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><span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Step 5:  how to track your user base</strong><br />
Users.isAppUser has come under a lot of criticism.  Well, from me at least.  Because it only records if a user has previously authorised an app, and not if the app is currently authorised, facebook platform currently has no sure way of knowing if it is installed by a user right now.  So we create our own solution with the previously mentioned db table turl.  Turl&#8217;s two fields userid &amp; url tell us if the user has authorised the app (userid is present) and what web image they have displayed (url).  So now that we have the user id, we check for authorisation:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//set isAppUser</span>
<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'select * from turl where userid = '</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">;</span><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Couldn't execute query&quot;</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;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</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: #000088;">$isAppUser</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span>
<span style="color: #000088;">$isAppUser</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>if authorised we get the image url and show it on the canvas:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">if($isAppUser){
//display gfx, webform
$user = $facebook-&gt;require_login();
$query = 'select * from turl where userid = '.$user;
$result=mysql_query($query) or die(&quot;Couldn't execute query&quot;);
$url=mysql_result($result,0,&quot;url&quot;);?&gt;&lt;img src=&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$url</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; /&gt;&lt;p class=&quot;section_button&quot;&gt;&lt;fb:add-section-button section=&quot;profile&quot;&gt;&lt;/fb:add-section-button&gt;&lt;/p&gt; }</pre></div></div>

<p><strong>Step 6:  Adding a user proper</strong><br />
We&#8217;re on our 6th step so lets take stock of where we are.  We&#8217;ve taken into account a user viewing another users canvas page and also a user viewing their own page.  We&#8217;ve also got the user&#8217;s id and, assuming a user&#8217;s been added to the database successfully, can tell if they have installed the app.  Now we can begin to comtemplate how a user is added to our database.</p>
<p>First we should deal with the preview:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"> else{
?&gt;&lt;span&gt;Want to display a web image of your choice on Facebook?  Enter the url here:&lt;/span&gt;&lt;form action=&quot;.&quot; method=&quot;get&quot;&gt; &lt;input name=&quot;url&quot; type=&quot;text&quot; /&gt; &lt;input value=&quot;Preview&quot; type=&quot;submit&quot; /&gt;&lt;/form&gt;<span style="color: #000000; font-weight: bold;">&lt;?</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
<span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>And so we have the above catchall statement added if the user is not currently using the app, inviting them to preview it.  Once this form is submitted by the user we need to show the preview, so we include the following case before the form:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"> elseif(!($_GET['url']==NULL||$_GET['url']=='')){
$url=$_GET['url'];?&gt;&lt;img src=&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$url</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; /&gt;&lt;span&gt;Happy with this?  Click to install app&lt;/span&gt;&lt;form action=&quot;.&quot; method=&quot;get&quot;&gt; &lt;input value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$url</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; name=&quot;url&quot; type=&quot;hidden&quot; /&gt;&lt;input name=&quot;add&quot; type=&quot;hidden&quot; /&gt; &lt;input value=&quot;Add Web Image&quot; type=&quot;submit&quot; /&gt;&lt;/form&gt;<span style="color: #000000; font-weight: bold;">&lt;?</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we also have the preview step.  If the user wants to install at this stage we go ahead with the obligatory warning page and then we can perform the main installation tasks.  So another case goes in above the previous one:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"> <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'add'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">=</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">require_login</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;">//once authorised FB forwards the user with all existing request variables - back to this page, so we can continue installation on our side</span>
<span style="color: #000088;">$url</span><span style="color: #339933;">=</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span>url<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;insert into turl values ('<span style="color: #006699; font-weight: bold;">$user</span>','<span style="color: #006699; font-weight: bold;">$url</span>')&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fbml_profile</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;a href=&quot;http://apps.facebook.com/&lt;yourappname&gt;/?user='</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;&lt;img src=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$url</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot; width=&quot;182&quot; height=&quot;182&quot; /&gt;&lt;/a&gt;'</span><span style="color: #339933;">;</span><span style="color: #000088;">$fbml_boxes</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;a href=&quot;http://apps.facebook.com/&lt;yourappname&gt;/?user='</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;&lt;img src=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$url</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot; width=&quot;360&quot; height=&quot;100&quot; /&gt;&lt;/a&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api_client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">profile_setFBML</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fbml_boxes</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fbml_profile</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>After the user authorises the application we add the user to our db and also set the fbml markup for displaying the chosen web image on their profile wall or boxes tab.</p>
<p><strong>Step 7:  Adding Viral Features</strong><br />
Along with maybe the application directory, this is the most powerful aspect of the Facebook platform for developers.  Given the right incentives/marketing/branding/whatever you wish to call it, apps on facebook can spread like wildfire.  We will implement two features commonly used by FB developers to reach the tipping point &#8211; app invites and newsfeed stories.</p>
<p>Both are normally done at app sign up time and are used to inform members of the users personal network.  But they differ in that an invite is an explicit question targeted at friends of the user&#8217;s choice while adding it to a users newsfeed merely passively notifies people that they are using your application.  It&#8217;s harder to get a user to send out invites because they aren&#8217;t always welcome but if a user does target them successfully it may lead to a higher sign up rate amongst their friends.</p>
<p><strong>Step 7a:  Application Invite</strong><br />
First the app invite.  It takes the form of <a href="http://wiki.developers.facebook.com/index.php/Multi_friend_selector">more FBML</a> and presents itself in a separate page pretty much like the authorisation page, before redirecting the user back to our page again.  You don&#8217;t want the user to send out any to friends who already have the application, so here&#8217;s the code to display only those who don&#8217;t yet have them:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  $fql = 'SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1='.$user.') AND has_added_app=1';$_friends = $facebook-&gt;api_client-&gt;fql_query($fql);
// Extract the user ID's returned in the FQL request into a new array.
$friends = array();
if (is_array($_friends) &amp;&amp; count($_friends)) {
foreach ($_friends as $friend) {$friends[] = $friend['uid'];}}
// Convert the array of friends into a comma-delimeted string.
$friends = implode(',', $friends);
// Prepare the invitation text that all invited users will receive.
$content = &lt;&lt;&lt;fbml&gt;&lt;fb:name shownetwork=&quot;false&quot; firstnameonly=&quot;true&quot; uid=&quot;{$user}&quot;&gt; wants to see your web image!&lt;fb:req-choice label=&quot;Add Your web image to your profile&quot; url=&quot;{$facebook-&gt;get_add_url()}&quot;&gt;FBML;?&gt;&lt;fb:multi-friend-selector exclude_ids=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$friends</span><span style="color: #339933;">;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; rows=&quot;5&quot; showborder=&quot;true&quot; actiontext=&quot;Invite your friends not yet displaying their web image&quot; max=&quot;20&quot;&gt;&lt;/fb:multi-friend-selector&gt;&lt;/fb:req-choice&gt;&lt;/fb:name&gt;&lt;/fbml&gt;</pre></div></div>

<p><strong>Step 7b:  Wall Story</strong><br />
The <a href="http://wiki.developers.facebook.com/index.php/Feed.publishUserAction">Wall story request feature</a> is implemented as a popup using FBJS &#8211; the subset of javascript allowed on Facebook canvas pages.  It is slightly more complex than that unfortunately &#8211; you need to create a feed template first to describe the format of the story that will appear on users newsfeeds.</p>
<p>Go to the <a href="http://developers.facebook.com/tools.php?feed">template editor tool</a> to begin.  We&#8217;ll create a simple feed that shows your application logo and invites people to try it or view their friends web image.  First choose your application then create a one liner, note the special markup involved to allow personalisation.  3 main bits to note in this:</p>
<p>Short story template title &amp; body:<br />
Add in your message -&gt; &#8220;{*actor*} added their web image&#8221;</p>
<p>Sample template data: very important for ensuring your story appears how you wish.  Use it to experiment.</p>
<p>Action Link URL:To give friends a way of viewing the user&#8217;s own web image, enter the following -&gt; &#8220;http://apps.facebook.com/<yourapppage>/?user={userid}&#8221;</yourapppage></p>
<p>Click through next, Register Template Bundle and note down the ID generated.  It can get more powerful than this but it&#8217;s quite error prone for a beginner so lets keep things simple.  We&#8217;re halfway there &#8211; now back to your php code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"> &lt;script type=&quot;text/javascript&quot;&gt;
var tpl_data={&quot;status&quot;:&quot;status&quot;,&quot;images&quot;:[{&quot;src&quot;:&quot;&lt;yourapplogo&gt;&quot;, &quot;href&quot;:&quot;http://apps.facebook.com/&lt;yourapppage&gt;&quot;}],&quot;userid&quot;:&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span>user<span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;};
var user_msg = {&quot;value&quot;:&quot;&quot;};
var share_msg = &quot;share with your friends&quot;;
Facebook.showFeedDialog(&lt;feeddialogid&gt;, tpl_data, &quot;&quot;, &quot;&quot;, null, share_msg, user_msg);&lt;/script&gt;&lt;fb:request-form content=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; type=&quot;web image&quot; invite=&quot;true&quot; method=&quot;POST&quot; action=&quot;http://apps.facebook.com/&lt;youapppage&gt;/&quot;&gt;&lt;/fb:request-form&gt;} &lt;/yourapplogo&gt;</pre></div></div>

<p>Enter your feed dialog ID in the code above, together with your app logo url, etc.  As you can maybe workout, we substitute the the real data needed in tpl_data in place of the sample template data you seen in the feed templating tool.  Note we pass in our own user variable, necessary to know which users image the friend wants to view.</p>
<p><strong>Step 8:  Deleting user records</strong><br />
Almost done.  A user now can view other users web images &amp; install one on their own profile.  But what happens when a user deletes the app?  To avoid our database potentially filling up with duplicate user accounts (and if we want to keep an accurate record of the total number of installed users), we must create a 2nd php script that Facebook can call when a user deletes our app.</p>
<p>To do this, create a 2nd script on your web host then go back into the FB <a href="http://www.facebook.com/developers">dev application</a>, click on the &#8216;more&#8217; tab of our app then &#8216;edit settings&#8217; -&gt; &#8216;authentication&#8217; -&gt; &#8216;Post-Remove Callback URL&#8217;.  Enter in the full URL of this script.  All we need to do is delete the user from our db:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Include the Facebook client library</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Set authentication variables</span>
<span style="color: #000088;">$appapikey</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;yourkeyhere&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$appsecret</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;yoursecrethere&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><span style="color: #000088;">$appapikey</span><span style="color: #339933;">,</span> <span style="color: #000088;">$appsecret</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get_loggedin_user</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: #000088;">$user</span> <span style="color: #339933;">!=</span> <span style="color: #009900; font-weight: bold;">NULL</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fb_params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'uninstall'</span><span style="color: #009900;">&#93;</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: #666666; font-style: italic;">//The user has removed your app</span>
<span style="color: #000088;">$username</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourusername&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$password</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourpassword&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$database</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;yourdb&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span>localhost<span style="color: #339933;">,</span><span style="color: #000088;">$username</span><span style="color: #339933;">,</span><span style="color: #000088;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">@</span><span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$database</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Unable to select database&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'delete from turl where userid = '</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">;</span>mysql_query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Couldn't execute query&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>And that&#8217;s that!  A working Facebook application from the ground up with several important features explained.</p>
<p>For a complete listing of the code check out google docs <a href="http://docs.google.com/View?id=dhshn36t_44chw8bccj">add.php</a> &amp; <a href="http://docs.google.com/View?id=dhshn36t_46db48szcr">remove.php</a></p>
<p>Need a more in-depth explanation?  In my opinion the book that offers the most clarity on the subject is <a href="http://www.amazon.com/gp/product/059651817X?ie=UTF8&amp;tag=basrnigh-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=059651817X" target="_blank">Facebook Cookbook: Building Applications to Grow Your Facebook Empire</a> <img src="http://www.assoc-amazon.com/e/ir?t=basrnigh-20&amp;l=as2&amp;o=1&amp;a=059651817X" onmouseout="undefined" onmouseover="undefined" vspace="0" width="1" border="0" height="1" hspace="0" /></p>
]]></content:encoded>
			<wfw:commentRss>http://aleatory.clientsideweb.net/2009/07/05/step-by-step-guide-to-creating-a-first-facebook-app/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
	</channel>
</rss>
