<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
	<title>Chris Morrell</title>
	
	<link>http://cmorrell.com</link>
	<description>The personal home page of Chris Morrell</description>
	<lastBuildDate>Thu, 02 Sep 2010 01:05:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/cmorrell" /><feedburner:info uri="cmorrell" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Zend Debugger Safari Toolbar</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/5L5xwxbpZ0I/zend-debugger-safari-toolbar-820</link>
		<comments>http://cmorrell.com/webdev/zend-debugger-safari-toolbar-820#comments</comments>
		<pubDate>Thu, 01 Jul 2010 21:42:53 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend studio]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=820</guid>
		<description><![CDATA[Update: It turns out Safari is more problematic than Firefox, so I&#8217;ve switched back.  I have no plans to finish this project.  Feel free to fork it on GitHub. When Safari 5 came out I decided to make the switch. &#8230; <a href="http://cmorrell.com/webdev/zend-debugger-safari-toolbar-820">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> It turns out Safari is more problematic than Firefox, so I&#8217;ve switched back.  I have no plans to finish this project.  Feel free to fork it on <a href="http://github.com/inxilpro/Zend-Debugger-Safari-Toolbar" target="_blank">GitHub</a>.</p>
<p>When Safari 5 came out I decided to make the switch.  The new Safari developer tools rival Firebug, Safari now supports extensions, and Firefox has been causing all sorts of problems for me lately (20-second freezes, choppy video, etc).  There were three things that I knew I couldn&#8217;t live without…</p>
<p><span id="more-820"></span>Those were:</p>
<ul>
<li>AdBlock</li>
<li>Delicious.com Integration</li>
<li>The Zend Studio Toolbar</li>
</ul>
<p>The first two were ported to Safari within days (if not hours) of the Safari 5 release.  The third is likely to take a while, so I decided to put together my own version for the time-being.  Right now it&#8217;s very much in an &#8220;alpha&#8221; stage.  It only supports the &#8220;debug current page&#8221; command, and it hasn&#8217;t been tested all that thoroughly.  That said, I plan on developing this over the next few weeks to mirror most of the features available in the current Zend Studio Toolbar for Firefox and MSIE.</p>
<p>I&#8217;m also adding some features of my own.  Namely, the toolbar remembers what domains you&#8217;ve enabled debugging on, and only shows itself on those domains.  There&#8217;s a browser button that you can use to toggle debugging, and in the future I want to add an indicator when the page you&#8217;re on supports debugging.</p>
<p>If you develop with Zend Studio and Safari, please <a href="http://cmorrell.com/safari-extensions/zend-debugger">check out the current version of the extension</a>.  I could really use some feedback from other folks (particularly those who have other workflows from me).</p>
<div class="su-linkbox" id="post-820-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zend-debugger-safari-toolbar-820&quot;&gt;Zend Debugger Safari Toolbar&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zend-debugger-safari-toolbar-820/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zend-debugger-safari-toolbar-820</feedburner:origLink></item>
		<item>
		<title>Optimize Legibility in Safari 5</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/l9FG0-4J9DY/optimize-legibility-safari-5-810</link>
		<comments>http://cmorrell.com/misc/optimize-legibility-safari-5-810#comments</comments>
		<pubDate>Tue, 29 Jun 2010 16:27:00 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[safari]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=810</guid>
		<description><![CDATA[Just saw this (via Daring Fireball): Cross-browser kerning-pairs &#38; ligatures And thought, &#8220;there&#8217;s gotta be an extension for that.&#8221;  Well, looks like there isn&#8217;t… so I made one: Enjoy! Link to this post!]]></description>
			<content:encoded><![CDATA[<p>Just saw this (via <a href="http://daringfireball.net/linked/2010/06/29/optimizelegibility" target="_blank">Daring Fireball</a>):</p>
<p><a href="http://www.aestheticallyloyal.com/public/optimize-legibility/" target="_blank">Cross-browser kerning-pairs &amp; ligatures</a></p>
<p>And thought, &#8220;there&#8217;s gotta be an extension for that.&#8221;  Well, looks like there isn&#8217;t… so I made one:</p>
<a href="http://cmorrell.com/downloads/8" title="Version 1.0, Downloaded 1285 times">Optimize Legibility [4.64 kB]</a>
<p>Enjoy!</p>
<div class="su-linkbox" id="post-810-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/misc/optimize-legibility-safari-5-810&quot;&gt;Optimize Legibility in Safari 5&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/misc/optimize-legibility-safari-5-810/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<feedburner:origLink>http://cmorrell.com/misc/optimize-legibility-safari-5-810</feedburner:origLink></item>
		<item>
		<title>Safari Toolbar CSS</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/bh0ppvNzJrc/safari-toolbar-css-805</link>
		<comments>http://cmorrell.com/misc/safari-toolbar-css-805#comments</comments>
		<pubDate>Wed, 09 Jun 2010 16:18:53 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Misc]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=805</guid>
		<description><![CDATA[By default, Safari extension toolbars are just plain old HTML. That means that your toolbar is going to look a lot like: Wouldn&#8217;t it be nice if instead it looked like: I&#8217;ve developed a (very) simple CSS file that styles &#8230; <a href="http://cmorrell.com/misc/safari-toolbar-css-805">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>By default, Safari extension toolbars are just plain old HTML.  That means that your toolbar is going to look a lot like:</p>
<p><img class="alignnone size-full wp-image-803" title="safari-css-before" src="http://cmorrell.com/wp-content/uploads/2010/06/safari-css-before.png" alt="" width="328" height="39" /></p>
<p>Wouldn&#8217;t it be nice if instead it looked like:</p>
<p><img class="alignnone size-full wp-image-802" title="safari-css" src="http://cmorrell.com/wp-content/uploads/2010/06/safari-css.png" alt="" width="328" height="39" /></p>
<p>I&#8217;ve developed a (very) simple CSS file that styles links (and &lt;button&gt; elements) to look like native Safari toolbar items.  <a href="http://cmorrell.com/safari-extensions">Download it now</a>.</p>
<div class="su-linkbox" id="post-805-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/misc/safari-toolbar-css-805&quot;&gt;Safari Toolbar CSS&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/misc/safari-toolbar-css-805/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://cmorrell.com/misc/safari-toolbar-css-805</feedburner:origLink></item>
		<item>
		<title>HTML5 Demo &amp; Resources</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/mckb_7nO63c/demo-and-resources-789</link>
		<comments>http://cmorrell.com/html-5/demo-and-resources-789#comments</comments>
		<pubDate>Wed, 28 Apr 2010 20:28:58 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[HTML 5]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=789</guid>
		<description><![CDATA[On April 27th I spoke at PANMA&#8217;s HTML5 Demystified event, demoing some of the new features that HTML 5, CSS 3 and other modern web standards bring to the table.  There was a great turnout—I&#8217;m glad we hit on a &#8230; <a href="http://cmorrell.com/html-5/demo-and-resources-789">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>On April 27th I spoke at <a href="http://www.panma.org/" target="_blank">PANMA&#8217;s</a> <a href="http://www.panma.org/organization/news/2010/04/html-5-demystified-on-427" target="_blank">HTML5 Demystified</a> event, demoing some of the new features that HTML 5, CSS 3 and other modern web standards bring to the table.  There was a great turnout—I&#8217;m glad we hit on a topic that so many people are interested in.  This post is just a quick follow up and a place for people to download the code I put together during the event and to check out some resources on HTML 5.</p>
<p><span id="more-789"></span></p>
<p><strong>[Update] Here&#8217;s a video of both Nick and my talks (sorry, the audio from the wireless mic we were using is pretty quiet):</strong></p>
<p><object id="viddler_whartondev_12" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="405" height="342" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://www.viddler.com/player/f4e2c72/" /><param name="name" value="viddler_whartondev_12" /><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><embed id="viddler_whartondev_12" type="application/x-shockwave-flash" width="405" height="342" src="http://www.viddler.com/player/f4e2c72/" wmode="transparent" name="viddler_whartondev_12" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
<p>And here&#8217;s the finished code, cleaned up a bit: <a href="http://cmorrell.com/downloads/6" title="Version , Downloaded 207 times">HTML5 Demo Files [46.58 kB]</a></p>
<p>It includes the demo page and its supporting files (except the actual video files, which are pretty large).   I took a few moments this morning to clean the file up and add the Mozilla-specific counterparts to the Webkit-specific CSS selectors and functions that I demoed.  I also threw a few extras in there, like transforms, so it&#8217;s worth having another look at the code.</p>
<p>One thing I did want to clarify is the @font-face rule.  We had a little trouble getting it to work during the demo, so I spent a few minutes reading up on browser support.  Here&#8217;s the breakdown:</p>
<ul>
<li><strong>TTF</strong>: Firefox 3.5+, Safari 3.1+, Chrome 2+, Opera 10+</li>
<li> <strong>OTF</strong>: Firefox 3.5+, Safari 3.1+, Opera 10+</li>
<li> <strong>EOT</strong>: Internet Explorer 4+</li>
<li> <strong>SVG</strong>: Safari 3.1+, Chrome 0.3+, Opera 9+</li>
</ul>
<p>It&#8217;s worth noting that before Chrome 4.0 @font-face was disabled by default, so even though SVG and TTF were supported by Chrome early on, they weren&#8217;t really usable until recently.</p>
<p>When you look at that list it becomes apparent that the best way to get the most @font-face support is to use TTF and OTF formats.  OTF is Microsoft&#8217;s &#8220;Embedded OpenType&#8221; format.  If you have a TTF or OTF formatted font, you can use <a href="http://www.kirsle.net/wizards/ttf2eot.cgi">this tool</a> to convert it to EOT.  Once you have your TTF and EOT files, just copy and modify the @font-face declaration in my demo code.</p>
<p>The last thing I wanted to post is a list of resources.  These are just some tutorials/web sites that either use or talk about HTML5:</p>
<ul>
<li><a href="http://bit.ly/dfCTw3" target="_blank">Great presentation on HTML5 written IN HTML5.</a> View in Chrome for best results.</li>
<li>&#8220;<a href="http://bit.ly/bheBOx" target="_blank">How to Make All Browsers Render HTML5 Mark-up Correctly &#8211; Even IE6</a>&#8220;.  It&#8217;s a good overview of how to get browsers to behave, but doesn&#8217;t go into much detail beyond that.</li>
<li><a href="http://bit.ly/cnFDoq" target="_blank">Sample code on how to get &lt;video&gt; to work for everyone</a> (with a fallback for MSIE).</li>
<li><a href="http://bit.ly/9TUF4j" target="_blank">Sublime video</a> (for consistent UI in &lt;video&gt; tags, with Flash fallback)</li>
<li>Basic tutorial on <a href="http://bit.ly/buBmp6" target="_blank">using the SQLite-compatible database in your browser</a>.</li>
<li>An <a href="http://bit.ly/csCqFG" target="_blank">overview of all forms of client-side storage</a>.</li>
<li>&#8220;<a href="http://bit.ly/aZ4cBu" target="_blank">HTML 5: Features you want desperately but still can&#8217;t use</a>&#8220;.  Great talk by Ian Hickson from 2008.  It&#8217;s a little out of date now, but there are lots of great demos in there.</li>
<li>Mark Pilgrim&#8217;s HTML5 Book &#8220;<a href="http://bit.ly/bi29bT" target="_blank">Dive Into HTML5</a>&#8220;.</li>
<li><a href="http://bit.ly/dkbgAZ" target="_blank">Modernizr</a> is a JS tool that helps you detect support for HTML5 features.</li>
<li>Nice chart of <a href="http://bit.ly/aFfJng" target="_blank">HTML5/CSS3 feature support by browser</a>.</li>
<li><a href="http://bit.ly/br04am" target="_blank">IE7.js and IE8.js</a>, which I mentioned in my talk, help make MSIE perform more like a standards-compliant browser.</li>
<li><a href="http://bit.ly/bwoI4N" target="_blank">Nissan Leaf product page</a>, made using &#8220;HTML5&#8243; (technically it&#8217;s still XHTML, but it&#8217;s using a lot of JS/SVG/etc to skip the need for Flash in many places).</li>
</ul>
<p><strong>[Update] Added 4/28:</strong></p>
<ul>
<li><a href="http://bit.ly/bQ6Nkj" target="_blank">CSS3 Solutions for Internet Explorer</a>.  Provides some useful filters and HTC files to make MSIE mimic CSS3 functionality.</li>
<li><a href="http://bit.ly/d37Me3" target="_blank">Aves Engine</a>: An HTML5-based social game engine.</li>
<li><a href="http://alteredqualia.com/canvasmol/" target="_blank">CanvasMol</a>: An HTML5-based web app for molecular modeling.</li>
<li>A good overview of <a href="http://bit.ly/cSOb75" target="_blank">HTML5 video Libraries, Toolkits and Players</a></li>
<li>A nice video covering <a href="http://bit.ly/8XIgc8" target="_blank">HTML5 features you can use right now</a>.</li>
<li>Very cool visualization of <a href="http://bit.ly/bpX20G" target="_blank">HTML5 &amp; CSS3 readiness</a>.</li>
<li>Gallery of 15 <a href="http://bit.ly/bznbuX" target="_blank">HTML5 templates and frameworks</a>.</li>
<li>Overview of <a href="http://bit.ly/bOiLQt" target="_blank">new HTML5 input types</a>, and why you should be using them right now.  <strong>Highly recommended.</strong></li>
<li>Very cool tool for generating <a href="http://bit.ly/bA0KEp" target="_blank">cross-browser border radius</a> code.</li>
<li>Introduction to <a href="http://bit.ly/9tXJCh" target="_blank">CSS3 transitions</a>.</li>
</ul>
<p><strong>[Update] Added 4/29:</strong></p>
<ul>
<li>Table of <a href="http://bit.ly/8Z2Gdn">CSS3 Support in Email Clients</a></li>
</ul>
<p>That&#8217;s everything I can think of right now.  I&#8217;m constantly adding new stuff to my <a href="http://delicious.com/inxilpro" target="_blank">Delicious account</a> and/or posting it to <a href="http://twitter.com/inxilpro" target="_blank">Twitter</a>, so keep an eye on those feeds for updates on this stuff in the future.</p>
<p>If you have any questions, feel free to ask in comments or <a href="http://twitter.com/inxilpro" target="_blank">@inxilpro</a> and I&#8217;ll do my best to answer or point you in the right direction.</p>
<div class="su-linkbox" id="post-789-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/html-5/demo-and-resources-789&quot;&gt;HTML5 Demo &amp; Resources&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/html-5/demo-and-resources-789/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://cmorrell.com/html-5/demo-and-resources-789</feedburner:origLink></item>
		<item>
		<title>Better Zend Framework Documentation</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/ZAQ_20nF07g/zend-framework-documentation-777</link>
		<comments>http://cmorrell.com/webdev/zf/zend-framework-documentation-777#comments</comments>
		<pubDate>Tue, 30 Mar 2010 13:07:09 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=777</guid>
		<description><![CDATA[If you&#8217;ve every tried to navigate the Zend Framework documentation&#8217;s longer pages you&#8217;ve probably looked everywhere for a table of contents.  Sure, there&#8217;s a TOC for the major sections of the component, but if you&#8217;re looking for a specific part &#8230; <a href="http://cmorrell.com/webdev/zf/zend-framework-documentation-777">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve every tried to navigate the <a href="http://framework.zend.com/manual/en/zend.filter.set.html" target="_blank">Zend Framework documentation&#8217;s longer pages</a> you&#8217;ve probably looked everywhere for a table of contents.  Sure, there&#8217;s a TOC for the major sections of the component, but if you&#8217;re looking for a specific part of a page (or an overview of what that page covers) you&#8217;re out of luck.  For example, take a look at the Zend_Validate <a href="http://framework.zend.com/manual/en/zend.validate.set.html" target="_blank">list of standard validation classes</a>.  Now try to find the documentation on the URI validator.  Can&#8217;t find it?  That&#8217;s &#8217;cause it doesn&#8217;t exist.  Too bad you had to scroll down through 39 page-lengths&#8217; worth of documentation to find that out.</p>
<p><span id="more-777"></span>Wouldn&#8217;t it be nice if you&#8217;d had something like this:</p>
<p><img class="alignnone size-full wp-image-779" title="Zend Validate TOC" src="http://cmorrell.com/wp-content/uploads/2010/03/Zend_Validate_TOC.png" alt="" width="281" height="338" /></p>
<p>Well, there are two things you can do.  The first is to vote on <a href="http://framework.zend.com/issues/browse/ZF-9509" target="_blank">ZF-9509</a> and <a href="http://framework.zend.com/issues/browse/ZF-9508" target="_blank">ZF-9508</a>.  But until the documentation is fixed, you can download my Greasemonkey script that gives you a page TOC right now:</p>
<p><a href="http://userscripts.org/scripts/show/72873" target="_blank">[Download id not defined]</a></p>
<p>Hope you enjoy!</p>
<div class="su-linkbox" id="post-777-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/zend-framework-documentation-777&quot;&gt;Better Zend Framework Documentation&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/zend-framework-documentation-777/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zf/zend-framework-documentation-777</feedburner:origLink></item>
		<item>
		<title>Automatic Virtual Hosts w/ Proxy Auto-Config</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/8188t1bbAOs/automatic-virtual-hosts-w-proxy-auto-config-768</link>
		<comments>http://cmorrell.com/webdev/automatic-virtual-hosts-w-proxy-auto-config-768#comments</comments>
		<pubDate>Thu, 25 Mar 2010 19:50:34 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=768</guid>
		<description><![CDATA[I often tell my co-workers that if they&#8217;re doing the same basic thing over and over again, to let me know, because there&#8217;s probably a way to automate it.  That&#8217;s why whenever I used to start a new web development &#8230; <a href="http://cmorrell.com/webdev/automatic-virtual-hosts-w-proxy-auto-config-768">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I often tell my co-workers that if they&#8217;re doing the same basic thing over and over again, to let me know, because there&#8217;s probably a way to automate it.  That&#8217;s why whenever I used to start a new web development project I&#8217;d feel a twinge of guilt.  Does this look familiar?</p>
<ul>
<li>Create /path/to/vhosts/projectname/public</li>
<li>Edit /etc/hosts to add <code>127.0.0.1 projectname.localhost</code></li>
<li>Edit /path/to/httpd-vhosts.conf to add a new <code>&lt;VirtualHost&gt;</code> directive for projectname.localhost</li>
<li>Repeat for each new project</li>
</ul>
<p>It&#8217;s not a big deal—maybe a two minute distraction—but it always bugged me.  I&#8217;d looked into automating this before, but it always led to me installing a DNS server on my local machine, which is something I don&#8217;t particularly want to do.  Then, just a few days ago, I accidentally stumbled on to a fantastic cross-platform solution.</p>
<p><span id="more-768"></span>First let&#8217;s start with Apache, which was always the un-problematic part of the equation.  There&#8217;s a great Apache extension called <a href="http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html" target="_blank">mod_vhost_alias</a> that was made to do just this.  All you need is one slightly modified <code>&lt;VirtualHost&gt;</code> directive and you&#8217;re set:</p>
<pre class="brush: plain;">
&lt;VirtualHost *:80&gt;
    ServerAdmin webmaster@localhost
    VirtualDocumentRoot &quot;/path/to/vhosts/%1/public&quot;
    ServerName subdomains.localhost
    ServerAlias *.localhost
    LogFormat &quot;%V %h %l %u %t \&quot;%r\&quot; %s %b&quot; vcommon
    ErrorLog &quot;logs/vhosts-error_log&quot;
    CustomLog &quot;logs/vhosts-access_log&quot; vcommon
&lt;/VirtualHost&gt;
</pre>
<p>And you&#8217;re also going to want to set directory permissions on all those directories:</p>
<pre class="brush: plain;">
&lt;Directory &quot;/path/to/vhosts/*/public&quot;&gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
&lt;/Directory&gt;
</pre>
<p>You&#8217;ll also probably want to turn <code>UseCanonicalName Off</code>.  Now Apache is set up to map <strong>anything</strong>.localhost to /path/to/vhosts/<strong>anything</strong>/public.  The problem is, your computer still doesn&#8217;t know that it should be handling http://anything.localhost.  That&#8217;s where the proxy auto-config file comes into play.</p>
<p>Proxy Auto-Config files, or PAC files, were designed to help your browser determine if and when it should use a proxy.  PAC files are actually just simple JavaScript files with one function that takes URL and Host Name arguments and returns a string telling the browser what to do.  Often this would be used to send certain traffic through a proxy, or proxy certain traffic at certain times of the week (it might be useful as a distraction-blocker as well), but in our case we&#8217;re going to use it to forward all <strong>.localhost</strong> traffic back to our local web server.</p>
<p>Just create a file called <strong>localhost.pac</strong> and put the following inside it:</p>
<pre class="brush: plain;">
function FindProxyForURL(url, host)
{
	if (dnsDomainIs(host, &quot;.localhost&quot;)) {
		return &quot;PROXY localhost&quot;;
	}
	return &quot;DIRECT&quot;;
}
</pre>
<p>Basically what this file is saying is, if the domain is <strong>*.localhost</strong>, send it to localhost, otherwise just connect directly.  All you have to do is save that file and tell your browsers to use it, and you&#8217;re set.  Each browser is a little different, but most (if not all) support PAC files:</p>
<ul>
<li><strong>Safari</strong>: System Preferences -&gt; Network -&gt; Advanced&#8230; -&gt; Proxies -&gt; Automatic Proxy Configuration</li>
<li><strong>Firefox</strong>: Preferences -&gt; Advanced -&gt; Network -&gt; &#8220;Configure how Firefox connects to the Internet&#8221; -&gt; Automatic proxy configuration URL</li>
<li><strong>MSIE</strong>: Tools -&gt; Internet Options -&gt; Connections -&gt; LAN Settings -&gt; Use automatic configuration script</li>
<li><strong>Chrome</strong>: Uses Safari/Internet Explorer settings</li>
<li><strong>Opera</strong>: Preferences -&gt; Advanced -&gt; Network -&gt; Use automatic proxy configuration</li>
</ul>
<p>Now, when you go to <strong>http://mynextawesomeidea.localhost</strong> your system will automatically attempt to load <strong>/path/to/vhosts/mynextawesomeidea/public</strong>.  Any time you want to start a new project, just create the directory and go!</p>
<p><strong>A couple notes:</strong> this technique messes with a few environmental variables.  Apache seems to get confused about your DOCUMENT_ROOT and REQUEST_URI.  Your document root is going to be your global document root, not the /path/to/vhosts/&#8230; directory, and your REQUEST_URI will include the hostname and protocol parts, not just the path and query parts.  Another side effect is that you need to set your RewriteBase to / if you&#8217;re using mode_rewrite.</p>
<div class="su-linkbox" id="post-768-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/automatic-virtual-hosts-w-proxy-auto-config-768&quot;&gt;Automatic Virtual Hosts w/ Proxy Auto-Config&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/automatic-virtual-hosts-w-proxy-auto-config-768/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/automatic-virtual-hosts-w-proxy-auto-config-768</feedburner:origLink></item>
		<item>
		<title>Review: Zend Framework 1.8 Web Application Development</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/_BXMtrD0NiE/review-1-8-web-application-development-760</link>
		<comments>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760#comments</comments>
		<pubDate>Wed, 24 Mar 2010 15:02:26 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=760</guid>
		<description><![CDATA[At the beginning of February PACKT Publishing sent me a copy of Zend Framework 1.8 Web Application Development by Keith Pope and asked me to post a review.  Unfortunately a bunch of stuff came up, so it wasn&#8217;t until this &#8230; <a href="http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At the beginning of February <a href="http://www.packtpub.com/" target="_blank">PACKT Publishing</a> sent me a copy of <em><a href="http://www.amazon.com/gp/product/1847194222?ie=UTF8&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;tag=inxilcom-20&amp;creativeASIN=1847194222">Zend Framework 1.8 Web Application Development</a></em> by Keith Pope and asked me to post a review.  Unfortunately a bunch of stuff came up, so it wasn&#8217;t until this last week that I got a chance to really look it over.  Here are some of my thoughts.</p>
<p><span id="more-760"></span></p>
<p>The book is structured in two parts.  The first two chapters cover the basic setup of the Zend Framework (ZF) and, more specifically, a look at its Model-View-Controller (MVC) implementation.  Almost all of the book from there on out focuses on building a real-world ecommerce application using ZF.  I tend to be a learning-by-doing type of person, which I think tends to be true of many programmers, so I think this is a pretty good way to lay out a book.</p>
<p>Much of the book focuses on Models, and how to use various ZF components to implement your domain logic.  Most people agree nowadays that you should have fat models and skinny controllers (in that your controllers should really just have enough code to facilitate your models doing the work), and Keith Pope&#8217;s focus on models really hits this home in the book.  The topics of user accounts, the shopping cart and the catalog are all addressed in this light, while still bringing up topics like forms, controllers, views, action helpers, etc.</p>
<p>In general, the book focuses on best practices, which I think is really important for new ZF developers.  Because one of the guiding principals of the Zend Framework is that it gives you freedom to implement things however you like and use only the components you want, it can be hard for people just getting started to get a sense of how they should use certain components, and particularly how everything falls together in a &#8220;typical&#8221; MVC application.   Following along with the development of the storefront application in this book is a great way to see how those components often are used together.</p>
<p>That said, there are ways in which the code in this book is outdated or less-than-ideal.  As with anything that moves as fast as the Zend Framework has been moving, it&#8217;s hard to keep up with the latest tricks and best practices (and in some places it feels like they skipped on editing to try to publish the book before it got too outdated—there are plenty of minor code inconsistencies and typos throughout).  This book is a good place to get started, but keep in mind that the Zend Framework is already at 1.10, with 2.0 on the horizon, so anything that&#8217;s not the <a href="http://framework.zend.com/manual/en/" target="_blank">Zend Framework Official Documentation</a> is in danger of being out of date at any moment.</p>
<p>Also, keep in mind that there&#8217;s already a lot of good information out there, so if you don&#8217;t mind finding it yourself, you might not need a book.  In fact, I found that most of the code in the authorization chapter was almost a direct copy of <a href="http://weierophinney.net/matthew/archives/201-Applying-ACLs-to-Models.html" target="_blank">Matthew Weier O&#8217;Phinney&#8217;s blog post on Applying ACL&#8217;s to Models</a>.  If you read blogs like Matthew&#8217;s (who is the project lead for ZF, and a fantastic resource) and spend time on <a href="http://zftalk.com/" target="_blank">#zftalk</a> you can figure most things out on your own (<a href="http://site.svn.dasprids.de/trunk/" target="_blank">Ben Scholzen&#8217;s demo application</a> is another good starting point).  The information may be a little scattered, but it&#8217;s out there.</p>
<p>In the end, I think that this book would be a really helpful resource to someone who&#8217;s just getting started with MVC architecture and other design patterns in PHP.  It also is a good way to see most of the Zend Framework best practices put to use in one place.  On the other hand, if you want the latest information available and are willing to work for it, everything you need is probably online and free.</p>
<p>Some resources that might be helpful to new ZF developers:</p>
<ul>
<li><a href="http://devzone.zend.com/tag/Zend%20Framework" target="_blank">Zend DevZone</a></li>
<li><a href="http://stackoverflow.com/questions/tagged/zend-framework" target="_blank">Questions tagged w/ Zend Framework on Stack Overflow</a></li>
<li><a href="http://zftalk.com/" target="_blank">#zftalk</a></li>
<li><a href="http://www.zendframeworkinaction.com/" target="_blank">Zend Framework in Action Blog</a></li>
<li><a href="http://weierophinney.net/matthew/" target="_blank">Matthew Weier O&#8217;Phinney&#8217;s Blog</a></li>
<li><a href="http://www.rmauger.co.uk/" target="_blank">Ryan Mauger&#8217;s Blog</a></li>
<li><a href="http://www.dasprids.de/" target="_blank">Ben Scholzen&#8217;s Blog</a></li>
</ul>
<div class="su-linkbox" id="post-760-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760&quot;&gt;Review: Zend Framework 1.8 Web Application Development&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760</feedburner:origLink></item>
		<item>
		<title>Zend Framework Bash Completion Script</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/XQA6YRx0nI0/bash-completion-script-751</link>
		<comments>http://cmorrell.com/webdev/zf/bash-completion-script-751#comments</comments>
		<pubDate>Sat, 20 Mar 2010 15:05:11 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=751</guid>
		<description><![CDATA[If you use the Zend Framework CLI interface much you probably find yourself expecting tab-completion to work.  Well, with this bash completion script it will.  Just add the following line to your .bashrc or .bash_profile: source path/to/zf.bash Next time you &#8230; <a href="http://cmorrell.com/webdev/zf/bash-completion-script-751">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you use the Zend Framework CLI interface much you probably find yourself expecting tab-completion to work.  Well, with this bash completion script it will.  Just add the following line to your .bashrc or .bash_profile:</p>
<p><code>source path/to/zf.bash</code></p>
<p>Next time you load the terminal, you can type &#8220;zf c&#8221; and hit TAB twice to see a list of available commands (change, configure and create&#8221; or type &#8220;zf cr&#8221; and hit TAB to have &#8220;create&#8221; automatically inserted for you.  The script works for both action names and provider names (but not for anything past that).  Eventually I want the script to dynamically load the available commands (so that it works with custom providers and future versions of ZF without updates) but I couldn&#8217;t get that working for this version so I just hard coded them.</p>
<p>There&#8217;s also a version that completes commands from the <a href="http://cmorrell.com/open-source/galahad-framework-extension">Galahad Framework Extension</a> if you&#8217;re testing that out…</p>
<a href="http://cmorrell.com/downloads/5" title="Version 1.10.2, Downloaded 999 times">Zend Framework CLI Bash Completion Script [1.71 kB]</a>
<p>Enjoy!</p>
<div class="su-linkbox" id="post-751-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/bash-completion-script-751&quot;&gt;Zend Framework Bash Completion Script&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/bash-completion-script-751/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zf/bash-completion-script-751</feedburner:origLink></item>
		<item>
		<title>Namespacing ACL resources &amp; Galahad_Acl</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/1QoWzgk6k1o/namespacing-acl-resources-galahad-acl-737</link>
		<comments>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737#comments</comments>
		<pubDate>Wed, 17 Mar 2010 16:04:25 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[galahad-fe]]></category>
		<category><![CDATA[wishlist]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=737</guid>
		<description><![CDATA[In most of my applications I like to handle authorization (querying the ACL) in one (or more) of three ways: Authorize access to a model&#8217;s method Authorize access to a controller action Authorize access to an arbitrary &#8220;permission&#8221; In general &#8230; <a href="http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In most of my applications I like to handle authorization (querying the ACL) in one (or more) of three ways:</p>
<ul>
<li>Authorize access to a model&#8217;s method</li>
<li>Authorize access to a controller action</li>
<li>Authorize access to an arbitrary &#8220;permission&#8221;</li>
</ul>
<p>In general I find it&#8217;s best to keep authorization within the domain (querying the ACL within my models when they&#8217;re accessed) as this provides the most consistent behavior.  For example, if I eventually add a REST API to my application I don&#8217;t have to duplicate all my authorization logic in the new REST controllers.  When the application calls something like <code>Default_Model_Post::save()</code> it either saves or throws an ACL exception, no matter where it was called from.  This is great in that it saves me from having to duplicate code and keeps my system more secure.</p>
<p>On the other hand, there are times when it&#8217;s just a lot easier to handle authorization in the controller.  For example, if guests should never access my &#8220;Admin&#8221; module, it doesn&#8217;t make sense to ever let them access /admin/ URLs.  Also, if you&#8217;re using Zend_Navigation, having ACL resources that match controller actions lets you utilize its ACL integration.</p>
<p>If you&#8217;re ever going to mix these two techniques, you&#8217;ll eventually bump into the case where a model and a controller share the same name.  What if you need to set permissions on a &#8220;user&#8221; controller and different permissions on a &#8220;user&#8221; model?  This is where namespacing comes into play.  As suggested by the <a href="http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.navigation.setup" target="_blank">Zend Framework manual</a>, I always name my controller action resources in the format <code>mvc:module.controller.action</code>.  I name my model resources similarly, in the format <code>model:module.modelName.methodName</code>.  In both theses cases, &#8220;mvc&#8221; and &#8220;model&#8221; are the namespace, and everything following the colon is the actual resource name.  Now I can refer to my &#8220;admin&#8221; module as <code>mvc:admin</code> and the models within my admin module as <code>model:admin</code>.</p>
<p>This is where things get interesting.  If you set up your ACL chains correctly, you can set permissions on whole modules or models and have those rules cascade to their child controllers or methods.  For example, say you set up your ACL as follows:</p>
<pre class="brush: php;">
$acl = new Zend_Acl();
$acl-&gt;addResource('mvc:');
$acl-&gt;addResource('mvc:admin', 'mvc:');
$acl-&gt;addResource('mvc:admin.user', 'mvc:admin');
$acl-&gt;addResource('mvc:admin.user.create', 'mvc:admin.user');
$acl-&gt;addRole('guest');
$acl-&gt;addRole('admin', 'guest');
$acl-&gt;deny();
$acl-&gt;allow('admin', 'mvc:admin');
</pre>
<p>Now if a user with the role &#8220;admin&#8221; tries to access the resource &#8220;mvc:admin.user.create&#8221; (http://basename/admin/user/create) they will be allowed, but a user with the role &#8220;guest&#8221; will not.  Using this technique gives you as much granularity as you need in your ACL, but at the same time lets you set broad permissions where appropriate.</p>
<p>This is where <code>Galahad_Acl</code> comes into play.  Setting up all these resources can be tedious, as is checking permissions in each controller.  <code>Galahad_Acl</code> in conjunction with <code>Galahad_Model_Entity</code> and <code>Galahad_Controller_Plugin_Acl</code> automate everything but the actual permissions that are specific to your application.</p>
<p><span id="more-737"></span></p>
<p>By default, whenever <code>Galahad_Acl</code> has a role added to it in the format &#8220;namespace:resource.subResourse&#8221; (etc) it automatically adds the resources up the chain.  For example, if I add &#8220;mvc:default.index.index&#8221; to a Galahad_Acl object, it would add the following resources to the ACL:</p>
<ul>
<li>mvc:</li>
<li>mvc:default (parent = &#8220;mvc:&#8221;)</li>
<li>mvc:default.index (parent = &#8220;mvc:default&#8221;)</li>
<li>mvc:default.index.index (parent = &#8220;mvc:default.index&#8221;)</li>
</ul>
<p><code>Galahad_Controller_Plugin_Acl</code> takes this a step further by automatically adding any controller action that&#8217;s dispatched to the ACL and then checking against the ACL.  This means that with the following ACL:</p>
<pre class="brush: php;">
$acl = new Galahad_Acl();
$acl-&gt;addRole('guest');
$acl-&gt;addRole('staff', 'guest');
$acl-&gt;addRole('admin', 'staff');
$acl-&gt;addResource('mvc:blog.entry.view');
$acl-&gt;deny();
$acl-&gt;allow('admin', 'mvc:');
$acl-&gt;allow('staff', 'mvc:blog');
$acl-&gt;allow('guest', 'mvc:blog.entry.view');
</pre>
<p>The following would be true:</p>
<ul>
<li>Role &#8220;admin&#8221; would be allowed access to any URL (&#8220;admin&#8221; is allowed access to &#8220;mvc:&#8221;)</li>
<li>Role &#8220;staff&#8221; would be allowed access to /blog/entry/edit even though permissions weren&#8217;t explicitly set for the resource &#8220;mvc:blog.entry.edit&#8221; (because &#8220;staff&#8221; is allowed to access &#8220;mvc:blog&#8221;)</li>
<li>Role &#8220;guest&#8221; would be allowed to view /blog/entry/view but no other portion of the blog (&#8220;guest&#8221; is allowed access to the specific resource &#8220;mvc:blog.entry.view&#8221;)</li>
</ul>
<p><code>Galahad_Model_Entity</code> works similarly.  By default each entity adds itself to the ACL in the format &#8220;model:module.modelName&#8221; so that the model <code>Default_Model_User</code> has the resource ID &#8220;model:default.user&#8221;.  Each model has a method called <code>_initAcl</code> which lets you manage permissions on a per-model basis.  This is better demonstrated in code:</p>
<pre class="brush: php;">
class Default_Model_Post extends Galahad_Model_Entity
{
    protected function _initAcl($acl)
    {
        // Deny permissions to anything on this model unless explicitly allowed
        // We don't have to add &quot;model:default.post&quot; because Galahad_Model_Entity
        // automatically does that for us
        $acl-&gt;deny(null, $this);
        // Allow guests to fetch the content of posts
        $acl-&gt;allow('guest', $this, 'fetch')
        // Allow admins to save changes to posts
        $acl-&gt;allow('admin', $this, 'save')
    }
    public function save()
    {
        if (!$this-&gt;getAcl()-&gt;isAllowed($this-&gt;getRole(), $this, 'save')) {
            throw new Galahad_Acl_Exception('Current user is not allowed to save posts');
        }
        $dataMapper = $this-&gt;getDataMapper();
        return $dataMapper-&gt;save($this);
    }
}
</pre>
<p>So, as you can see, the model denies access to itself unless explicitly allowed, and then allows access to certain methods for certain roles.</p>
<p>All three of these classes are in their early stages of development, but I&#8217;d love some feedback on the ideas/suggestions on how to make them better.</p>
<p>Check out the code on GitHub:</p>
<ul>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Acl.php" target="_blank">Galahad_Acl</a></li>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Controller/Plugin/Acl.php" target="_blank">Galahad_Controller_Plugin_Acl</a></li>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Model/Entity.php" target="_blank">Galahad_Model_Entity</a></li>
</ul>
<p>Also, for more information about the <code>Galahad_Model</code> system, check out my previous post on <a href="http://cmorrell.com/web-development/more-php-modelling-383">modeling in the Zend Framework</a>.</p>
<div class="su-linkbox" id="post-737-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737&quot;&gt;Namespacing ACL resources &amp; Galahad_Acl&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737</feedburner:origLink></item>
		<item>
		<title>Zend Framework URI validator &amp; filter</title>
		<link>http://feedproxy.google.com/~r/cmorrell/~3/9bfxE2Kxe2U/validate-filter-url-728</link>
		<comments>http://cmorrell.com/webdev/zf/validate-filter-url-728#comments</comments>
		<pubDate>Fri, 12 Mar 2010 19:06:53 +0000</pubDate>
		<dc:creator>inxilpro</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>
		<guid isPermaLink="false">http://cmorrell.com/?p=728</guid>
		<description><![CDATA[For the last couple of months I&#8217;ve been incorporating portions of applications I&#8217;m working on into my Galahad Framework Extension project.  Right now it&#8217;s not at a point where I&#8217;d feel comfortable promoting it (you can check out the project &#8230; <a href="http://cmorrell.com/webdev/zf/validate-filter-url-728">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the last couple of months I&#8217;ve been incorporating portions of applications I&#8217;m working on into my Galahad Framework Extension project.  Right now it&#8217;s not at a point where I&#8217;d feel comfortable promoting it (you can <a title="Galahad Framework Extension" href="http://bit.ly/d3ULiy" target="_blank">check out the project on GitHub</a> if you want), but there are portions that are pretty solid that might be useful to others right now.  Two such portions are <code>Galahad_Validate_Uri</code> and <code>Galahad_Filter_PrependHttp</code> which are both very useful for processing forms with URL fields.</p>
<p><span id="more-728"></span></p>
<p>Recently I was building a form that contained a URL field, and after browsing the <a href="http://framework.zend.com/manual/en/zend.validate.html" target="_blank">Zend_Validate docs</a>, I was surprised not to find a <code>Zend_Validate_Uri</code> component.  Luckily, <code>Zend_Uri</code> already validates URIs, so it was just a matter of writing a wrapper that followed the Zend_Validate APIs.  Basic usage:</p>
<pre class="brush: php;">
$validator = new Galahad_Validate_Uri();
$validator-&gt;isValid('http://www.google.com/');
</pre>
<p>Obviously this would be much more useful when combined with <code>Zend_Form</code> or some more extensive validation chains, but you get the point.</p>
<p>Grab <a href="http://bit.ly/cFB0li" target="_blank">Galahad_Validate_Uri</a> from GitHub.</p>
<p>The second issue I often deal with is people forgetting (or not knowing) to include http:// in the URLs that they submit.  Rather than solve this at the controller-level, I decided this was a common enough problem to build a Zend_Filter component for.  Basic usage:</p>
<pre class="brush: php;">
$filter = new Galahad_Filter_PrependHttp(array(
    'allowedSchemes' =&gt; array('http://', 'https://', 'mailto:'),
    'checkUri' =&gt; true,
));
echo $filter-&gt;filter('google.com'); // Prints 'http://google.com'
</pre>
<p>This filter takes any string and prepends &#8220;http://&#8221; to it if it doesn&#8217;t already contain an allowed scheme (more on that below).  By default it allows &#8220;http://&#8221;, &#8220;https://&#8221; and &#8220;mailto:&#8221; schemes, but you could set this to anything (say you want to allow &#8220;itms://&#8221; [iTunes] links) by setting the &#8216;allowedSchemes&#8217; option.  It also (optionally) checks if the resulting URI is valid, and only applies the filter if it is (effectively only prepending &#8220;http://&#8221; to otherwise valid URIs).  Remember, though, that &#8220;http://something&#8221; is technically a valid URI, so that will be accepted.  In the future I hope to add additional options to limit to URLs that follow certain standards.</p>
<p>Grab <a href="http://bit.ly/csqLWK" target="_blank">Galahad_Filter_PrependHttp</a> from GitHub.</p>
<p><strong>Update</strong>: I&#8217;ve submitted Zend_Filter_PrependHttp to the Zend Framework wiki for comments.  <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Filter_PrependHttp+-+Chris+Morrell" target="_blank">Check it out</a> and let me know if you think there&#8217;s anything I should change (I&#8217;ve posted a few ideas already).</p>
<p>The validator and filter work well together with <code>Zend_Form</code> to create URL form elements:</p>
<pre class="brush: php;">
$this-&gt;addElement('text', 'my_url', array(
    'label' =&gt; 'URL:',
    'filters' =&gt; array('StringTrim', 'StringToLower', new Galahad_Filter_PrependHttp()),
    'validators' =&gt; array(new Galahad_Validate_Uri()),
));
</pre>
<p>The form element generated by that code will produce fairly normalized, valid URIs.</p>
<div class="su-linkbox" id="post-728-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/validate-filter-url-728&quot;&gt;Zend Framework URI validator &amp; filter&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/validate-filter-url-728/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://cmorrell.com/webdev/zf/validate-filter-url-728</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 4.022 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-05 12:00:26 --><!-- Compression = gzip -->
