<?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>Labs &#187; PHP</title>
	<atom:link href="http://labs.iamkoa.net/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.iamkoa.net</link>
	<description>I break it. I fix it. You learn.</description>
	<lastBuildDate>Fri, 09 Jul 2010 02:26:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>First Thing&#8217;s First: Validate</title>
		<link>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/</link>
		<comments>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 22:44:43 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/?p=338</guid>
		<description><![CDATA[Have a sweet function written that requires valid variables? Make sure you&#8217;re validating those variables at the top of your function. Validating variables before (as apposed to while) they are used is key in making sure that important logic isn&#8217;t executed using crappy data. Here&#8217;s an example of validating first, then executing: /* The good... [...]]]></description>
			<content:encoded><![CDATA[<p>Have a sweet function written that requires valid variables? Make sure you&#8217;re validating those variables at the top of your function. Validating variables <em>before</em> (as apposed to <em>while</em>) they are used is key in making sure that important logic isn&#8217;t executed using crappy data.</p>
<p>Here&#8217;s an example of validating first, then executing:</p>
<pre class="brush:php">
	/* The good... */
	public function insertNewInvoiceItem($item, $quantity)
	{
		if(!$item instanceof Shop_Item) {
			throw new InvalidArgumentException ('Expecting an item to be an instance of Shop_Item.');
		}

		if(!is_numeric($quantity)) {
			throw new InvalidArgumentException('Quantity is not numeric.');
		}

		// We're good to go. Continue with the function...
	}
</pre>
<p>The method above is also much cleaner than <code>if... else... </code> statements and limits the extra (perhaps useless) work required by your code:</p>
<pre class="brush:php">
	/* The bad... */
	public function insertNewInvoiceItem($item, $quantity)
	{
		if($item instanceof Shop_Item) {
			// Do some $item stuff...

			if(is_numeric($quantity)) {
				// Do some $quantity calculations
			} else {
				// Uh oh, $quantity was bad but we've
				// run some Shop_Item logic already.
			}
		}
		else
		{
			// $item is not part of Shop_Item
		}
	}
</pre>
<p>I used a simple example to demonstrate my point but when this technique is used on more complex logic, it&#8217;s benefits are much more obvious.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Three Bitchin&#8217; PHP Classes &#8211; Cache, Last.fm API, Time</title>
		<link>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/</link>
		<comments>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 07:11:23 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[parse]]></category>
		<category><![CDATA[time]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/?p=77</guid>
		<description><![CDATA[There&#8217;s nothing like the feeling that comes with typing a few lines in a PHP application and letting some included classes take care of the dirty work; you know, the filthy stuff like caching, calling the Last.fm API, purifying timestamps, and handling file uploads. (Dirty, right?) All of the following PHP classes are &#8220;works in [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s nothing like the feeling that comes with typing a few lines in a PHP application and letting some included classes take care of the dirty work; you know, the filthy stuff like <strong>caching</strong>, <strong>calling the Last.fm API</strong>, <strong>purifying timestamps</strong>, and <strong>handling file uploads</strong>. (Dirty, right?)</p>
<p>All of the following PHP classes are &#8220;works in progress&#8221;, but hopefully each is mature enough to find its way into your code. Continue reading to view, download, and use each class.</p>
<p><span id="more-77"></span></p>
<hr />
<h2>Cache &#8211; Output &#038; Object Caching</h2>
<p>Though this class is old (three years), it does the trick, and quickly. <a href="http://www.phpclasses.org/browse/package/3807.html" target="_blank">Dragon Bosnjak</a> wrote this gem, allowing for easy caching of webpage content into a directory (and filename) of your choosing.</p>
<h3>Using Cache Class</h3>
<p>Caching your web content is a breeze! Create a new Cache class by specifying a directory to store the cache file, and surround your webpage content in a <code>while</code> loop, like so:</p>
<pre class="brush:php">
$cache = new Cache("../cache/");

while ($cache->save("filename.cache", 30)) {
	// "30" is the number of seconds the content should remain cached.
	// Your cached content goes here...
 }
</pre>
<h3>Download Cache</h3>
<p>You can download and use this golden-nugget of love by visiting <a href="http://www.phpclasses.org/browse/package/3807.html" target="_blank">PHP Classes</a> &#8211; perhaps the most poorly styled/organized website on the internet, but that&#8217;s another post entirely.</p>
<hr />
<h2>Last.fm API</h2>
<p>If you have yet to discover the hotness of using <a href="http://us2.php.net/oop5.magic" target="_blank">&#8220;Magic Methods&#8221; in PHP</a>, I suggest you read up on how to serve up a magic teapot of greatness using PHP5. These Magic Methods are exactly what I used to create this simple Last.fm API class. The result is the ability to quickly make <em>almost</em> any API call without having to continuously fiddle with API key variables, etc.</p>
<h3>Using Last.fm API Class</h3>
<p>After including the LastFm class file, you need to create a new instance of the <code>LastFm()</code> class.</p>
<pre class="brush:php">
// include class file
include_once('../inc/class.lastfm.php');

// initate LastFm class
$lastfm = new LastFm();
$lastfm->key = "1234567890"; // your LastFm API key
</pre>
<p>Then you can call your LastFm API action using the following conversion:</p>
<p>Let&#8217;s say we want to call <a href="http://www.last.fm/api/show?service=299" target="_blank">User.getTopAlbums</a> with the <strong>user</strong> argument set to <code>bob</code> and the <strong>period</strong> argument set to <code>3month</code>:</p>
<pre class="brush:php">
$lastfm->user_getTopAlbums("user=iamkoa","period=3month");
</pre>
<p>The above PHP code will generate the following API call:</p>
<pre class="brush:html">

http://ws.audioscrobbler.com/2.0/?method=user.getTopAlbums&#038;user=bob&#038;period=3month&#038;api_key=1234567890
</pre>
<h3>Let The Class Parse Things For You&#8230;</h3>
<p>The API call will return, for example, the following XML to Array:</p>
<pre class="brush:php">
Array
(
    [lfm] => Array
        (
            [attr] => Array
                (
                    [status] => ok
                )

            [recenttracks] => Array
                (
                    [attr] => Array
                        (
                            [user] => iamkoa
                            [page] => 1
                            [perPage] => 8
                            [totalPages] => 2777
                        )

                    [track] => Array
                        (
                            [0] => Array
                                (
                                    [artist] => Array
                                        (
                                            [value] => Black Eyed Peas
                                            [attr] => Array
                                                (
                                                    [mbid] => d5be5333-4171-427e-8e12-732087c6b78e
                                                )

                                        )
// etc...
</pre>
<p>To make any Last.fm API call, simply replace the <code>.</code> symbol with an <code>_</code> symbol and include any arguments with a <code>"var=bar"</code> pattern. For example, here&#8217;s how to make a couple calls:</p>
<pre class="brush:php">
// call user.getWeeklyTrackChart
$lastfm->user_getWeeklyTrackChart("user=iamkoa");

// call group.getMembers
$lastfm->group_getMembers("group=groupName");

// etc...
</pre>
<h3>Download Last.fm</h3>
<p><a href="http://labs.iamkoa.net/wp-content/uploads/2010/04/php-class-lastfm-04222010.zip">Download and use the Last.fm PHP class</a>. Please post any enhancements to the class here for others to use.</p>
<hr />
<h2>Time</h2>
<p>Time is a bitch. It&#8217;s always against us. In the case of parsing a date string into a human-friendly string, it&#8217;s even more apparent that time sucks. Hopefully this Time class, though not entirely finished, will help with parsing dates.</p>
<h3>Use it</h3>
<p>It&#8217;s really, really simple to use:</p>
<pre class="brush:php">
$time = new Time();
echo $time->timeAgoInWords($date_string);
</pre>
<p>Depending upon when <code>$date_string</code> is relative to the current time, the above code might print one of the following:</p>
<p><code>"26 July, 2:45 PM", "Yesterday morning", "Today", "Last night", or "28 minutes ago", etc...</code></p>
<p>Editing the class is pretty simple, so I&#8217;ll let all you hackers dig into it for details.</p>
<h3>Download Time</h3>
<p><a href="http://labs.iamkoa.net/wp-content/uploads/2010/04/php-class-time-04222010.zip">Download and use the Time PHP class</a>. Please post any enhancements to the class here for others to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CakePHP 1.1 File Upload Plays Rough With PHP 4</title>
		<link>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/</link>
		<comments>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 00:23:07 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/</guid>
		<description><![CDATA[Uploading files via CakePHP has been covered a few times on Labs. Based on the feedback, it&#8217;s safe to assume bridging the gap between file uploads and PHP can be tricky. Usually Cake is ready to lend a helpful hand. Not this time. //If you're finding that executing this: //... returns something like this: $this->data:Array [...]]]></description>
			<content:encoded><![CDATA[<p>Uploading files via CakePHP has been covered a <a href="http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/">few</a> <a href="http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/">times</a> on Labs. Based on the feedback, it&#8217;s safe to assume bridging the gap between file uploads and PHP can be tricky. Usually Cake is ready to lend a helpful hand. Not this time.</p>
<p><span id="more-52"></span></p>
<pre class="brush:php">
//If you're finding that executing this:
<?php echo $html->formTag('/' . $params['url']['url'], 'post', array('enctype' => 'multipart/form-data')); ?>
	<?php echo $html->input('Test/title'); ?>
	<?php echo $html->file('Test/file'); ?>
	<?php echo $html->submit('Save'); ?>
</form>

//... returns something like this:
$this->data:Array
(
    [Test] => Array
        (
            [title] => Foo
            [file] => 4tmp/phpHGSjDA
        )
)

//... instead of something like this:
$this->data:Array
(
    [Test] => Array
        (
            [title] => Foo
            [file] => Array
                (
                    [name] => aeo.jpg
                    [type] => image/jpeg
                    [tmp_name] => /tmp/phppM8tfc
                    [error] => 0
                    [size] => 45471
                )
        )
)

//... then you must be as annoyed as I am.
</pre>
<p>The reason why the <code>file</code> form field is returning the tmp name is because CakePHP expects <code>register_globals</code> is OFF.</p>
<h2>Solution One</h2>
<p>Turn off register_globals via .htaccess:</p>
<pre class="brush:php">
#/app/webroot/.htaccess
php_flag register_globals off
</pre>
<h2>Solution Two</h2>
<p>Manually write your HTML form fields without using an input array:</p>
<pre class="brush:php">
// do this
<input type="file" name="file" />
// not this
<?php echo $html->file('Test/file'); ?> // will output:
<input type="file" name="data[Test][test]" />
</pre>
<p>Solution two is a slight pain in the ass, because now that you&#8217;ve eliminated the array within the form input field, you need to do a little extra work in your CakePHP controller. (If there&#8217;s a demand, I&#8217;ll give some examples.)</p>
<p>Hopefully this&#8217;ll clear up Cake&#8217;s messhole.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Simple/Secure Email Class For PHPMailer</title>
		<link>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/</link>
		<comments>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/#comments</comments>
		<pubDate>Tue, 27 Nov 2007 23:57:38 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/</guid>
		<description><![CDATA[If you&#8217;re not careful, sending email via PHP is about as safe as cookies at Fat Camp. BKWLD was recently tagged by a spammer who noticed one such insecurity on one of our websites and ended up using our server to send hundreds of emails. It wasn&#8217;t until MediaTemple informed us of this breach that [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re not careful, sending email via PHP is about as safe as cookies at Fat Camp. <a href="http://bkwld.com">BKWLD</a> was recently tagged by a spammer who noticed one such insecurity on one of our websites and ended up using our server to send hundreds of emails. It wasn&#8217;t until <a href="http://mediatemple.net">MediaTemple</a> informed us of this breach that we realized what had happened.</p>
<p>The method most spammers use is called a &#8220;mail injection&#8221;, in that the spammer manipulats the PHP <code>mail()</code> function via a custom form post, etc. I won&#8217;t go into details, as a quick search on Google came up with over 225,000 pages describing this technique &#8211; <a href="http://www.bl0g.co.uk/060214/PHP_mail_Email_Injection_Attack_Allows_Spammers_to_Send_Email/">here</a> <a href="http://www.tonyspencer.com/2005/12/15/email-injection-exploit-through-a-php-contact-form/">are</a> <a href="http://www.securephpwiki.com/index.php/Email_Injection">a</a> <a href="http://www.maravelias.gr/archives/security/28">few</a>.</p>
<p>Getting around these hacks requires detailed validation of your data.Thankfully I&#8217;ve done everything for you using the best PHP email class around, <a href="http://phpmailer.codeworxtech.com/">PHPMailer</a>. My class is called <code>SendMail</code> and it&#8217;s an extension of the PHPMailer class. The result is a powerful script capable of sending email via SMTP or POP3, all without handing over your server to a toothless spammer.</p>
<p><span id="more-48"></span></p>
<blockquote><p>
The SendMail class has been updated. Please view <a href="#updates">the updates</a> before commenting.
</p></blockquote>
<h2>Download The SendMail Class</h2>
<p>Click the link to download the SendMail class and continue reading to learn how to use it.<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/sendmail-class-11262007.zip' title='SendMail Class'>Download the SendMail class</a></p>
<h2>Setup</h2>
<p>Setting up the SendMail class is easy-peezie. Simply include the required SendMail variables and call the <code>send()</code> function to send emails:</p>
<pre class="brush:php">
<?php
require("inc/class.sendmail.php");

if($_POST){
    $mail = new SendMail;

    <span class="highlight">$mail->authHosts = array("domain.com");</span>

    $mail->addEmail("name@person.com","Name",);
    $mail->addEmail("name2@person.com","Name2");

    $mail->subject($_POST['subject']);
    $mail->body($_POST['body']);

    $mail->fromName($_POST['from_name']);
    $mail->fromEmail($_POST['from_email']);

    $result = $mail->send();

    if (!$result){
        if(!empty($mail->errors)) {
            $mail->displayErrors($mail->errors,'ol');
        }
    exit();
    }
}

echo "Message was sent successfully";
?>
<form method="post" action="<?=$_SERVER['PHP_SELF']?>">
<input type="text" name="from_email" value="people@info.com" />
<input type="text" name="from_name" value="People" />
<input type="text" name="subject" value="This is a subject" />
<input type="text" name="body" value="Email body goes here." />
<input type="submit" value="Submit" />
</form>
</pre>
<p>For further security, you may implement the <code>authHosts</code> variable as highlighted above. The <code>authHosts</code> array specifies what domains are allowed to send <code>$_POST</code> data. Any domains not listed that attempted to contact the script via <code>$_POST</code> will get a 403 (permission denied) error.</p>
<h2>Further Configuration</h2>
<p>If you need to specify an SMTP host, username, and password, include each variable before calling the <code>send()</code> function. You may also specify the charset and select whether or not HTML should be used in the email by using the respective code below:</p>
<pre class="brush:php">
// ...
$mail = new SendMail;

if($_POST) {

    $mail = new SendMail;

    $mail->authHosts = array("domain.com");

    <span class="highlight">$mail->host = 'mail.domain.com';
    $mail->username = 'root';
    $mail->password = 'pass123';

    $mail->charset = 'utf-8';
    $mail->bodyHtml = "HTML goes in here";</span>

    $mail->addEmail("name@person.com","Name");
    $mail->addEmail("name2@person.com","Name2");

    $mail->subject($_POST['subject']);
    $mail->body($_POST['body']);

    $mail->fromName($_POST['from_name']);
    $mail->fromEmail($_POST['from_email']);

    $mail->Mailer = 'mail';

    $result = $mail->send();

    if (!$result){
        if(!empty($mail->errors)) {
            $mail->displayErrors($mail->errors,'ol');
        }
    exit();
    }
}
// ...
</pre>
<p>When displaying errors via the <code>displayErrors()</code> function, you may choose to use <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code> HTML. If you&#8217;d rather receive errors as an array, use <code>$mail-&gt;errors</code> only.</p>
<h2>Fini, Cowboy</h2>
<p>If you need further explanation or would like a better understanding of the code, dig into the <code>inc/class.sendmail.php</code> file. The code is well-commented and should guide you nicely. If it doesn&#8217;t, comment and I&#8217;ll help you myself. For further information on PHPMailer, <a href="http://phpmailer.codeworxtech.com/">go to the official website</a>.</p>
<h2>Updates</h2>
<p><a name="updates"></a><strong>Nov 27, 2007</strong>: The entire SendMail class has been rewritten to better perform as OOP should. The domain security is now optional. All files have been updated for downloading.</p>
<p><strong>Dec 21, 2007</strong>: Select between sending with PHP <code>mail()</code>, SMTP, or POP using <code>Mailer</code> as shown above. All files have been updated for downloading. Eat it up.</p>
<p><strong>Jan 15, 2008</strong>: When sending HTML mail, alternative text sends accordingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Vision, Simple PHP/JS/CSS Photo Viewer</title>
		<link>http://labs.iamkoa.net/2007/11/19/vision-simple-phpjscss-photo-viewer/</link>
		<comments>http://labs.iamkoa.net/2007/11/19/vision-simple-phpjscss-photo-viewer/#comments</comments>
		<pubDate>Tue, 20 Nov 2007 01:24:42 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Labs]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/19/vision-simple-phpjscss-photo-viewer/</guid>
		<description><![CDATA[The simplest image viewer known to man has been created. Visi&#243;n uses a light touch of PHP, Javascript and CSS to create a straightforward, stylish image viewer. It can be incorporated into any website in under three minutes and takes up less than 20kb of space. Stop reading this and download Visi&#243;n. This article covers [...]]]></description>
			<content:encoded><![CDATA[<p>The simplest image viewer known to man has been created. Visi&oacute;n uses a light touch of PHP, Javascript and CSS to create a straightforward, stylish image viewer. It can be incorporated into any website in under three minutes and takes up less than 20kb of space. Stop reading this and <a href="http://iamkoa.net/vision/" target="_blank">download Visi&oacute;n</a>.</p>
<p><span id="more-44"></span></p>
<div style="text-align:center;width:100%"><a href='http://iamkoa.net/vision/' title='Vision, Simple PHP/JS/CSS Photo Viewer' target='_blank'><img src='http://labs.iamkoa.net/wp-content/uploads/2007/11/vision_screenshot.jpg' alt='Vision Screenshot' /></a></div>
<p></p>
<blockquote><p>
This article covers <u>how</u> to use Visi&oacute;n. To learn more about Visi&oacute;n, <a href="http://iamkoa.net/vision/">check this out</a>.
</p></blockquote>
<h2>Setup Vision</h2>
<p>If you haven&#8217;t already done so, <a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/vision-viewer.zip' title='Vision, Simple PHP/JS/CSS Photo Viewer'>download a copy of Visi&oacute;n</a> and unzip it to any location that&#8217;s able to parse PHP files, like localhost.</p>
<p>For a basic install of Visi&oacute;n, the only file you need to edit is <code>index.php</code>:</p>
<pre class="brush:php">
/**  setup  **/
$imgDir	= "img"; 		// image directory
$imgSub	= false;		// include sub directories when gathering images?
$imgId	= "lgImage"; 	// id tag for images
</pre>
<p>To successfully pull images from your images folder, edit <code>$imgDir</code> accordingly. The above example would be looking for images in a folder called &#8220;img&#8221;, located in the same directory as the <code>index.php</code> file you are editing.</p>
<p>If you would also like to include images located in folders <em>within</em> the images folder you&#8217;ve specified, set the <code>$imgSub</code> variable to <strong>true</strong>. If <code>$imgSub</code> remains set to <strong>false</strong>, all sub folders within the specified images folder will be ignored.</p>
<p>Lastly, you may choose to specify the <strong>id</strong> used for your image on display. Under most circumstances, you won&#8217;t have to change this value.</p>
<h2>Integrate Vision</h2>
<p>Once you&#8217;ve got the <code>index.php</code> edited to your liking, integrating Visi&oacute;n into a web application of your choice is a matter of copying and pasting a few lines of code.</p>
<p>Make sure all the PHP code (lines 1-11) is copied, along with the javascript code (lines 25-37), and content within the <code>id="content"</code> div.</p>
<h2>Easy, Huh?</h2>
<p>That wasn&#8217;t too hard, right? If you&#8217;ve hacked/tweaked/etc Visi&oacute;n for your website, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/19/vision-simple-phpjscss-photo-viewer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
