<?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>Kevin &#34;Skwerl&#34; Cogill &#187; Technical</title>
	<atom:link href="http://iamskwerl.com/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://iamskwerl.com</link>
	<description>I would never call what I do &#34;hacking.&#34;</description>
	<lastBuildDate>Wed, 07 Mar 2012 22:09:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Custom Embed Code With JW Player For WordPress Plugin</title>
		<link>http://iamskwerl.com/tech/2012/03/custom-embed-code-with-jw-player-for-wordpress-plugin/</link>
		<comments>http://iamskwerl.com/tech/2012/03/custom-embed-code-with-jw-player-for-wordpress-plugin/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 19:43:40 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[JW Player]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Regex]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=215</guid>
		<description><![CDATA[If you care about this, I don&#8217;t need to give you too much background. Longtail&#8217;s JW Player is a great HTML5/Flash video player that has been around for years, with tons of plugins and a large user base, and at this point there&#8217;s very little you can&#8217;t do with it. At least as far as [...]]]></description>
			<content:encoded><![CDATA[<p>If you care about this, I don&#8217;t need to give you too much background. Longtail&#8217;s <a href="http://www.longtailvideo.com/players" target="_blank">JW Player</a> is a great HTML5/Flash video player that has been around for years, with tons of plugins and a large user base, and at this point there&#8217;s very little you can&#8217;t do with it. At least as far as playing audio and video goes.</p>
<p>The guy who coded most of JW Player&#8217;s core and plugins has also produced a handy <a href="http://www.longtailvideo.com/support/addons/jw-player-plugin-for-wordpress/11513/getting-started-with-the-wordpress-plugin-for-the-jw-pla" target="_blank">WordPress plugin</a> that lets you integrate JW Player into your WordPress site, and for the most part it works beautifully.</p>
<p>There&#8217;s at least one exception: While you have the option to integrate the sharing plugin via the plugin&#8217;s settings in WordPress, you have one global field for &#8220;embed code&#8221; that can&#8217;t really accept anything useful. You have to URI escape anything that goes in there (which wouldn&#8217;t be so bad if there was a way to URI unescape the output), and there&#8217;s no way to add a MEDIAID variable in there so that your embed code can be dynamic (which is a complete dealbreaker for almost every user).</p>
<p>Well, I needed this feature, so I found a workaround. And I didn&#8217;t want to go hacking into the plugin code (so that I could update it later, without clobbering my fix), so the way I did it was through a PHP regex in my theme&#8217;s functions.php.</p>
<p>I first did two things, only one of which should be necessary: In the plugin configuration, I set my custom embed code to <em>[FIXME]</em>, which is what my regex will look for, and replace with something useful.</p>
<p>Second, I edited sharing.xml in the WordPress plugin&#8217;s plugins directory, to use the sharing-3 repository, rather than sharing-1. I just prefer version 3&#8242;s interface, but I also figured newer was probably better. All I did was change the value of the &lt;repository&gt; field from <em>sharing-1</em> to <em>sharing-3</em>.</p>
<p>But here&#8217;s the fix: In my theme&#8217;s functions.php, I added a filter for the_content (set at priority 999 so it would run after the JW Player plugin has already replaced my shortcode with the complete embed code), which finds the MEDIAID, and finds my <em>[FIXME]</em> placeholder, and assembles a good embed code. &lt;embed id=&#8221;1&#8243; /&gt; is obviously not good embed code; that&#8217;s just for simplicity/illustration. You&#8217;ll want to replace that with <em>your</em> custom embed code, and <a href="http://www.longtailvideo.com/support/addons/sharing-plugin/14049/setting-clean-embed-codes" target="_blank">here are some ideas</a> on how to do that cleanly.</p>
<p><strong>Theme functions.php</strong></p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">function</span> swap_embed<span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$good_code</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;embed id=\&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'\&quot; /&gt;'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$replaced</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$good_code</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">',&quot;mediaid&quot;:&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$replaced</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> fix_jw_embed<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$regex</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/\&quot;(\[FIXME\])\&quot;(,.*)?,\&quot;mediaid\&quot;:\&quot;(\d{1,})\&quot;/i'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace_callback</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$regex</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'swap_embed'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$content</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'the_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fix_jw_embed'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">999</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Caveat: This only fixes the players in the post body, and not the one generated for the og:video tag for playable embedding on Facebook. I&#8217;ll be figuring that out later, and eventually adding the code to this piece, for anyone that needs it.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2012/03/custom-embed-code-with-jw-player-for-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Only Good Matte Screen Film For Macbook Air</title>
		<link>http://iamskwerl.com/tech/2011/11/matte-screen-film-for-macbook-air/</link>
		<comments>http://iamskwerl.com/tech/2011/11/matte-screen-film-for-macbook-air/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 19:25:58 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=183</guid>
		<description><![CDATA[I really do like my 13&#8243; Macbook Air more than I ever thought I could when Airs were first unveiled. I maxed out the RAM and HD, but I didn&#8217;t pick up the Ethernet adapter or external optical drive, and I haven&#8217;t really missed them. The battery life is great, and on the road, getting [...]]]></description>
			<content:encoded><![CDATA[<p>I really do like my 13&#8243; Macbook Air more than I ever thought I could when Airs were first unveiled. I maxed out the RAM and HD, but I didn&#8217;t pick up the Ethernet adapter or external optical drive, and I haven&#8217;t really missed them. The battery life is great, and on the road, getting real work done is about as convenient as opening up a magazine.</p>
<p>The only thing that gave me pause when I suddenly found myself needing a new laptop after the death of my 15&#8243; Macbook Pro was the fact that there was no option for a matte screen. Even though the Air&#8217;s screen is not quite as glossy as those of its peers, I <em>hate</em> (with the sort of <em>burning</em> passion reserved by developers/designers for seemingly inconsequential details such as mildly objectionable fonts and colors) glossy displays where a certain shade of red could be lord knows what wrong color depending on what angle you&#8217;re viewing at or what in the room is reflecting off your screen. Yes, we&#8217;re talking about the most minuscule of nitpicky details, and I&#8217;m a psycho, but whatever. I ams what I ams. So before I even turned my new Macbook Air on for the first time, I had installed a <a href="http://www.powersupportusa.com/accessories/macbook-air-13/anti-glare-film.html" target="_blank">Power Support anti-glare film</a>.</p>
<p>Over the course of the past 8-10 months or so or however long I&#8217;ve had the Air, I&#8217;ve changed the film a few times, due to OCD more than necessity. I&#8217;ve tried a bunch of less expensive films.</p>
<p>However, the Power Support films are the only ones that really do give you a great matte display, just like the ones Apple provides optionally for the Macbook Pros. No one even asked me, let alone paid me to tell you this. Just a public service announcement from one psychotic design geek to all others.</p>
<p>If you have an Air, buy a bunch while the company / product is still around.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/matte-screen-film-for-macbook-air/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Emails, Outlook And Background Images</title>
		<link>http://iamskwerl.com/tech/2011/11/html-emails-outlook-and-background-images/</link>
		<comments>http://iamskwerl.com/tech/2011/11/html-emails-outlook-and-background-images/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 21:39:50 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Outlook]]></category>
		<category><![CDATA[VML]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=172</guid>
		<description><![CDATA[Coding HTML for emails can be a total bitch. I&#8217;m not going to give an exhaustive how-to here, but I just wanted to share a few tricks I had to learn the hard way, in case it might save you some headaches. First, a few general rules. These rules will occasionally need to be broken, [...]]]></description>
			<content:encoded><![CDATA[<p>Coding HTML for emails can be a total bitch. I&#8217;m not going to give an exhaustive how-to here, but I just wanted to share a few tricks I had to learn the hard way, in case it might save you some headaches.</p>
<p>First, a few general rules. These rules will occasionally need to be broken, but if you start off by at least <em>trying</em> to follow them, you&#8217;ll give yourself a more stable foundation.</p>
<ul>
<li>Host all of your images online (or via a CDN/S3) and use absolute URLs. Of course.</li>
<li>Use old-school tables to position all of your elements. I know you spent a lot of time weaning yourself off them and mastering div tags positioned with CSS, but email clients rarely handle that stuff properly. For email, we&#8217;ve gotta take it all back to 1998.</li>
<li>When you do use CSS (which is by no means recommended against), put your styles either in-line, or in the body tag. Many email clients will chuck your head tag completely.</li>
<li>Set alt attributes for all of your images and links. I&#8217;ve seen email clients discard images and links that didn&#8217;t have alt attributes.</li>
<li>Explicitly setting border-collapse on your tables to collapse with CSS seems to help kill certain table spacing-related quirks.</li>
<li><a href="http://validator.w3.org/" target="_blank">Validate your HTML</a> at w3.org. Get it as close to perfectly valid as possible (necessary hacks may make perfect validity impossible).</li>
</ul>
<p>Now there&#8217;s one thing in particular that has given me an extraordinary amount of hell when doing HTML emails, and that is background images. Particularly when it comes to Outlook&#8217;s nasty habit of chucking them.</p>
<p>If you&#8217;re okay with having one big background image behind everything, you can apply a background image via CSS to the body tag. That actually works in Outlook. However, put your CSS inline or within the body tag (see above). I&#8217;ve also heard that you need to set repeat-y if you go this route; that setting CSS background-repeat to no-repeat will actually lose the background image completely in Outlook. Not sure if that&#8217;s always the case or what.</p>
<p>The holy grail here is applying background images to table cells. It doesn&#8217;t really work in Outlook. There is, however, a hack that I&#8217;ve found, and that is the main thing I wanted to share here today:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span> <span style="color: #000066;">width</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #000066;">border</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellpadding</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellspacing</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;border-collapse: collapse;&quot;</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;width: 600px; height: 350px; background-image: url('http://epicreviewsdotorg.files.wordpress.com/2011/05/unicorn1.jpg');&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">&lt;!--[if gte mso 9]&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;v:image xmlns:v=&quot;urn:schemas-microsoft-com:vml&quot; id=&quot;theImage&quot; style='behavior: url(#default#VML); display: inline-block; position: absolute; width: 600px; height: 350px; top: 0; left: 0; border: 0; z-index: 1;' src=&quot;http://epicreviewsdotorg.files.wordpress.com/2011/05/unicorn1.jpg&quot; /&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;v:shape xmlns:v=&quot;urn:schemas-microsoft-com:vml&quot; id=&quot;theText&quot; style='behavior: url(#default#VML); display: inline-block; position: absolute; width: 600px; height: 350px; top: -5; left: -10; border: 0; z-index: 2;'&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;div&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;![endif]--&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span> <span style="color: #000066;">width</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #000066;">border</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellspacing</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellpadding</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;border-collapse: collapse;&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;350&quot;</span> <span style="color: #000066;">align</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;center&quot;</span> <span style="color: #000066;">valign</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;top&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>This table in here has a bunch of stuff I want to lay over the background image...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span> &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">tr</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">&lt;!--[if gte mso 9]&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/v:shape&gt;</span><br />
<span style="color: #808080; font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;![endif]--&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">tr</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span></div></td></tr></tbody></table></div>
<p>Outlook can&#8217;t (or refuses to) render basic CSS, but it <em>does</em> know VML (Vector Markup Language), which is what Microsoft Office uses to position elements in Word and Powerpoint. So what we&#8217;re doing is targeting Outlook specifically, and hitting it with some VML.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/html-emails-outlook-and-background-images/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Passing Query Variables To Facebook Fan Page Tabs</title>
		<link>http://iamskwerl.com/tech/2011/11/passing-query-variables-to-facebook-fan-page-tabs/</link>
		<comments>http://iamskwerl.com/tech/2011/11/passing-query-variables-to-facebook-fan-page-tabs/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 02:08:25 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=145</guid>
		<description><![CDATA[UPDATE: Apparently, you can pass variables in using Facebook&#8217;s app_data parameter, and then grab them by parsing out the signed request. Hard to say which is now the easier solution, but here&#8217;s another option, for whatever it&#8217;s worth. I guess it would be the way to go if you wanted to keep data out of [...]]]></description>
			<content:encoded><![CDATA[<p><em>UPDATE: Apparently, you can pass variables in using Facebook&#8217;s <a href="http://ikorolchuk.blogspot.com/2011/03/facebook-fan-page-pass-parameter-to.html" target="_blank">app_data parameter</a>, and then grab them by parsing out the signed request. Hard to say which is now the easier solution, but here&#8217;s another option, for whatever it&#8217;s worth. I guess it would be the way to go if you wanted to keep data out of the URL, or if you want a solution that also works outside of Facebook.</em></p>
<p>Here&#8217;s a trick to let you Facebook app developers do a couple of things that are typically considered impossible.</p>
<p>Let&#8217;s say you have a Facebook app with a Page Tab, and you want to pass it some dynamic variables from an external site or a share post. While you can link directly to a tab by appending an ?sk=app_ to the page URL <a href="http://www.facebook.com/pages/The-Mirthful-Squirrel/339835768589?sk=app_345186569012" target="_blank">(example)</a>, any custom, non-Facebook variables appended to the URL won&#8217;t be passed through to your tab page.</p>
<p>Another problem: Let&#8217;s say that tab page has links to sub-pages that load within the main tab iFrame (a la target=&#8221;_self&#8221;). That&#8217;s all easy enough, and pretty common. But what happens when you want to link to sub-sections of your tab page from an external site or share post?</p>
<p>You can&#8217;t get variables in through the &#8220;front door&#8221; so to speak, but you <em>can</em> pass them around the back, using what I call &#8220;the cookie trick&#8221; (or, inexplicably, &#8220;cookie party,&#8221; when it&#8217;s late in the office and we&#8217;re all loopy and/or drunk). The trick involves using a redirect that stores dynamic variables in a cookie, and then sends a user to the tab. When the tab loads, it grabs the data it needs from the cookie, and then deletes it. It&#8217;s completely transparent to the end-user.</p>
<p>Here&#8217;s all it takes. First, a redirect script:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$var</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'var'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'var'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myapp_var'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$var</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">3600</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><br />
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$fb_app_url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Then, your main tab page just needs to check for the cookie, get what it needs, and then delete it:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$var</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'myapp_var'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'myapp_var'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myapp_var'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">86400</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Do stuff with $var...</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Voila. You just send your vars to something like redirect.php?var=foo, and they&#8217;re slipped to your tab via the cookie.</p>
<p>If you want to link to a sub-page, just pass the sub-page path into your redirect.php as a variable, and then use a PHP header() redirect, or output a line of Javascript to send your users where they need to go.</p>
<p>Here&#8217;s an example of a deep-link to one of four mini-games in a Page Tab I built for The Black Eyed Peas Experience game: <a href="http://promethiumtorch.com/bep/redirect.php?goto=whatsyourgroove" target="_blank">http://promethiumtorch.com/bep/redirect.php?goto=whatsyourgroove</a></p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/passing-query-variables-to-facebook-fan-page-tabs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating Distances Between Addresses</title>
		<link>http://iamskwerl.com/tech/2011/11/calculating-distances-between-addresses/</link>
		<comments>http://iamskwerl.com/tech/2011/11/calculating-distances-between-addresses/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 22:05:33 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=110</guid>
		<description><![CDATA[Here&#8217;s a basic rundown of one way (there are many) to build a store locator. Essentially it boils down to three steps: Geocode a table of addresses to latitude and longitude coordinates using the Google Maps API (only need to do this once). Geocode a query string to get its latitude and longitude coordinates. Query addresses from [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a basic rundown of one way (there are many) to build a store locator.</p>
<p>Essentially it boils down to three steps:</p>
<ol>
<li>Geocode a table of addresses to latitude and longitude coordinates using the Google Maps API (only need to do this once).</li>
<li>Geocode a query string to get its latitude and longitude coordinates.</li>
<li>Query addresses from DB by comparing latitude and longitude using the <a href="http://en.wikipedia.org/wiki/Haversine_formula" target="_blank">Haversine formula</a>.</li>
<li>Bask in the warm glow of trigonometry.</li>
</ol>
<p>Let&#8217;s start with the DB table. Since we&#8217;re going to be querying based on latitude and longitude, those two fields should be set as keys. Your MySQL server will probably cry if you don&#8217;t do this. And your queries may be noticeably slow.</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> <span style="color: #008000;">`stores`</span> <span style="color: #FF00FF;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`id`</span> <span style="color: #999900; font-weight: bold;">INT</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">3</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">UNSIGNED</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span> <span style="color: #FF9900; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`store<span style="color: #008080; font-weight: bold;">_</span>name`</span> <span style="color: #999900; font-weight: bold;">VARCHAR</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">64</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`store<span style="color: #008080; font-weight: bold;">_</span>address`</span> <span style="color: #999900; font-weight: bold;">VARCHAR</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">128</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`store<span style="color: #008080; font-weight: bold;">_</span>city`</span> <span style="color: #999900; font-weight: bold;">VARCHAR</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">64</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`store<span style="color: #008080; font-weight: bold;">_</span>state`</span> <span style="color: #999900; font-weight: bold;">VARCHAR</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">64</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`latitude`</span> <span style="color: #999900; font-weight: bold;">DECIMAL</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #000033;">,</span><span style="color: #008080;">7</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">`longitude`</span> <span style="color: #999900; font-weight: bold;">DECIMAL</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #000033;">,</span><span style="color: #008080;">7</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #990099; font-weight: bold;">PRIMARY KEY</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`id`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #990099; font-weight: bold;">KEY</span> <span style="color: #008000;">`lat<span style="color: #008080; font-weight: bold;">_</span>key`</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`latitude`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #990099; font-weight: bold;">KEY</span> <span style="color: #008000;">`lng<span style="color: #008080; font-weight: bold;">_</span>key`</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`longitude`</span><span style="color: #FF00FF;">&#41;</span><br />
<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">ENGINE</span><span style="color: #CC0099;">=</span>MyISAM <span style="color: #FF9900; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #CC0099;">=</span><span style="color: #008080;">1</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #FF9900; font-weight: bold;">CHARSET</span><span style="color: #CC0099;">=</span>utf8<span style="color: #000033;">;</span></div></td></tr></tbody></table></div>
<p>Populate your table of stores, leaving the latitude and longitude fields blank. Then, you can fill those fields by looping through the table, pinging them against the Google Maps API, and popping off AJAX calls to update your DB table:</p>
<p>(You&#8217;ll need to include the Maps API Javascript, and jQuery will help you with the AJAX calls.)</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://maps.googleapis.com/maps/api/js?sensor=false&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></div></td></tr></tbody></table></div>
<p>You&#8217;ll want to query your table of stores, assembling an array of address strings, and encoding them to a JSON array or something using the row IDs as the keys. Then, loop through it:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> geocoder <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Geocoder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> index <span style="color: #000066; font-weight: bold;">in</span> addresses<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; geocoder.<span style="color: #660066;">geocode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">'address'</span><span style="color: #339933;">:</span>addresses<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>results<span style="color: #339933;">,</span> <span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">status</span> <span style="color: #339933;">==</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">GeocoderStatus</span>.<span style="color: #660066;">OK</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; latitude <span style="color: #339933;">=</span> results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">geometry</span>.<span style="color: #660066;">location</span>.<span style="color: #660066;">lat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; longitude <span style="color: #339933;">=</span> results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">geometry</span>.<span style="color: #660066;">location</span>.<span style="color: #660066;">lng</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;insert.php&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span>index<span style="color: #339933;">,</span> lat<span style="color: #339933;">:</span>latitude<span style="color: #339933;">,</span> lng<span style="color: #339933;">:</span>longitude <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>You can update a DB, right? Your insert.php would look something like this:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PDO<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mysql:host='</span><span style="color: #339933;">.</span>DB_HOST<span style="color: #339933;">.</span><span style="color: #0000ff;">';dbname='</span><span style="color: #339933;">.</span>DB_NAME<span style="color: #339933;">,</span> DB_USER<span style="color: #339933;">,</span> DB_PASSWORD<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$q</span><span style="color: #339933;">=</span><span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'INSERT INTO stores (latitude,longitude) VALUES (?,?) WHERE id = ?'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lat'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lng'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>If you hate Javascript (or just suck at it), you could go with this super simple PHP route to get latitude and longitude from Google (thanks <a href="http://www.westonradcliffe.com/" target="_blank">Weston</a>):</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$geocode</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://maps.google.com/maps/api/geocode/json?address=/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$address</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&amp;sensor=false'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$geocode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$lat</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">geometry</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">location</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lat</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$lon</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">geometry</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">location</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lng</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">// Insert to DB...</span></div></td></tr></tbody></table></div>
<p>That&#8217;s step one, the hardest part, the part that only needs to be done once. Once you&#8217;ve got that groundwork done, your DB is ready for real user queries.</p>
<p>First, take the user&#8217;s input query and Geocode it, using either method above (Javascript or PHP), to get the latitude and longitude. Once you have those, you can do one clean MySQL query to get locations ordered by distance (replace QUERY_LAT and QUERY_LON with the latitude and longitude returned from Google, respectively):</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span><span style="color: #000033;">,</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">3959</span> <span style="color: #CC0099;">*</span> <span style="color: #000099;">acos</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">cos</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>QUERY_LAT<span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">*</span> <span style="color: #000099;">cos</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>latitude<span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">*</span> <span style="color: #000099;">cos</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>longitude<span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">-</span> <span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>QUERY_LON<span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">+</span> <span style="color: #000099;">sin</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>QUERY_LAT<span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">*</span> <span style="color: #000099;">sin</span><span style="color: #FF00FF;">&#40;</span><span style="color: #000099;">radians</span><span style="color: #FF00FF;">&#40;</span>latitude<span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">AS</span> <span style="color: #00CC00;">distance</span> <span style="color: #990099; font-weight: bold;">FROM</span> stores <span style="color: #990099; font-weight: bold;">ORDER BY</span> <span style="color: #00CC00;">distance</span><span style="color: #000033;">;</span></div></td></tr></tbody></table></div>
<p>Fuck yeah, math.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/calculating-distances-between-addresses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>24-Bit Audio Explained</title>
		<link>http://iamskwerl.com/tech/2011/11/24-bit-audio-explained/</link>
		<comments>http://iamskwerl.com/tech/2011/11/24-bit-audio-explained/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 19:13:57 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Musical]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=108</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/24-bit-audio-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Random Selection With Weight</title>
		<link>http://iamskwerl.com/tech/2011/11/random-selection-with-weight/</link>
		<comments>http://iamskwerl.com/tech/2011/11/random-selection-with-weight/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 18:39:10 +0000</pubDate>
		<dc:creator>Skwerl</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://iamskwerl.com/?p=86</guid>
		<description><![CDATA[I’d like to share with you a simple algorithm for taking random selections from a set of items while factoring in a manual, arbitrary “weighting” mechanism.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to share with you a simple algorithm for taking random selections from a set of items while factoring in a manual, arbitrary &#8220;weighting&#8221; mechanism.</p>
<p>We&#8217;re assuming that the default weight is 1, and that a weight of 0 would exclude an item from the result set. Whether or not there is a &#8220;maximum&#8221; weight is irrelevant to this algorithm.</p>
<p>The idea is that you first sum all of the weights together, to get a grand total of the combined weight of all items in the result set. Now imagine all of your results lined up in a straight line, with the size of their spot in the line determined by their weight. So if the first item has a weight of 50, its spot in line goes from points 1 to 51. If the second item has a weight of 20, it goes from points 52 to 72. And so on, with the last item ending at that cumulative total we calculated.</p>
<p>What you then do is pick random numbers between (and including) 1 and that cumulative total. Whatever item is occupying that position in the line is your winner. Repeat for as many results as you need.</p>
<p>If your data is in a MySQL database, you can add a running cumulative count to the results array using a MySQL variable:</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SET</span> @csum <span style="color: #CC0099;">:=</span> <span style="color: #008080;">0</span><span style="color: #000033;">;</span><br />
<span style="color: #990099; font-weight: bold;">SELECT</span><br />
&nbsp; &nbsp; item.id<span style="color: #000033;">,</span><br />
&nbsp; &nbsp; item.name<span style="color: #000033;">,</span><br />
&nbsp; &nbsp; item.<span style="color: #000099;">field</span><span style="color: #000033;">,</span><br />
&nbsp; &nbsp; item.weight<span style="color: #000033;">,</span><br />
&nbsp; &nbsp; <span style="color: #FF00FF;">&#40;</span>@csum <span style="color: #CC0099;">:=</span> @csum <span style="color: #CC0099;">+</span> item.weight<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">as</span> cumulative_sum<br />
<span style="color: #990099; font-weight: bold;">FROM</span> items <span style="color: #990099; font-weight: bold;">as</span> item<br />
<span style="color: #990099; font-weight: bold;">WHERE</span> item.weight <span style="color: #CC0099;">&gt;</span> <span style="color: #008080;">0</span><br />
<span style="color: #990099; font-weight: bold;">ORDER BY</span> id<span style="color: #000033;">;</span></div></td></tr></tbody></table></div>
<p>Then you iterate through a loop for as many random selections as you need, counting up to the item whose cumulative_sum contains your random number. For example, in PHP:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$winners</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$has_enough</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$random_index</span> <span style="color: #339933;">=</span> <span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #000088;">$cumulative_total</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$items</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cumulative_sum'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$random_index</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$winners</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Set $has_enough to true when you have enough...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>All in all, very efficient.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamskwerl.com/tech/2011/11/random-selection-with-weight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

