<?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>Graphics by Greg</title>
	<atom:link href="http://www.gregphoto.net/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gregphoto.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sat, 03 Mar 2012 18:41:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.6.13</generator>
	<item>
		<title>ObservableTrait &#8211; Experiment with PHP 5.4</title>
		<link>http://www.gregphoto.net/index.php/2012/03/03/observabletrait-experiment-with-php-5-4/</link>
		<pubDate>Sat, 03 Mar 2012 18:41:47 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=117</guid>
		<description><![CDATA[PHP 5.4 was released this week, and one of the biggest new capabilities from a language perspective is traits, called mixins in some other languages. Traits are basically a way of creating a set of reusable methods and properties and adding them to class, almost like copy paste. In a way this is like inheritance, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PHP 5.4 was released this week, and one of the biggest new capabilities from a language perspective is <a href="http://us2.php.net/manual/en/language.oop5.traits.php">traits</a>, called mixins in some other languages.  Traits are basically a way of creating a set of reusable methods and properties and adding them to class, almost like copy paste.  In a way this is like inheritance, but a class can use multiple traits to add multiple capabilities.  Whereas with inheritance you say something like &#8216;a Dog is an Animal&#8217;, with traits you say &#8216;a Dog can be observed&#8217;.</p>
<p>To try out traits I took inspiration from JavaScript, a language that I&#8217;ve been using quite a bit recently.  Client-side javascript for complex applications is very event driven and accordingly makes heavy use of event listeners &#8211; both DOM events and custom events.  One approach that I&#8217;ve been impressed with is <a href="http://www.sencha.com/">Sencha&#8217;s</a> <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.util.Observable">Observable</a> class/mixin that allows classes to easily fire events and notify any listeners without tightly coupling the listeners and the observed.  </p>
<p>While PHP is significantly less event driven (user input only comes at the beginning of a script), I thought that implementing a similar Observable mechanism would be a good way to try out the new feature. I&#8217;ve added the trait to <a href="https://github.com/gneustaetter/gUtils">my growing library of utility classes on Github</a>.  Here&#8217;s how it works:</p>
<p>1. A class uses the ObservableTrait and then fires events whenever an important event occurs:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
require_one<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'gUtils/ObservableTrait.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">Class</span> Dog <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">use</span> gUtils\ObservableTrait<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> bark<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;woof woof<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fireEvent</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'barked'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> rollOver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'('</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; rolls over)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fireEvent</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'didTrick'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'roll over'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> shake<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'('</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; shakes hands)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fireEvent</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'didTrick'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'shake hands'</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></td></tr></table></div>

<p>The calls to fireEvent include the name of the event, and any additional parameters that should be passed to any listener.</p>
<p>2. On instantiation of an object, listeners can be attached to the object to be notified when particular events occur:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Dog.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Dog<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Fido'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$listeners</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addListeners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #0000ff;">'barked'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dog</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Shhh '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$dog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'didTrick'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dog</span><span style="color: #339933;">,</span> <span style="color: #000088;">$trickName</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Good dog, '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$dog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; - I love it when you <span style="color: #006699; font-weight: bold;">{$trickName}</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</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;">// Shhh Fido</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollOver</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;">// Good dog, Fido - I love it when you roll over</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">shake</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;">// Good dog, Fido - I love it when you shake hands</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">stopEvents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;stopped listening for a while<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">shake</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">resumeEvents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;listening again<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</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;">// Shhh Fido</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">removeListener</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$listeners</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;removed bark listener<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bark</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fido</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollOver</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;">// Good dog, Fido - I love it when you roll over</span></pre></td></tr></table></div>

<p>And that&#8217;s about it &#8211; you can:</p>
<ul>
<li>Add Events</li>
<li>Add Listeners (one at a time or multiple)</li>
<li>Remove Listeners (one at a time or multiple)</li>
<li>Stop throwing events</li>
<li>Resume throwing events</li>
<li>Remove all listeners</li>
</ul>
<p>So <a href="https://github.com/gneustaetter/gUtils/blob/master/gUtils/ObservableTrait.php">take a look</a> and let me know what you think&#8230;</p>
]]></content:encoded>
			</item>
		<item>
		<title>InputValidator &#8211; Simple Input Validation for PHP</title>
		<link>http://www.gregphoto.net/index.php/2011/12/26/inputvalidator-simple-input-validation-for-php/</link>
		<comments>http://www.gregphoto.net/index.php/2011/12/26/inputvalidator-simple-input-validation-for-php/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 00:24:00 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=108</guid>
		<description><![CDATA[I recently needed a library for validating form input and everything seemed either verbose or required a huge number of files and libraries to be included. Here&#8217;s what I was looking for: Easy to include in projects without having to change include paths, mess with auto loaders, or include other frameworks Something that minimized the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I recently needed a library for validating form input and everything seemed either verbose or required a huge number of files and libraries to be included.  Here&#8217;s what I was looking for:</p>
<ul>
<li>Easy to include in projects without having to change include paths, mess with auto loaders, or include other frameworks</li>
<li>Something that minimized the amount of validation code that needed to be written, preferably with a fluent interface</li>
<li>Ability to generate error messages that can be shown to the end user</li>
<li>Ability to transform data to data types needed by the rest of the script</li>
<li>Capability to validate against arbitrary regexes</li>
<li>Capability to validate against closures or other external functions</li>
</ul>
<p>I couldn&#8217;t find exactly what I was looking for, so I decided to write it myself.  I added the result, InputValidator, to my <a href="https://github.com/gneustaetter/gUtils">gUtils</a> collection of PHP classes on Github.  InputValidator is a standalone script for validating user input from forms or other sources.  </p>
<p>Everything is in a single file, making it easy to include in any (PHP 5.3+) project. Here&#8217;s some example usage:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'gUtils/InputValidator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// this could be from $_POST</span>
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Greg Neustaetter'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'email'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'greg@emailaddress.com'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'website'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'http://www.gregphoto.net'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'favoriteNumber'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'xyz'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'date'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'11/11/2011'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// pass in the data to be validated</span>
<span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> gUtils\InputValidator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// validate each field</span>
<span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">required</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">length</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'email'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Email Address'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">required</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">email</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'website'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'favoriteNumber'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Your favorite number'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">intRange</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toInt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'date'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toDateTime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'m/d/Y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">after</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// after the current time</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allValid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;pre&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrors</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// returns an array of errors indexed by field</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;pre&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</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: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValues</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;">// returns an array of values indexed by field</span>
<span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// get the value of name</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$v</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">escape</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// escape the value of name for output with htmlspecialchars</span></pre></td></tr></table></div>

<p>This script would print the following error array:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'favoriteNumber'</span> <span style="color: #339933;">=&gt;</span> Your favorite number must be an integer between <span style="color: #cc66cc;">0</span> and <span style="color: #cc66cc;">100</span>
    <span style="color: #0000ff;">'date'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Date</span> cannot be before <span style="color: #cc66cc;">12</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2011</span>
<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>In addition to validation the library includes a few filters to manipulate data and cast it to formats needed by your code.  Take a look at <a href="https://github.com/gneustaetter/gUtils/wiki/InputValidator-Documentation">the documentation</a> on the Github wiki for a list of the 20 validators and the 8 filters. </p>
<p>Let me know if you find it useful or if you have any feedback&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2011/12/26/inputvalidator-simple-input-validation-for-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RecursiveFileExtensionFilteredIterator</title>
		<link>http://www.gregphoto.net/index.php/2011/06/09/recursivefileextensionfilterediterator/</link>
		<pubDate>Fri, 10 Jun 2011 05:28:36 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=102</guid>
		<description><![CDATA[RecursiveFileExtensionFilteredIterator &#8211; rolls right off the tongue, right? Recently I had the need to find all of the files in a fairly big directory structure that were web pages &#8211; in my case, files with the .php and .html extensions. There were hundreds of directories and thousands of files to go through, so I decided [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>RecursiveFileExtensionFilteredIterator &#8211; rolls right off the tongue, right?  </p>
<p>Recently I had the need to find all of the files in a fairly big directory structure that were web pages &#8211; in my case, files with the .php and .html extensions.  There were hundreds of directories and thousands of files to go through, so I decided to write a php script to find the files and then execute some code on the resulting files.  </p>
<p>I abstracted out the code to find files matching a particular extension and have posted the (minimal) code on <a href="https://github.com/gneustaetter/gutils">Github</a> as <a href="https://github.com/gneustaetter/gutils/blob/master/src/RecursiveFileExtensionFilteredIterator.php">RecursiveFileExtensionFilteredIterator</a>.  The 20 or so lines of code makes use of a couple of PHP&#8217;s <a href="http://www.php.net/manual/en/spl.iterators.php">SPL iterators</a> including the <a href="http://www.php.net/manual/en/class.recursivedirectoryiterator.php">Recursive Directory Iterator</a>, the <a href="http://www.php.net/manual/en/class.recursiveiteratoriterator.php">the Recursive Iterator Iterator</a>, and the <a href="http://www.php.net/manual/en/class.filteriterator.php">Filter Iterator</a>.  The result of this is a simple class that allows you to loop through a directory recursively to find only files that match a particular set of extensions, returning a <a href="http://us2.php.net/manual/en/class.splfileinfo.php">SplFileInfo</a> object for each file.  Here&#8217;s a simple example that prints out all of the paths:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'RecursiveFileExtensionFilteredIterator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$path</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/path/to/starting/directory'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$extensions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'html'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$files</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecursiveFileExtensionFilteredIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #000088;">$extensions</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$files</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPathname</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>that&#8217;s it &#8211; short and sweet.  </p>
]]></content:encoded>
			</item>
		<item>
		<title>PasswordHelper: PHP library for password hashing and more</title>
		<link>http://www.gregphoto.net/index.php/2011/01/19/passwordhelper-php-library-for-password-hashing-and-more/</link>
		<comments>http://www.gregphoto.net/index.php/2011/01/19/passwordhelper-php-library-for-password-hashing-and-more/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 03:24:41 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=92</guid>
		<description><![CDATA[Only two years since my last post 🙂 I was fixing up an old website I had built to improve the security and as part of that I wanted to improve the way in which passwords were stored, created, and verified for complexity. As part of this I built PasswordHelper, a small PHP library (61 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Only two years since my last post <img src="https://s.w.org/images/core/emoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>I was fixing up an old website I had built to improve the security and as part of that I wanted to improve the way in which passwords were stored, created, and verified for complexity.  As part of this I built <a href="/projects/passwordHelper">PasswordHelper</a>, a small PHP library (61 lines of code) described on the <a href="/projects/passwordHelper">overview/download/documentation/example</a> page as follows:</p>
<p>&#8212;&#8212;&#8212;&#8211;</p>
<p>PasswordHelper is a lightweight <b>BSD licensed</b> PHP class that has a number of password related utility functions that make it easy to:</p>
<ul>
<li><b>Securely store passwords</b> by hashing them with the adaptive <b>Blowfish/bcrypt</b> algorithm with random salt values</li>
<li>Compare user submitted passwords with stored password hashes</li>
<li>Generate <b>random passwords</b></li>
<li>Validate <b>password complexity</b> for length and matches to a configurable set of regular expressions</li>
</ul>
<p>	The library does nothing too complex &#8211; it just makes it easy to do common things to help create more secure PHP applications utilizing existing PHP functions through a simpler API.  Most of the <a href="http://www.php.net/manual/en/function.crypt.php">existing APIs</a> seem a bit&#8230;cryptic (ha ha, right?) and there are so many options and algorithms from which to choose.  Choosing the &#8216;wrong&#8217; algorithm for password hashing can lead to big problems, like the ability for hackers to <a href="http://www.duosecurity.com/blog/entry/brief_analysis_of_the_gawker_password_dump">brute force hundreds of thousands of passwords from your database in an hour</a>.</p>
<p>&#8212;&#8212;&#8212;&#8211; </p>
<p>Here&#8217;s a quick example of how it is used:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PasswordHelper.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$pass</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PasswordHelper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Hash a password with bcrypt and a random salt before storing it in a database</span>
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pass</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generateHash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myP@ssword'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Validate the password against the stored hash on a login attempt</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pass</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">compareToHash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myWrongPassword'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$hash</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;">// password matches	</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// password doesn't match</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Generate a random password</span>
<span style="color: #000088;">$randomPassword</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pass</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generateRandomPassword</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Validate the complexity of a password</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pass</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">checkPasswordComplexity</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$password</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;">// password meets requirements	</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// password doesn't meet requirements</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><a href="/projects/passwordHelper">Check it out</a> if you need some help with passwords in your PHP application&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2011/01/19/passwordhelper-php-library-for-password-hashing-and-more/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Review: Balsamiq Mockups</title>
		<link>http://www.gregphoto.net/index.php/2009/04/22/review-balsamiq-mockups/</link>
		<comments>http://www.gregphoto.net/index.php/2009/04/22/review-balsamiq-mockups/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 06:51:16 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=59</guid>
		<description><![CDATA[In my job as a product manager one of my key responsibilities is designing high-productivity software that is easy to use and powerful. We work in a complex domain that involves massive amount of data, millions of dollars on the line, and tight deadlines. We attack these complex software with advanced technology, masked in easy [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In my <a href="http://www.stratify.com">job</a> as a product manager one of my key responsibilities is designing high-productivity software that is easy to use and powerful.  We work in a complex domain that involves massive amount of data, millions of dollars on the line, and tight deadlines.  We attack these complex software with advanced technology, masked in easy to use software.</p>
<p>One of the challenges with user interface development &#8211; and all software development, for that matter &#8211; is that the further down the line in development something goes, the harder it is to change.  Once a developer spends days or weeks working on something the resistance becomes huge as people are attached to their work &#8211; regardless of whether it is a good fit for the customer.  To counter these problems, I&#8217;m a big advocate of building mockups in order to sort out the key design issues before significant development happens.</p>
<p>Over the years, I&#8217;ve used the following types of tools to do this:</p>
<ul>
<li>Whiteboards with digital camera snapshots</li>
<li>Pen and paper sketches scanned</li>
<li>Photoshop / image mockups</li>
<li>HTML mockups</li>
<li>PHP prototypes</li>
</ul>
<p>I use these various tools to build mockups for a variety of applications including native windows applications, classical web applications, and dynamic ajax applications.  The more complex applications become, with complex widgets such as data grids, trees, and tabs, the tougher the hurdles are to crank out a quick mockup.  The other problem I&#8217;ve seen is that the closer to &#8216;real&#8217; a mockup looks, the more people are going to comment on the nitty gritty details instead of focusing on the key issues of workflow and usability &#8211; just like the problem of developers getting attached to something they&#8217;ve worked on, reviewers of super realistic models seem to often just assume that they can&#8217;t question the general structure and end up commenting on alignment issues, colors, etc.</p>
<p>I&#8217;m always on the prowl for new tools to use in this design phase, and have recently come across a product that is becoming a great addition to my arsenal of tools: <a href="http://www.balsamiq.com/products/mockups">Balsamiq Mockups</a>.  Balsamiq is a lightweight tool for building wireframes/mockups that look like sketches.  The focus is on rapid creation of screen mockups that are easy to make and easy to change, encouraging feedback and rapid iteration.  The product is available in a desktop version and also version integrated with Wiki software like Confluence.  For the past few weeks I&#8217;ve been playing around with the desktop version &#8211; their website said that they&#8217;d give a free license of the desktop version if you promised to write a review, so here I am! Here I&#8217;d like to point out some of my likes, some annoyances, some features I&#8217;d like to see, and a weird little bug I came across.</p>
<p>First off, here&#8217;s a sample of what a mockup looks like for a fictional, non-sense product:</p>
<p><a href="http://www.gregphoto.net/wp-content/uploads/2009/04/sample.png"><img src="http://www.gregphoto.net/wp-content/uploads/2009/04/sample-300x233.png" alt="Balsamiq Mockup screenshot" title="Balsamiq Mockup screenshot" width="300" height="233" class="aligncenter size-medium wp-image-61" srcset="http://www.gregphoto.net/wp-content/uploads/2009/04/sample-300x233.png 300w, http://www.gregphoto.net/wp-content/uploads/2009/04/sample.png 663w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In a way, Balsamiq seems to be very much inspired by Microsoft PowerPoint&#8230;but in a good way.  You drag shapes from a list of about 75 widgets onto a page and then rearrange, align, and change properties for the items.  The big difference is in the different types of widgets that are available.  There are some basic shapes, but most of the widgets are things you would see in applications, like text inputs, dropdowns, radio/checkboxes, and then some more complex widgets like tabs, trees, data grids, and iPhone widgets.  The result is that you can build things <u>fast</u> &#8211; the mockup above took about 5 minutes to put together.</p>
<h4>What I like</h4>
<ul>
<li>Easy to use &#8211; the number one feature.  As mentioned, the application uses many known paradigms from existing applications such as PowerPoint and other design apps.  I was able to get going without reading the manual, going through a tutorial, or getting a lesson &#8211; the application explains itself.</li>
<li>Fast &#8211; ok, this is tied for the number one feature.  Because of its ease of use, it is possible to create and iterate on designs very quickly. The &#8216;Quick Add&#8217; feature really speeds things up by letting you type in the name of a widget without having to find it in the mix of 75 widgets &#8211; conveniences like this can make a massive difference in productivity.</li>
<li>Just the right level of realism &#8211; the mockups definitely would never be confused with a real application, but they are clean enough that they can convey to point very well and get people to focus on the key design and workflow issues early on in product design and development</li>
<li>Advanced widgets such as tree and data table &#8211; these advanced widgets are some of the items that make it tough to build mockups for advanced apps in languages like HTML without investing a lot of effort to use libraries like extjs, jquery, or YUI.</li>
<li>Easy to export to PNG &#8211; mockups can easily be exported out to the PNG format for posting on a wiki or emailing.</li>
<li>Editable &#8211; as compared to paper mockups, these have the major advantage of being editable, so you don&#8217;t have to break out the eraser or start over from scratch.</li>
<li>Translates well to traditional webapps, ajax webapps, and desktop applications &#8211; because the application</li>
</ul>
<h4>Annoyances&#8230;or things that aren&#8217;t necessarily bugs, but would make the application easier to use if they were addressed</h4>
<ul>
<li>After &#8216;Quick Add&#8217; clicking f2 doesn&#8217;t go into edit mode &#8211; you have to click the widget first.  If you drag items from the strip they automatically go into edit mode, it would be nice to have that for the quick add as well.</li>
<li>Dragging items from the strip doesn&#8217;t show the guides unless you place the widget then drag again, whereas normally when you are dragging you see guides to help you line up widgets</li>
<li>It would be nice if there were a better way to select a set of items without moving the item beneath it.  If you have 20 widgets on a dialog box and you need to shift them over to make space, in order to select them all you have to first lock the dialog box, select the items by click dragging, drag, release, and unlock the dialog.  If you don&#8217;t do this then the dialog box will just be moved.  This gets more confusing if you have multiple boxes on top of each other.  It would be nice if there were a way to move into selection mode which would allow you to select any elements that are entirely enclosed by a bounding box.</li>
<li>Related to the previous entry, you unlock items through a right-click menu (the only usage of right-click in the app?), but if multiple items are locked in the clicked area it just shows the item type in the context menu.  In some scenarios I had 3 or 4 items showing up, some of which were of the same type.  It would be nice to highlight the item when hovering over it in the context menu to let you know you&#8217;ve got the right one.</li>
<li>It would be nice if the tree could user smaller fonts &#8211; some of the other widgets allow for choosing smaller fonts to fit more text, but the tree uses a very large font, making it tough to represent even remotely realistic data.</li>
</ul>
<h4>Features I&#8217;d like to see</h4>
<ul>
<li>Ability to click through from one mockup to another to create workflow &#8211; while I don&#8217;t need to create an entire flow for an application, if I&#8217;m mocking up a particular feature it would be useful to show 3 or 4 screens that are linked together maybe with a generated HTML files or something of the sort.</li>
<li>Ability to regroup after ungrouping items &#8211; you can group items, but you need to ungroup to make any edits (unlike PowerPoint which allows you to change text or even move sub-items), but then you don&#8217;t have an option to regroup&#8230;meaning you have to go through the same fun of locking outer elements, and reselecting.</li>
<li>Radio and Check Box controls should allow adding multiple at once similar to Dropdown &#8211; since these fields usually come with multiple entries it would be nice to have the widgets allow for adding multiple &#8216;rows&#8217; of data similar to dropdowns</li>
<li>It would be nice to have right-click context menus for some operations like grouping or ungrouping</li>
<li>Layers &#8211; it might be nice to have layers (like Photoshop) to help avoid some of the issues with moving items&#8230;this would add a lot of utility but it would come with the negative impact on ease of use and ramp up time.</li>
<li>Ability to add custom widgets &#8211; it would be nice to be able to add custom widgets&#8230;now if you create a widget by composing the built in widgets you have to save it as another mockup and then select-all and copy/paste into the destination mockup &#8211; it would be nice to be able to save the widget to the strip and give it a name.</li>
<li>Favorites bar in addition to the current &#8216;All&#8217;, &#8216;Big&#8217;, &#8216;Buttons&#8217; &#8211; for many projects only a small number of the widgets are necessary.  In my applications I have no need for things like the iPhone widgets so they just get in the way.</li>
<li>Maybe a way to switch from click mode to select mode for selecting multiple items</li>
</ul>
<h4>Bug</h4>
<ul>
<li>This was a weird one.  If you type &#8216;scro&#8217; into the Quick Add box and click the entry for the &#8216;vertical scrollbar&#8217;, the horizontal scrollbar is actually added.  Surprisingly, if you type in &#8216;scrol&#8217; or &#8216;scr&#8217; it works just fine!</li>
</ul>
<h4>Conclusion</h4>
<p>Overall I really like this application &#8211; I&#8217;ve found myself evangelizing to colleagues and used it for some real feature design and have gotten good feedback from all who have seen the results.  Like all software, there are many things that could be improved and there likely always will be, but it seems that the application is in active development and the focus on usability and user productivity look like they&#8217;ll keep the product on the right trajectory.  At $79 I think it is a bargain and justifies its cost in hours or days of use.  It doesn&#8217;t necessarily replace all of the other tools in my mockup toolbox &#8211; to get to the finer level of detail I still need to break out the HTML occasionally  &#8211; but this is now usually something that happens only after I&#8217;ve validated the basic design with Balsamiq.</p>
<p>Rating: 8/10</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2009/04/22/review-balsamiq-mockups/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Playing mp3s with SoundManager 2</title>
		<link>http://www.gregphoto.net/index.php/2008/11/23/playing-mp3s-with-soundmanager-2/</link>
		<comments>http://www.gregphoto.net/index.php/2008/11/23/playing-mp3s-with-soundmanager-2/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 01:10:32 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=56</guid>
		<description><![CDATA[My friend Michael Ross is a musician and he sent me an email with a couple of the songs he recorded recently. I asked him if he would like me to put together a simple web page for his songs so that he didn&#8217;t have to send out emails with large attachments, and a week [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>My friend Michael Ross is a musician and he sent me an email with a couple of the songs he recorded recently.  I asked him if he would like me to put together a simple web page for his songs so that he didn&#8217;t have to send out emails with large attachments, and a week or so later we had a new site up and running for him &#8211; <a href="http://www.michaelrossmusic.net">www.michaelrossmusic.net</a>.  He wanted a page that listed the albums, had links to download mp3 songs, and a way for people to listen to the songs without downloading them.  I had used <a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a> <a href="http://www.gregandyenari.com/happyholidays">previously</a> to have mp3s play on a page, so I knew that it would be a good fit.</p>
<p>I wanted to be able to build a simple page with regular links to the mp3 files and for JavaScript to do the magic of making the songs playable in the browser &#8211; this post explains how I made it happen.  SoundManager 2 is a JavaScript library built on top of Flash &#8211; the music plays through Flash (which has much better audio support than browsers), but everything is controlled via JavaScript.  I also used <a href="http://www.prototypejs.org">Prototype</a> as a framework to build out the functionality.</p>
<p>Here&#8217;s what I did:</p>
<ol>
<li>Created a <a href="http://www.michaelrossmusic.net">simple page</a> with links to mp3 files</li>
<li>Added a SoundManager handler so that as soon as it loads it instantiates PagePlayer, a JavaScript class I created</li>
<li>PagePlayer takes a CSS selector as input (and optionally an options object) and identifies all of the links that match the selector &#8211; &#8216;a.mp3Link&#8217; in this case (all links with the class &#8216;mp3Link&#8217;).</li>
<li>For each of the identified links, PagePlayer creates a SoundManager sound object using the link to the mp3, adds a play button just prior to the song link, creates event handlers for the play button and sound object, and stores the song in a hash</li>
<li>The event handlers take care of all of the logic: playing songs, making sure that only a single song is playing, changing the state of the button from play to stop</li>
</ol>
<p>Here&#8217;s a current snapshot of the script:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">PagePlayer <span style="color: #339933;">=</span> Class.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	songCount<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
	songs<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">new</span> Hash<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	nowPlaying<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span>
	options<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span>
&nbsp;
	initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>selector<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
			imgPath<span style="color: #339933;">:</span> <span style="color: #3366CC;">'images/'</span><span style="color: #339933;">,</span>
			imgPlay<span style="color: #339933;">:</span> <span style="color: #3366CC;">'control_play.png'</span><span style="color: #339933;">,</span>
			imgStop<span style="color: #339933;">:</span> <span style="color: #3366CC;">'control_stop.png'</span><span style="color: #339933;">,</span>
			mp3LinkTitle<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Download song'</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
		<span style="">Object</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span><span style="color: #339933;">,</span> options <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		$$<span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addSong</span><span style="color: #339933;">,</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	addSong<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>mp3Link<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		mp3Link.<span style="color: #660066;">title</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">mp3LinkTitle</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">var</span> songId <span style="color: #339933;">=</span> mp3Link.<span style="color: #660066;">identify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">var</span> soundObj <span style="color: #339933;">=</span> soundManager.<span style="color: #660066;">createSound</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
			id<span style="color: #339933;">:</span> songId<span style="color: #339933;">,</span>
			url<span style="color: #339933;">:</span> mp3Link.<span style="color: #660066;">href</span><span style="color: #339933;">,</span>
			onfinish<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">finishHandler</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span>songId<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">var</span> controlBtn <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Element<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img'</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>
			src<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPath</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPlay</span><span style="color: #339933;">,</span>
			className<span style="color: #339933;">:</span> <span style="color: #3366CC;">'audioControl'</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		mp3Link.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>before<span style="color: #339933;">:</span> controlBtn<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		controlBtn.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">toggleHandler</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span>songId<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">songs</span>.<span style="color: #000066; font-weight: bold;">set</span><span style="color: #009900;">&#40;</span>songId<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
			controlBtn<span style="color: #339933;">:</span> controlBtn<span style="color: #339933;">,</span>
			soundObj<span style="color: #339933;">:</span> soundObj
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">songCount</span><span style="color: #339933;">++;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	toggleHandler<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>songId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">var</span> oldSong <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">nowPlaying</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">var</span> newSong <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">songs</span>.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span>songId<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>oldSong<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			oldSong.<span style="color: #660066;">soundObj</span>.<span style="color: #660066;">stop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			oldSong.<span style="color: #660066;">controlBtn</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPath</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPlay</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>oldSong <span style="color: #339933;">===</span> newSong<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">nowPlaying</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		newSong.<span style="color: #660066;">controlBtn</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPath</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgStop</span><span style="color: #339933;">;</span>
		newSong.<span style="color: #660066;">soundObj</span>.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">nowPlaying</span> <span style="color: #339933;">=</span> newSong<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	finishHandler<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">nowPlaying</span>.<span style="color: #660066;">controlBtn</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPath</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">imgPlay</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">nowPlaying</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And on the page it is started up as follows:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;script src=&quot;js/soundmanager2-nodebug-jsmin.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/pagePlayer.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
	soundManager.url = '';
	soundManager.onload = function() {
		new PagePlayer('a.mp3Link');
	};
&lt;/script&gt;</pre></td></tr></table></div>

<p>It&#8217;s not the prettiest code, but it gets the job done in 1.58 KB of code and works at least in recent versions of Firefox, IE, Safari, and Chrome.  So, if you need to add some mp3s to a page, check out <a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a> &#8211; it&#8217;s easy to use, well documented, and super flexible&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2008/11/23/playing-mp3s-with-soundmanager-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A walk on the beach</title>
		<link>http://www.gregphoto.net/index.php/2008/10/19/a-walk-on-the-beach/</link>
		<pubDate>Sun, 19 Oct 2008 23:36:40 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/?p=49</guid>
		<description><![CDATA[Its been a long time since I&#8217;ve written anything here&#8230;mostly due to a very busy year which included Yenari and me getting married in June. I&#8217;ll try my best to be more active (i.e. more than one post a year), but for now, I&#8217;ll just provide a link to a little experiment I put together [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Its been a long time since I&#8217;ve written anything here&#8230;mostly due to a very busy year which included Yenari and me getting married in June.  I&#8217;ll try my best to be more active (i.e. more than one post a year), but for now, I&#8217;ll just provide a link to a little experiment I put together from some pictures from our honeymoon in the Cook Islands.  It&#8217;s a little slideshow-like page, built with JavaScript:</p>
<p><a href="http://www.gregphoto.net/projects/beach">Walking into the Ocean</a></p>
<p>Nothing too crazy on the JavaScript side &#8211; just playing around with some stuff I hadn&#8217;t done before.  I wrote about three quarters of this a few months ago and just finished it off this afternoon.  I had to write a simple, but hopefully effective, image preloader that has nice callbacks and a decent api.  The actual slideshow could be written better, but it works, and that&#8217;s all I was going for&#8230;</p>
]]></content:encoded>
			</item>
		<item>
		<title>Yelp for the iPhone</title>
		<link>http://www.gregphoto.net/index.php/2007/12/03/yelp-for-the-iphone/</link>
		<comments>http://www.gregphoto.net/index.php/2007/12/03/yelp-for-the-iphone/#comments</comments>
		<pubDate>Tue, 04 Dec 2007 05:51:12 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/index.php/2007/12/03/yelp-for-the-iphone/</guid>
		<description><![CDATA[I just put together my first simple website for my new toy &#8211; my iPhone. It is a simple iPhone-specific interface for Yelp, my favorite source for restaurant and other local reviews. They have a ton of reviews for just about every local restaurant so I find myself using it all the time to find [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I just put together <a href="http://www.gregphoto.net/projects/yelp">my first simple website</a> for my new toy &#8211; my iPhone.  It is a simple iPhone-specific interface for <a href="http://www.yelp.com">Yelp</a>, my favorite source for restaurant and other local reviews. They have a ton of reviews for just about every local restaurant so I find myself using it all the time to find new restaurants to go to or to find more info about restaurants I already know.  I could access the website just fine already on my phone, but it was a bit crowded and difficult to navigate on a small screen, so I decided it take this as a challenge to build my first iPhone web interface.</p>
<p>And yes, I&#8217;m probably about the 58th person to build a Yelp interface for the iPhone, but I was looking for something I&#8217;d actually use and learn from!</p>
<p>Yelp provides a REST search API that allows you to pass in a location and a search term and they return a JSON object with a list of matching businesses, their ratings, and the business info.  I used the Zend Framework and the Prototype JavaScript library to put it together.  I could have done a pure JavaScript implementation using script hacks, but figured it&#8217;d be better to have the PHP code serve as a basic proxy for the Yelp web service.</p>
<p><a href="http://www.gregphoto.net/projects/yelp">Try it out!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2007/12/03/yelp-for-the-iphone/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP5 Defensio Class</title>
		<link>http://www.gregphoto.net/index.php/2007/11/24/php5-defensio-class/</link>
		<comments>http://www.gregphoto.net/index.php/2007/11/24/php5-defensio-class/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 23:46:32 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/index.php/2007/11/24/php5-defensio-class/</guid>
		<description><![CDATA[Looooong time since I&#8217;ve written anything here &#8211; about 9 months! This time around I&#8217;ve put together a simple PHP5 class for communicating with the Defensio web service. Defensio has an example PHP class, but unfortunately it is PHP4 only and it&#8217;s more fun to rewrite it, right? For those who don&#8217;t know about Defensio, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Looooong time since I&#8217;ve written anything here &#8211; about 9 months!  This time around I&#8217;ve put together a simple PHP5 class for communicating with the <a href="http://www.defensio.com">Defensio</a> web service.  Defensio has an example PHP class, but unfortunately it is PHP4 only and it&#8217;s more fun to rewrite it, right?</p>
<p>For those who don&#8217;t know about Defensio, it is a web service for determining whether a comment on a blog or message in an application is spam.  To use it, you must first <a href="http://defensio.com/signup">register</a> for an API key.  Defensio is very similar to the venerable Akismet (see <a href="http://www.gregphoto.net/index.php/2006/06/11/akismet-and-the-zend-framework/">the article I wrote on Akismet</a>) but they provide a couple other features such an indication of the &#8216;spaminess&#8217; of an individual message.  Akismet has worked out great for me (123,419 spam comments caught so far!), but I figured it would be good to try out something new as well.</p>
<p>The class is a PHP5 class and the public methods are reasonably well commented.  The bottom of this post has a link to a test application and a download of the class/test application.  So&#8230;the usage of this class is quite straightforward, as shown below:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'library/Gregphoto/Defensio.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'library/Gregphoto/Defensio/Adapter/Streams.php);
&nbsp;
$apiKey = '</span>mysecretapikey<span style="color: #0000ff;">';
$siteUrl = '</span>http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//my.secret.site.url.com';</span>
&nbsp;
<span style="color: #000088;">$defensio</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Gregphoto_Defensio<span style="color: #009900;">&#40;</span><span style="color: #000088;">$apiKey</span><span style="color: #339933;">,</span><span style="color: #000088;">$siteUrl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$defensio</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpClient</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Gregphoto_Defensio_Adapter_Streams<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'user-ip'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'article-date'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'2007/11/24'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment-author'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Big Bad Spammer'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment-type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment-content'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'please click links and buy viagra'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment-author-email'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'bigbadspammer@annoying.com'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment-author-url'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'http://www.annoying.com'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$defensio</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">audit_comment</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</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;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'spam'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'true'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Comment is spam with a spam score of &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'spaminess'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Comment is not spam&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>A couple key points on usage:</p>
<ul>
<li>Each Gregphoto_Defensio object requires an Http adapter that it will use to make Http POST requests to the Defensio web service.  I originally hardcoded it to use the Zend_Http_Client from the Zend Framework, but figured this could discourage people from using it.  Then I wrote up a quick adapter to use PHP&#8217;s Http Stream Wrappers, but realized that didn&#8217;t work on my Dreamhost account, so I added in an extra one for the Curl extension.  In theory I should have added a Gregphoto_Defensio_Adapter_Interface class, but I was lazy and didn&#8217;t want to add in an extra file.</li>
<li>Each Gregphoto_Defensio object can be used to make many requests</li>
<li>All of the current <a href="http://www.defensio.com/api">Defensio API&#8217;s</a> are covered by the class.  These are covered by the following methods in the Gregphoto_Defensio class:
<ul>
<li>validate_key</li>
<li>announce_article</li>
<li>audit_comment</li>
<li>report_false_negatives</li>
<li>report_false_positives</li>
<li>get_stats</li>
</ul>
</li>
<li>Each of these methods takes a single parameter, an associative array of options as defined by the Defensio API.  Each API also returns an associative array of response parameters.  Two static utility methods Gregphoto_Defensio::getActions (returns a list of defensio methods such as &#8216;validate-key&#8217;) and Gregphoto_Defensio::getActionDetails (returns a list of required parameters, optional parameters, and response parameters for a specific Defensio action) are provided in order to get the details of the input and output parameters.
</ul>
<p>I created a simple <a href="http://www.gregphoto.net/projects/defensio/test">test application</a> which can be used to test Gregphoto_Defensio and all of the APIs provided by Defensio.</p>
<p><a href="http://www.gregphoto.net/projects/defensio/Gregphoto_Defensio.zip">Download the Gregphoto_Defensio class and the test application</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2007/11/24/php5-defensio-class/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Photos from South Korea, India, and Singapore</title>
		<link>http://www.gregphoto.net/index.php/2007/06/10/photos-from-south-korea-india-and-singapore/</link>
		<comments>http://www.gregphoto.net/index.php/2007/06/10/photos-from-south-korea-india-and-singapore/#comments</comments>
		<pubDate>Mon, 11 Jun 2007 00:57:30 +0000</pubDate>
		<dc:creator><![CDATA[Greg]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.gregphoto.net/index.php/2007/06/10/photos-from-south-korea-india-and-singapore/</guid>
		<description><![CDATA[I just got back from 20 days of traveling to South Korea, India, and Singapore. I went to South Korea with Yenari to see her family and friends for about a week. After this I headed to Bangalore (India) for work while Yenari stayed in South Korea a bit longer. On the way back home [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I just got back from 20 days of traveling to South Korea, India, and Singapore.  I went to South Korea with Yenari to see her family and friends for about a week.  After this I headed to Bangalore (India) for <a href="http://www.stratify.com">work</a> while Yenari stayed in South Korea a bit longer.  On the way back home I had a long layover (9 hours) in Singapore and got a chance to check out the city.</p>
<p>Check out my pictures here: <a href="http://picasaweb.google.com/gneustaetter/SouthKoreaIndiaAndSingapore">http://picasaweb.google.com/gneustaetter/SouthKoreaIndiaAndSingapore</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregphoto.net/index.php/2007/06/10/photos-from-south-korea-india-and-singapore/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
