<?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>Aaron Saray » Blog</title>
	
	<link>http://aaronsaray.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Wed, 16 May 2012 15:14:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/aaronsaray" /><feedburner:info uri="aaronsaray" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://aaronsaray.com</link><url>http://assets.aaronsaray.com/images/logo.png</url><title>Aaron Saray</title></image><feedburner:emailServiceId>aaronsaray</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Keep your Admin Interface CSS Separate</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/X46SCEKvJzQ/</link>
		<comments>http://aaronsaray.com/blog/2012/05/16/keep-your-admin-interface-css-separate/#comments</comments>
		<pubDate>Wed, 16 May 2012 15:14:53 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1031</guid>
		<description><![CDATA[There are a number of performance arguments about combining assets to reduce HTTP requests and speed up your site. I agree! However, I do have to say that there is such a thing as overkill &#8211; to the detriment of &#8230; <a href="http://aaronsaray.com/blog/2012/05/16/keep-your-admin-interface-css-separate/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/05/16/keep-your-admin-interface-css-separate/">Keep your Admin Interface CSS Separate</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>There are a number of performance arguments about combining assets to reduce HTTP requests and speed up your site.  I agree!  However, I do have to say that there is such a thing as overkill &#8211; to the detriment of speed and security&#8230; </p>
<p><strong>Keep your admin interface CSS separate from the rest of your CSS.</strong>  </p>
<p>There are a number of reasons to do this:</p>
<ul>
<li><strong>Security:</strong> In CSS, a number of class names and IDs are revealed.  And, if you&#8217;re programming your code semantically, they should be pretty explanatory (see: verbose).  This exposes the names/interfaces/code structure and featureset of your administration interface to anyone who can look at the CSS.  Not Good.</li>
<li><strong>Extra space / slows down the interwebs:</strong> Let&#8217;s face it, more than 99% of your userbase should be normal users, right?  Why add on all this extra CSS just for the 1% of users.  Keep it trim and fitting the 99% of users.  This is 19% better than Pareto&#8217;s principle even!</li>
<li><strong>Another HTTP request for admin is fine&#8230;</strong> Usually when you&#8217;re logged into the administration side of things, you&#8217;re not expecting lightning fast results anyways.  And to top it off, you&#8217;re no longer (and never were) a conversion.  Speed and usability matters much more for your conversion statistics (IE, this user may leave because the site is too slow).  You&#8217;re not going to abandon your own site because your admin interface is too slow, are you?  (True, though, that&#8217;s not me just giving you free-for-all to make horribly slow admin interfaces though&#8230;)</li>
</ul>
<p><a href="http://aaronsaray.com/blog/2012/05/16/keep-your-admin-interface-css-separate/">Keep your Admin Interface CSS Separate</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=X46SCEKvJzQ:rqJvnHARrI8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=X46SCEKvJzQ:rqJvnHARrI8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=X46SCEKvJzQ:rqJvnHARrI8:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/X46SCEKvJzQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/05/16/keep-your-admin-interface-css-separate/</feedburner:origLink></item>
		<item>
		<title>PHPUnit Mock Objects: Only Mock What You Need</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/eT47O57ZcYI/</link>
		<comments>http://aaronsaray.com/blog/2012/05/08/phpunit-mock-objects-only-mock-what-you-need/#comments</comments>
		<pubDate>Tue, 08 May 2012 13:59:49 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1034</guid>
		<description><![CDATA[I was looking at mock objects in PHPUnit the other day and started to get confused. When I asked for a Mock object, the entire object was a mock. In all actuality, it wasn&#8217;t so much a Mock of the &#8230; <a href="http://aaronsaray.com/blog/2012/05/08/phpunit-mock-objects-only-mock-what-you-need/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/05/08/phpunit-mock-objects-only-mock-what-you-need/">PHPUnit Mock Objects: Only Mock What You Need</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I was looking at mock objects in PHPUnit the other day and started to get confused.  When I asked for a Mock object, the entire object was a mock.  In all actuality, it wasn&#8217;t so much a Mock of the object but a complete shell of it.  Each method needed to be defined.  So, if I was testing an object that required three methods to execute, I would have to mock each method.  (Yeah, some people would say that no single test should test more than one method, but that&#8217;s just semantics.  Sometimes you have to start more grand in your testing instead of the perfect best way.  I was working on a legacy application and didn&#8217;t have the ability to refactor at this time&#8230;).  Anyway, I created my mock in the normal way I knew of:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1034code4'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p10344"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1034code4"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$myMock</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myObject'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>Now, the entire object was an empty mock.  I had to define each one.  </p>
<p><strong>Define your methods to mock only, instead.</strong></p>
<p>Try this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1034code5'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p10345"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1034code5"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$myMock</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMockBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myObject'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMethods</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'onlyMethodToMock'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMock</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>Oh, and to make it easier, in PHP Unit 3.6, it&#8217;s all built in as a second parameter of the getMock() call:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1034code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p10346"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1034code6"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$myMock</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myObject'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'onlyMethodToMock'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>Sweet.
<p><a href="http://aaronsaray.com/blog/2012/05/08/phpunit-mock-objects-only-mock-what-you-need/">PHPUnit Mock Objects: Only Mock What You Need</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=eT47O57ZcYI:rJiKGnfEVDg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=eT47O57ZcYI:rJiKGnfEVDg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=eT47O57ZcYI:rJiKGnfEVDg:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/eT47O57ZcYI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/05/08/phpunit-mock-objects-only-mock-what-you-need/</feedburner:origLink></item>
		<item>
		<title>Translate Your Error Messages in Your Zend Framework Controllers</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/qIkNgADjicY/</link>
		<comments>http://aaronsaray.com/blog/2012/05/01/translate-your-error-messages-in-your-zend-framework-controllers/#comments</comments>
		<pubDate>Tue, 01 May 2012 13:41:12 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Misc Web Design]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=991</guid>
		<description><![CDATA[I&#8217;ve been making a push to have more of my projects multi-lingual. However, one thing I kept forgetting about was those super-rare error messages that have to come from the Controller. For the most part, all of your errors should &#8230; <a href="http://aaronsaray.com/blog/2012/05/01/translate-your-error-messages-in-your-zend-framework-controllers/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/05/01/translate-your-error-messages-in-your-zend-framework-controllers/">Translate Your Error Messages in Your Zend Framework Controllers</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been making a push to have more of my projects multi-lingual.  However, one thing I kept forgetting about was those super-rare error messages that have to come from the Controller.  For the most part, all of your errors should be handled by your validators in your forms.  However, from time to time, there needs to be an error handled in your controller.  </p>
<p>Enter Zend_Translate!  Here is what I suggest:</p>
<p>Create a Zend Translate instance for your entire project.  Store this in the Zend_Registry (I tend to do this in the bootstrap because every item, whether it be CLI or web, needs the ability to translate output).  Then, create your situation where you might have to add an error message.  Finally, translate the message before it is added to the persistent storage.</p>
<p>Side note: There is some argument as to whether the translation should be handled in the controller or when you are trying to show the view.  In this example I will just be showing / suggesting in the controller.  However, that is a good discussion to have&#8230; perhaps this should only happen in the views&#8230; <img src='http://aaronsaray.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Let&#8217;s check out some code in an action</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p991code8'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p9918"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p991code8"><div class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> dosomethingAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>Zend_Auth<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasIdentity</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><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//ruh roh - need some identity</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$translate</span> <span style="color: #339933;">=</span> Zend_Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'translate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// our main object we created</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$translate</span><span style="color: #339933;">-&gt;</span>_<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Please log in.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">flashMessenger</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_redirect<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// life is ok here!</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></table></div>

<p>It may be easy to forget that we want to translate all of our output.  Don&#8217;t forget the error messages in the controller!</p>
<p><a href="http://aaronsaray.com/blog/2012/05/01/translate-your-error-messages-in-your-zend-framework-controllers/">Translate Your Error Messages in Your Zend Framework Controllers</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=qIkNgADjicY:iXaC2ssRFiE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=qIkNgADjicY:iXaC2ssRFiE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=qIkNgADjicY:iXaC2ssRFiE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/qIkNgADjicY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/05/01/translate-your-error-messages-in-your-zend-framework-controllers/</feedburner:origLink></item>
		<item>
		<title>Site profile: thebetterbachelor.com</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/_fDHr4fCIso/</link>
		<comments>http://aaronsaray.com/blog/2012/04/17/site-profile-thebetterbachelor-com/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 14:06:11 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[Misc Web Design]]></category>
		<category><![CDATA[site profile]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1115</guid>
		<description><![CDATA[Goal: to create a bachelor cookbook and sell it to other bachelors online. The price of the cookbook was to be very cheap so that it wasn&#8217;t too much of a risk. The book itself was supposed to be picture &#8230; <a href="http://aaronsaray.com/blog/2012/04/17/site-profile-thebetterbachelor-com/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/04/17/site-profile-thebetterbachelor-com/">Site profile: thebetterbachelor.com</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Goal: to create a bachelor cookbook and sell it to other bachelors online.  The price of the cookbook was to be very cheap so that it wasn&#8217;t too much of a risk.  The book itself was supposed to be picture rich and very verbose.  It showed how to accomplish tasks that other books assumed a person knew.</p>
<p>Technology/Process:</p>
<p>thebetterbachelor.com was redirected to /10dish for 10 Dish Cookbook.  The thought was at some point to broaden the platform if the cookbook was successful.</p>
<p>This was a one page selling page with a paypal link.  It simply talked about the features of the book, the cost of creating your own meals, and compared this all to going out.  The cost savings was emphasized.</p>
<p>I also appeared to give an &#8216;author&#8217;s note&#8217; to the potential customer.</p>
<p>If the visitor chose to purchase, it was a paypal IPN process.  So they received a success message and then they were emailed a link to download the PDF when paypal finished the transaction.  The link contained a special URL that used Zend Framework to read in the source PDF and stamp their name and email on each page.</p>
<p>There was also a coupon system that bypassed the purchase system and allowed an instant copy to be sent.</p>
<p>Lessons Learned</p>
<p>I learned that I really needed to give away a free chapter.  Up until receiving the product, visitors did not know the quality of the book. It could have been horrible with no pictures.</p>
<p>After speaking with a SEO expert I know, he set me up with an A/B test.  Unfortunately, not a lot was determined from that.  His suggestions was to develop the newsletter style approach which seems to work.  Hook people for some free information, and make a sales pitch later.  I never thought of doing this because when I purchase something myself, I want it.  I don&#8217;t want to wait till I get a few emails about it first.  But, he says this seems to be the best way to market items like this.</p>
<p>Overall, it was a good project.  I didn&#8217;t sell as many as I&#8217;d like but I paid for the cost of the food &#8211; and that was enough for me!</p>
<p><em>Screenshots:</em></p>
<p><a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/1.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/1-150x150.png" alt="" title="1" width="150" height="150" class="alignnone size-thumbnail wp-image-1116" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/2.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/2-150x150.png" alt="" title="2" width="150" height="150" class="alignnone size-thumbnail wp-image-1117" /></a></p>
<p><strong>Bonus! Download the cookbook free!</strong>
<a href='http://aaronsaray.com/wp/wp-content/uploads/2012/03/10dish.pdf'>10dish Cookbook</a>
<p><a href="http://aaronsaray.com/blog/2012/04/17/site-profile-thebetterbachelor-com/">Site profile: thebetterbachelor.com</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=_fDHr4fCIso:EGjjGyOQxX0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=_fDHr4fCIso:EGjjGyOQxX0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=_fDHr4fCIso:EGjjGyOQxX0:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/_fDHr4fCIso" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/04/17/site-profile-thebetterbachelor-com/</feedburner:origLink></item>
		<item>
		<title>Filtering and Validating Discussion</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/OyA_yhRJR4U/</link>
		<comments>http://aaronsaray.com/blog/2012/04/10/filtering-and-validating-discussion/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 13:13:43 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1146</guid>
		<description><![CDATA[I came up with a great topic to write this blog entry about: filters and validators. Then, I got to thinking &#8211; maybe I can get more feedback from other programmers I know. I decided to send a note out &#8230; <a href="http://aaronsaray.com/blog/2012/04/10/filtering-and-validating-discussion/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/04/10/filtering-and-validating-discussion/">Filtering and Validating Discussion</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I came up with a great topic to write this blog entry about: filters and validators.  Then, I got to thinking &#8211; maybe I can get more feedback from other programmers I know.  I decided to send a note out to a few of my buddies and see what they thought as well.  </p>
<p><strong><a href="http://aaronsaray.com">Aaron Saray</a></strong></p>
<p>Today we are comparing Filters and Validators.  Generally, we filter data to remove unwanted parts.  Validators are used against data to validate that it meets certain requirements.  As you see, these have some overlap, and it all depends on how you might choose to implement them. You could validate that a string is only alpha-numeric (and subsequently reject it if it is not), or you could filter out non-alpha-numeric content and accept that as your data.</p>
<p>So the questions are related to the following thoughts.  Feel free to share your experience and best practice advice.  Should you filter your data before you store it?  Should you filter for harmful web content, harmful xml content, or business requirements?  How do you determine what is &#8216;harmful?&#8217;  Would you say there is a difference between filtering input and filtering output?  What about when you validate based on business rules?  What if the rules change and you now have filtered or validated data this no longer valid?  Could you do a conversion if you kept all data and didn&#8217;t filter it out permanently?</p>
<p><strong><a href="http://joelclermont.com">Joel Clermont</a></strong></p>
<p><em>Quote: &#8230;Should you filter your data before you store it?  &#8230;</em>
I&#8217;m a strong believer in the basic principle: filter input, escape output. Both are equally important. If you do this properly, you can probably avoid 3 or 4 of the top 10 exploits listed by OWASP.</p>
<p><em>Quote: &#8230; Should you filter for harmful web content, harmful xml content, or business requirements?  &#8230;</em>
I guess it depends on the definition of the word &#8220;harmful&#8221;. I tend to think of things that could either harm the system (SQL injection) or harm the system&#8217;s users (XSS, malware links, etc). Some people might extend that to be harmful to the company&#8217;s reputation (graphic images or language).</p>
<p>My main advice here is to not reinvent the wheel. There are some great libraries (HTML Purifier, for one) that handle this. Oh, and don&#8217;t think that PHP&#8217;s strip_tags or ZF&#8217;s Zend_Filter_StripTags are up to the task. They&#8217;re not.</p>
<p><em>Quote: &#8230; Would you say there is a difference between filtering input and filtering output? &#8230;</em>
Filtering input is about protecting the system. Escaping output is about protecting the user. Both important, but they are implemented separately and solve different problems.</p>
<p><em>Quote: &#8230;Could you do a conversion if you kept all data and didn&#8217;t filter it out permanently?&#8230;</em>
This is a tough one. Some filters, like stripping whitespace, would likely never change. They will always be in play. But maybe if you normalize data (state/country names, for example), there&#8217;s no way to de-normalize that in the future and get raw customer input. I guess if I thought I would ever care about the raw data, I might store that somewhere else for posterity&#8217;s sake. This seems like an edge case however.</p>
<p><strong><a href="http://rodenkirch.com">James Rodenkirch</a></strong></p>
<p>Interesting topic, and actually very timely with projects I am dealing with on a daily basis <img src='http://aaronsaray.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Currently we are building out an enterprise level data warehouse for education data and one for corrections data. As surprising as this may seem to some, both of these domains have HORRENDOUS data. We see instances of missing data fields, flat out wrong demographics, and data files that change from year to year.</p>
<p>Your question &#8220;Should you filter data before you store it?&#8221; &#8211; absolutely. You never want to store data that could come back and bite you in the ass. The concepts of data warehousing require that your data is stored in a pristine state, if it is not pristine, you hold it in limbo until it can be made pristine (usually requiring user intervention).</p>
<p>So, what if you are not running a data warehouse but are running a CMS? I would still strongly argue that it is important to cleanse/reject bad data before it gets stored. If you think about the read/write actions needed on the database you can quickly see that it is better to run filters/validators once on &#8220;write&#8221;, than every time the data is requested on &#8220;read&#8221;. Basic performance benefits lead us to doing as much of the filter/validation up front as possible.</p>
<p>Please note, this does not replace the need for escaping output on display &#8211; we always need to protect our applications and our users from dangerous data. </p>
<p><strong><a href="http://twitter.com/akadeej">Jeremy Dee</a></strong></p>
<p>Great points James. I’d like to add that while providers of web services (SOAP &#038; REST) probably do a pretty good job of filtering &#038; validating the requests they receive, I think that consumers tend to place too much faith in said services &#8211; probably giving them less filtering &#038; validation than they should, especially with the easy deployment/proliferation of REST services. While many devs are quick to filter their form data, do they take the time to make sure that the current weather forecast they&#8217;re getting doesn&#8217;t have something nasty contained in it?  Exception/Error handling around any type of XML parsing to catch unannounced changes response format isn&#8217;t a bad idea either.</p>
<p>In the case of critical web services, I often store a compressed copy of my request and their response alongside the data I’ve pulled out of the transaction for the flexibility it offers (maybe I’ll use more of this transaction’s data someday) and liability concerns.</p>
<p>Finally, a question I have for the group &#8211; what practices do you follow regarding “internal” filtering and validating on a big system. With high cohesion you get an explosion of objects, each with public methods potentially being called from anywhere. When do you check parameter types and/or values? Or do you just let it fail? Type hinting’s fine for objects, but what about primitives? Personally, I know some of my “gateway” methods that start a cascade of actions, so I’ll make sure that I’ve at least got my parameters straight before I proceed with them so I don’t have to do a giant rollback way down the call stack, but I’ve often wondered if it’s overkill. </p>
<p><strong><a href="http://aaronsaray.com">Aaron Saray</a></strong>
I have two thoughts.  First, we always talk about escaping output when it comes to the user.  However, there always seems to be a bit of confusion when the actual escaping should happen.  Don&#8217;t you indeed escape potentially unsafe data going to your database (see: mysql_real_escape_string()) but you also escape it going outwards (htmlentities, etc)&#8230; So the question is where do you draw the line with escaping?  Could one argue that you could do htmlentities before you store the data too?</p>
<p>Jeremy &#8211; in regards to your primitive checking.  I&#8217;ve never come across a good standard for doing that checking.  However, I&#8217;ve been known to write special methods per class&#8230; something like &#8220;_checkSanity()&#8221; with enough domain knowledge and type knowledge to filter out unwanted data.  I&#8217;m sure that&#8217;s not the best way to do it, however.  I generally would trigger a failure than to filter the content.</p>
<p><strong><a href="http://ericlightbody.com">Eric Lightbody</a></strong></p>
<p>I&#8217;d like to address the recent question that Aaron had in regards to where to draw the line with escaping. As a general rule I like to escape before it could be potentially harmful. If I&#8217;m going to store information in a database I need to make sure that the data going into it is safe. HTML entities are safe for a database, so I&#8217;ll let it be stored there. However, those same entities can be harmful for a browser. So, before I &#8220;store&#8221; it in the browser, I need to make sure that it is safe to be there.   Business logic may change, and you may need access to the entities that were stored in the database.</p>
<p>As a side note, I would like to add that it is important that you make it easy on yourself for this type of work. Zend Framework, for example, provides a boatload of filters and validators. It also makes it easy to implement your own. If there isn&#8217;t a good structure in place to use the proper filters and validators, it&#8217;s easy to be lazy and let things slip through.</p>
<p><strong><a href="http://twitter.com/akadeej">Jeremy Dee</a></strong></p>
<p>Wow &#8211; great way of putting it Eric &#8211; &#8220;storing in the browser&#8221; &#8211; that notion of safely storing your data whatever that may mean makes for a nice rule-of-thumb. </p>
<h3>Final Thoughts</h3>
<p>I thought I&#8217;d publish this conversation so that other&#8217;s could see how a few professionals approach filtering and validating too.  Any thoughts?  Feel free to add comments below.
<p><a href="http://aaronsaray.com/blog/2012/04/10/filtering-and-validating-discussion/">Filtering and Validating Discussion</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=OyA_yhRJR4U:h5lTThgG5Mc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=OyA_yhRJR4U:h5lTThgG5Mc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=OyA_yhRJR4U:h5lTThgG5Mc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/OyA_yhRJR4U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/04/10/filtering-and-validating-discussion/</feedburner:origLink></item>
		<item>
		<title>Service profile: mketweeps</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/SxdEZB6uiXU/</link>
		<comments>http://aaronsaray.com/blog/2012/04/03/service-profile-mketweeps/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 15:20:09 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[Misc Web Design]]></category>
		<category><![CDATA[site profile]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1137</guid>
		<description><![CDATA[Goal: I came up with an idea that I wanted to find local people in our area and mention them using a twitter bot. Pretty simple. Two requirements were they either had to use the word milwaukee in their profile &#8230; <a href="http://aaronsaray.com/blog/2012/04/03/service-profile-mketweeps/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/04/03/service-profile-mketweeps/">Service profile: mketweeps</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Goal: I came up with an idea that I wanted to find local people in our area and mention them using a twitter bot.  Pretty simple.  Two requirements were they either had to use the word milwaukee in their profile or be from the milwaukee location, and they had to not have a blank profile.  The tweet contained a shout out to their name and as much of their profile as could be fit in the tweet.</p>
<p>Technology used:
Zend framework command line cron job.  Once an hour it ran.  Pretty simple using the Zend Framework OAuth stuff.  (Originally I was using the first version of the API to twitter &#8211; so I used standard HTTP requests).  </p>
<p>Lessons learned:
-Stay current when APIs change. I ignored the oAuth change at twitter and had a bot that was not functioning for a long time.
-Follow the people you mention.  Very little people followed the bot even though they were mentioned.
-Lots of replies &#8230; ok so that isn&#8217;t such a &#8216;lessons learned&#8217; but a &#8220;what should I have done about that&#8221;
-monetization.  What if I had grown a large collection of followers. Now what?
-Personal account: I should have followed people that replied to the bot.  I generally ignored all the tweets even.  Pay more attention!</p>
<p><em>screenshots</em>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-18-203832.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-18-203832-150x150.png" alt="" title="Screenshot at 2012-03-18 20:38:32" width="150" height="150" class="alignnone size-thumbnail wp-image-1138" /></a>
<p><a href="http://aaronsaray.com/blog/2012/04/03/service-profile-mketweeps/">Service profile: mketweeps</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=SxdEZB6uiXU:h5c-qY7tOug:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=SxdEZB6uiXU:h5c-qY7tOug:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=SxdEZB6uiXU:h5c-qY7tOug:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/SxdEZB6uiXU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/04/03/service-profile-mketweeps/</feedburner:origLink></item>
		<item>
		<title>Site profile: jemdiary.com</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/o8T90Zmdhr8/</link>
		<comments>http://aaronsaray.com/blog/2012/03/28/site-profile-jemdiary-com/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 19:48:18 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[Misc Web Design]]></category>
		<category><![CDATA[site profile]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1120</guid>
		<description><![CDATA[JEMDiary Goal: In 2001, having an online diary was only being piloted by a few people. Blogging was big, but considering it a &#8216;diary&#8217; was not that popular. Only a few competitors existed: myopendiary and teendiary. I started my own &#8230; <a href="http://aaronsaray.com/blog/2012/03/28/site-profile-jemdiary-com/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/03/28/site-profile-jemdiary-com/">Site profile: jemdiary.com</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>JEMDiary</p>
<p>Goal: In 2001, having an online diary was only being piloted by a few people.  Blogging was big, but considering it a &#8216;diary&#8217; was not that popular.  Only a few competitors existed: myopendiary and teendiary.  I started my own online diary system for my own site.  After a year, a few friends saw what I was doing and asked if they could do it too.  I decided to launch JEMDiary for the three girls who wanted it as a free online diary system for all.  </p>
<p>What happened: This was my longest running website.  I think it was slightly before its time.  When it became more popular, I just didn&#8217;t have the time to keep developing on it.  Then, other larger sites eclipsed it and it slowly lost market share.</p>
<p>Technology:
This was originally written in procedural PHP4.  Then, later I migrated to PHP5 in procedural style.  It finally became my first object oriented framework with my own custom controllers and views.  </p>
<p>I used to host on dreamhost.  Because of that, I learned what it was like to have a slow host that needed the site to be optimized more.  I started compressing and caching my assets.  I even ran a system to create the home page every hour as a static page with no PHP required.  This made a huge performance boost.</p>
<p>I made lots of mistakes.  One of the mistakes I made was to put the incompatible browser message at the top of the page.  Then, almost all of my pages in Google showed up with that headline instead of their actual content.  Whoops!  (That was many years ago).  To fix that, I made the tagline a h2 at the top of the page, but in smaller font.  (the design of the page wasn&#8217;t such that large headings were that available all the time).</p>
<p>The other mistake I made was having the incompatible browser be a whitelist.  So now, even with chrome, it gives a warning about having an incompatible browser.  That is not the case.</p>
<p>The site went through 5 programming versions of which 3 of those had design changes as well.  The last design was nice and clean and seemed to have the best conversion rate.</p>
<p>I did put in a few little easter eggs here and there too.  Once someone was looking at the security of my site and sent me an email with one of the easter eggs they found.  They thought it was clever. (I had put a header in there talking about the girl who I was in love with.)  I also had a &#8216;boss key&#8217; which allowed you to quickly replace the entire screen with any other url.  By default I suggested a google search of &#8216;productivity tools.&#8217;</p>
<p>The final thing I did, which was really a big deal for the time, was to allow users to export their diary in both text and word doc format.  In word doc, I would actually insert the images into their diary.  The user had control of their data.</p>
<p>I learned from MySpace success for a time with the initial Tom friend.  I would add myself as a friend.  I also started using an automated system that would comment as my user on all new user&#8217;s content. It would make one comment on their profile and one on their first diary entry. I twas ran every few hours.  The system would look at their account and create a special message based on things they said.  For example, I suggested someone add a profile picture in 4 different ways. The system would pick one randomly &#8211; and only add it to the message if they didn&#8217;t have a profile picture already.  A lot of the users thought I was actually adding the messages myself.  (A few times the programming was faulty &#8211; and I commented on &#8216;deleted&#8217; diary entries &#8211; that wasn&#8217;t good!)</p>
<p>Lessons learned:
- keep with the times!  I think I could have made some more money off of google ads if I would have kept current
- use google ads and other ads! I wasn&#8217;t placing ads very well for a while.
- advertise.  I was still #3 in free online diary search on google &#8211; but sometimes people just didn&#8217;t search that.
- some of my features were too advanced.  Some people couldn&#8217;t tell the difference between password protecting your entire diary with the other feature to password protect only certain ones.
- better anti-spam measures.  I didn&#8217;t use a captcha or anything like that to sign up.  After a while, I had a lot of spam entries.</p>
<p>Final thoughts:
It&#8217;s almost sad to see something you&#8217;ve spent more than a decade with go away.  But it was time to retire this beast.  I&#8217;m so glad I made it, stuck with it, and that I get to pull the plug myself.</p>
<p><em>Screenshots</em></p>
<p><a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162645.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162645-150x150.png" alt="" title="Screenshot at 2012-03-14 16:26:45" width="150" height="150" class="alignnone size-thumbnail wp-image-1121" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162725.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162725-150x150.png" alt="" title="Screenshot at 2012-03-14 16:27:25" width="150" height="150" class="alignnone size-thumbnail wp-image-1122" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162737.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162737-150x150.png" alt="" title="Screenshot at 2012-03-14 16:27:37" width="150" height="150" class="alignnone size-thumbnail wp-image-1123" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162758.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162758-150x150.png" alt="" title="Screenshot at 2012-03-14 16:27:58" width="150" height="150" class="alignnone size-thumbnail wp-image-1124" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162812.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162812-150x150.png" alt="" title="Screenshot at 2012-03-14 16:28:12" width="150" height="150" class="alignnone size-thumbnail wp-image-1125" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162819.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162819-150x150.png" alt="" title="Screenshot at 2012-03-14 16:28:19" width="150" height="150" class="alignnone size-thumbnail wp-image-1126" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162836.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162836-150x150.png" alt="" title="Screenshot at 2012-03-14 16:28:36" width="150" height="150" class="alignnone size-thumbnail wp-image-1127" /></a><a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162846.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162846-150x150.png" alt="" title="Screenshot at 2012-03-14 16:28:46" width="150" height="150" class="alignnone size-thumbnail wp-image-1128" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162854.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162854-150x150.png" alt="" title="Screenshot at 2012-03-14 16:28:54" width="150" height="150" class="alignnone size-thumbnail wp-image-1129" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162906.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162906-150x150.png" alt="" title="Screenshot at 2012-03-14 16:29:06" width="150" height="150" class="alignnone size-thumbnail wp-image-1130" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162917.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-162917-150x150.png" alt="" title="Screenshot at 2012-03-14 16:29:17" width="150" height="150" class="alignnone size-thumbnail wp-image-1131" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-163004.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-163004-150x150.png" alt="" title="Screenshot at 2012-03-14 16:30:04" width="150" height="150" class="alignnone size-thumbnail wp-image-1132" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-164457.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-164457-150x150.png" alt="" title="Screenshot at 2012-03-14 16:44:57" width="150" height="150" class="alignnone size-thumbnail wp-image-1133" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-18-114756.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-18-114756-150x132.png" alt="" title="Screenshot at 2012-03-18 11:47:56" width="150" height="132" class="alignnone size-thumbnail wp-image-1134" /></a>
<p><a href="http://aaronsaray.com/blog/2012/03/28/site-profile-jemdiary-com/">Site profile: jemdiary.com</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=o8T90Zmdhr8:YCPX1rTIVzA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=o8T90Zmdhr8:YCPX1rTIVzA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=o8T90Zmdhr8:YCPX1rTIVzA:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/o8T90Zmdhr8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/03/28/site-profile-jemdiary-com/</feedburner:origLink></item>
		<item>
		<title>Extend Zend_Mail to use Views</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/ejMSLul8Q3E/</link>
		<comments>http://aaronsaray.com/blog/2012/03/20/extend-zend_mail-to-use-views/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 15:42:39 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1012</guid>
		<description><![CDATA[I love working in the Zend Framework view system. One thing that bothers me, however, is that I must create a complex set of models when trying to send email. I decided that I&#8217;d like to move all of this &#8230; <a href="http://aaronsaray.com/blog/2012/03/20/extend-zend_mail-to-use-views/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/03/20/extend-zend_mail-to-use-views/">Extend Zend_Mail to use Views</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I love working in the Zend Framework view system.  One thing that bothers me, however, is that I must create a complex set of models when trying to send email.  I decided that I&#8217;d like to move all of this output for the mail class into my own view system as well.  </p>
<p>Before we begin, it&#8217;s important to know the goal. The goal is to create a version of Zend_Mail that can read in views for both HTML and Text emails. In addition, since I am such a Unit Testing Fool, I want to make sure my new changes are testable.  For once, you&#8217;re going to see a fully documented class!  I&#8217;ll post the code here and then review it afterward.</p>
<p><strong>application/models/Mail.php</strong></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1012code11'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p101211"><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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
</pre></td><td class="code" id="p1012code11"><div class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Zend_Mail override<br />
&nbsp;* <br />
&nbsp;* Holds the class for the zend_mail override<br />
&nbsp;* @package AaronSaray<br />
&nbsp;*/</span><br />
<br />
<span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Overrides Zend_Mail to use views<br />
&nbsp;* <br />
&nbsp;* This creates the setBody commands in such a way that the views can be used to populate the emails<br />
&nbsp;* @author Aaron Saray<br />
&nbsp;* @package AaronSaray<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Application_Model_Mail <span style="color: #000000; font-weight: bold;">extends</span> Zend_Mail<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @var string constant saying this a text type<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">const</span> TYPE_TEXT <span style="color: #339933;">=</span> <span style="color: #0000ff;">'text'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @var string constant saying this is html type<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">const</span> TYPE_HTML <span style="color: #339933;">=</span> <span style="color: #0000ff;">'html'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* This is used to make all of my e-mails utf-8 instead<br />
&nbsp; &nbsp; &nbsp;* @param string $charset<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &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;">$charset</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$charset</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Sets the type of body content<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* Sets the proper body content with the proper content, initializing view<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @param string $type the type of stuff<br />
&nbsp; &nbsp; &nbsp;* @param string $scriptname the name of the email script<br />
&nbsp; &nbsp; &nbsp;* @param array $params stuff to replace<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setBody<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span> <span style="color: #000088;">$scriptname</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$layout</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Layout<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'layoutPath'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getLayoutPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">case</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">TYPE_HTML</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">case</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">TYPE_TEXT</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$layout</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLayout</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'email'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">default</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Exception<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' type is not a valid body type'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$view</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_View<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setScriptPath</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getViewPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$layout</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">content</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$scriptname</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$type</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.phtml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$layout</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$func</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'setBody'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/ucwords"><span style="color: #990000;">ucwords</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$func</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* returns the layout path used in email formation<br />
&nbsp; &nbsp; &nbsp;* @return string path<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> _getLayoutPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/layouts/scripts'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* returns the view path used in email formation<br />
&nbsp; &nbsp; &nbsp;* @return string path<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> _getViewPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/views/scripts/email'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></table></div>

<p>Starting out the class, you&#8217;ll see I created it as a single class in a single file.  The first two docblocks just define what this file does and what the class goal is.  Next, the model extends the Zend_Mail class.  For the most part, all of the features are perfect in the Zend_Mail class for our goal.  </p>
<p>The two constants defined next will be used when determining the type of email body we&#8217;re currently working with.  The constant name makes it easy to determine what the constant is for.  The value is a normalized version of the &#8216;name&#8217; of our view or layout that we&#8217;ll be using later on.  It is important to note that views used later will be suffixed by the content of these constants.  For example, the layout for text emails will be called emailtext because &#8216;text&#8217; is the constant value.</p>
<p>The constructor defines the default charset.  Since all of my views are UTF-8, I felt it necessary to define this by default.</p>
<p>I&#8217;m going to skip the setBody() method and talk about the other two methods real quick.  You&#8217;ll notice that there are two methods called _getLayoutPath() and _getViewPath().  The reason these are methods unto themselves is to make this class easier for testing.  Since you generally don&#8217;t define a test suite inside of an application (view files aren&#8217;t testable code generally), the user input for this would always be randomly or non existent.  For our test suite, we can mock these two methods to point to locations where we keep assets for our tests so that we know the content of those files specifically.  An additional reason to use this is if you introduce themes into your Zend Framework project.  You may need to extend this class again to define where the theme&#8217;s view files are located (because they may not be in the default location).  </p>
<p>Finally, the setBody() call.  If you recall, the Zend_Mail class has both setBodyText and setBodyHtml methods.  Once again, we see the constant values defined earlier coming into more use.  This is more of a generic call because most of our code used to define the views is duplicate.  Let&#8217;s dissect:</p>
<p>First, create a new Zend_Layout object (this is of course assuming your project is using Layouts.  Let&#8217;s be honest, you more than likely are&#8230;).  Then, depending on the type that is passed into the setBody() command, it sets the layout as emailtext or emailhtml.  If neither type, it will throw an exception.</p>
<p>Next, create a new Zend_View instance.  This will retrieve the script from the $scriptname parameter combined with the view location defined in the _getViewPath() method.  Once this is created, each of the final parameter (the $params array) is applied to the view.  This is what is used to populate your view once rendered.  </p>
<p>Finally, the views and layouts are rendered and applied.  The setBody specific command is called then of the parent class with our rendered view-based content sent in as a parameter.</p>
<p>This is how you might use this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1012code12'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p101212"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1012code12"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$mail</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Application_Model_Mail<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #339933;">...</span><br />
<span style="color: #000088;">$mail</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setBody</span><span style="color: #009900;">&#40;</span>Application_Model_Mail<span style="color: #339933;">::</span><span style="color: #004000;">TYPE_HTML</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'forgotpassword'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setBody</span><span style="color: #009900;">&#40;</span>Application_Model_Mail<span style="color: #339933;">::</span><span style="color: #004000;">TYPE_TEXT</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'forgotpassword'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$mail</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>This would load the layout from <strong>APPLICATION_PATH/layouts/scripts/emailtext.phtml</strong> and <strong>APPLICATION_PATH/layouts/scripts/emailhtml.phtml</strong>.  Then, the views would be rendered from <strong>APPLICATION_PATH/views/scripts/email.forgotpasswordhtml.phtml</strong> and <strong>APPLICATION_PATH/views/scripts/email.forgotpasswordtext.phtml</strong>
<p><a href="http://aaronsaray.com/blog/2012/03/20/extend-zend_mail-to-use-views/">Extend Zend_Mail to use Views</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=ejMSLul8Q3E:T_AWGq6ENCs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=ejMSLul8Q3E:T_AWGq6ENCs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=ejMSLul8Q3E:T_AWGq6ENCs:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/ejMSLul8Q3E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/03/20/extend-zend_mail-to-use-views/</feedburner:origLink></item>
		<item>
		<title>Site Profile: name-tag.me</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/wM2LFPn-aao/</link>
		<comments>http://aaronsaray.com/blog/2012/03/14/site-profile-name-tag-me/#comments</comments>
		<pubDate>Wed, 14 Mar 2012 21:11:07 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[Misc Web Design]]></category>
		<category><![CDATA[site profile]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1086</guid>
		<description><![CDATA[Note: I have shut down name-tag.me. These notes were taken before I pulled the plug. The goal was to make a &#8220;hello my name is&#8221; style name tag without the use of images but with a handwritten font. Trouble I &#8230; <a href="http://aaronsaray.com/blog/2012/03/14/site-profile-name-tag-me/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/03/14/site-profile-name-tag-me/">Site Profile: name-tag.me</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p><strong>Note: I have shut down name-tag.me.  These notes were taken before I pulled the plug.</strong></p>
<p>The goal was to make a &#8220;hello my name is&#8221; style name tag without the use of images but with a handwritten font.  </p>
<p>Trouble I ran into:
nametag.me was already taken.  I had to use the dashed version because I couldn&#8217;t think of a different name.  hellomynameis.com was also taken.  This became a problem because repeat visitors and word-of-mouth tend to forget about the dash.  Plus, it is a lot harder to say: &#8220;name dash tag dot me.&#8221;  I also found out that the .me name, although popular, was still hard for people to remember.  A lot of .com visitors I&#8217;m sure.</p>
<p>Technical specifications:
Open Graph integration.
This is the first time that I used an apple-touch icon and an open graph image.  Since the only images on the site were my signature portion (and link to my main website) and share icons, that was the preview that showed up when you shared it on Facebook.  I added the meta property of og:image which pointed to the image.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1086code18'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p108618"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1086code18"><div class="html" style="font-family:monospace;">&lt;meta property=&quot;og:image&quot; content=&quot;http://name-tag.me/apple-touch-icon.png&quot;&gt;</div></td></tr></table></div>

<p>Mod_expires / mod_deflate</p>
<p>I also used mod_expires and mod_deflate to compress and cache images/css/javascript out for a year.  I also turned off ETags as I find that pretty annoying.  Here are entries from the apache config:</p>
<pre>
SetOutputFilter DEFLATE

ExpiresActive On

ExpiresByType image/png A31536000
ExpiresByType image/x-icon A31536000
ExpiresByType application/x-icon A31536000
ExpiresByType application/javascript A31536000
ExpiresByType application/x-javascript A31536000
ExpiresByType text/css A31536000

#turn off etags
FileETag none
</pre>
<p>Because of this too, I decided to &#8216;version&#8217; my css and javascript files.  At the time of writing, I had version 3 of css and version 2 of javascript.  Some people will add parameters at the end of the URLs but other caches/proxies can&#8217;t handle that properly.  So, I decided to actually just change the name of the file itself.  3.css and 2.js, say hello to the world!</p>
<p>Browser sniffing body tag.  
Because there were specific layout elements in place here (and they had to work exactly), I had to sniff browsers.  I did that with this famous line:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1086code19'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p108619"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1086code19"><div class="html" style="font-family:monospace;">&nbsp; &nbsp; &lt;!--[if lt IE 7 ]&gt; &lt;body class=&quot;ie6&quot;&gt; &lt;![endif]--&gt;<br />
&nbsp; &nbsp; &lt;!--[if IE 7 ]&gt; &nbsp; &nbsp;&lt;body class=&quot;ie7&quot;&gt; &lt;![endif]--&gt;<br />
&nbsp; &nbsp; &lt;!--[if IE 8 ]&gt; &nbsp; &nbsp;&lt;body class=&quot;ie8&quot;&gt; &lt;![endif]--&gt;<br />
&nbsp; &nbsp; &lt;!--[if IE 9 ]&gt; &nbsp; &nbsp;&lt;body class=&quot;ie9&quot;&gt; &lt;![endif]--&gt;<br />
&nbsp; &nbsp; &lt;!--[if (gt IE 9)|!(IE)]&gt;&lt;!--&gt; &lt;body&gt; &lt;!--&lt;![endif]--&gt;</div></td></tr></table></div>

<p>This was important because some browsers made the name tag misshapen so I had to change their CSS.</p>
<p>Whitespace
What I didn&#8217;t do here was remove whitespace from my HTML and CSS.  I have done that on other projects, but I just didn&#8217;t do that on this one.  It was only 1.21k (2.02k deflated).</p>
<p>Clipboard Integration
I ended up using a script called ZeroClipboard.  This was a javascript that worked cross browser using technologies like the built in clipboard access to flash objects to send the URL to the clipboard.</p>
<p>jQuery
Yup, used the google CDN.</p>
<p>Rounded corners
In order to get rounded corners, but with all browsers covered, I used jQuery Corners plugin.  I really wanted to use CSS border-radius but I also wanted this to work in IE&#8230; oh well.</p>
<p>TTF Font
I defined the font I wanted to use using a utility called FontSquirrel:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1086code20'); return false;">View Code</a> CSS</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p108620"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p1086code20"><div class="css" style="font-family:monospace;"><span style="color: #a1a100;">@font-face {</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">font-family</span><span style="color: #00AA00;">:</span> <span style="color: #ff0000;">'DesyrelRegular'</span><span style="color: #00AA00;">;</span><br />
&nbsp; &nbsp; src<span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'desyrel-webfont.eot'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span><br />
&nbsp; &nbsp; src<span style="color: #00AA00;">:</span> local<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'☺'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'desyrel-webfont.woff'</span><span style="color: #00AA00;">&#41;</span> format<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'woff'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'desyrel-webfont.ttf'</span><span style="color: #00AA00;">&#41;</span> format<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'truetype'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'desyrel-webfont.svg#webfontOicIDNk6'</span><span style="color: #00AA00;">&#41;</span> format<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'svg'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">normal</span><span style="color: #00AA00;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">font-style</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">normal</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></table></div>

<p>Then later, defiend it in the font-family declaration:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1086code21'); return false;">View Code</a> CSS</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p108621"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1086code21"><div class="css" style="font-family:monospace;">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">font-family</span><span style="color: #00AA00;">:</span> DesyrelRegular<span style="color: #00AA00;">,</span> tahoma<span style="color: #00AA00;">,</span> verdana<span style="color: #00AA00;">,</span> arial<span style="color: #00AA00;">,</span> <span style="color: #993333;">sans-serif</span><span style="color: #00AA00;">;</span></div></td></tr></table></div>

<p>Image Download
I was able to use the same ttf font in my image downloading.  I used imagettftext to position the items.  I then sent the following headers:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1086code22'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p108622"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1086code22"><div class="php" style="font-family:monospace;"><a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Cache-Control: public&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Description: File Transfer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Disposition: attachment; filename=&quot;Hello My Name Is.png&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Type: application/octet-stream&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Transfer-Encoding: binary&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>Lessons Learned
- Branding is important with the URL.  I think a lot of people didn&#8217;t get the dash in the name.
- Offering too much help, like click to copy to clipboard, is not worth it (Google analytics says that hardly anyone clicked that).
- Average time on site was under 5 seconds.  It&#8217;s unclear if people could use the functionality that quickly or if they just didn&#8217;t understand it and bounced.  I should have made action funnels on actually filling in the box.
- Check your userbase.  Turns out, I didn&#8217;t need to use jquery corners (of course I wouldn&#8217;t know that till now).  1% of my visitors were Internet Explorer over the lifetime of the site.</p>
<p>RIP Name-Tag.me!</p>
<p><em>Screenshots / Downloads</em></p>
<p><a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150408.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150408-150x150.png" alt="" title="Screenshot at 2012-03-14 15:04:08" width="150" height="150" class="alignnone size-thumbnail wp-image-1088" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150425.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150425-150x150.png" alt="" title="Screenshot at 2012-03-14 15:04:25" width="150" height="150" class="alignnone size-thumbnail wp-image-1089" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150450.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Screenshot-at-2012-03-14-150450-150x150.png" alt="" title="Screenshot at 2012-03-14 15:04:50" width="150" height="150" class="alignnone size-thumbnail wp-image-1090" /></a>
<a href="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Hello-My-Name-Is-Aaron.png"><img src="http://aaronsaray.com/wp/wp-content/uploads/2012/03/Hello-My-Name-Is-Aaron-150x150.png" alt="" title="Hello My Name Is Aaron" width="150" height="150" class="alignnone size-thumbnail wp-image-1087" /></a>
<p><a href="http://aaronsaray.com/blog/2012/03/14/site-profile-name-tag-me/">Site Profile: name-tag.me</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=wM2LFPn-aao:Ql-jg62apqc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=wM2LFPn-aao:Ql-jg62apqc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=wM2LFPn-aao:Ql-jg62apqc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/wM2LFPn-aao" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/03/14/site-profile-name-tag-me/</feedburner:origLink></item>
		<item>
		<title>Removing the extra elements on Zend_Form for Submit Button</title>
		<link>http://feedproxy.google.com/~r/aaronsaray/~3/bJG1_zVmwLQ/</link>
		<comments>http://aaronsaray.com/blog/2012/03/13/removing-the-extra-elements-on-zend_form-for-submit-button/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 14:12:38 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://aaronsaray.com/?p=1041</guid>
		<description><![CDATA[Have you ever used Zend Form, created a submit button, and had a few extra tags that were just throwing you off? I know you have&#8230; You probably did it like me: ?View Code PHP1 2 3 4 $this-&#62;addElement&#40;'submit', 'submitbutton', &#8230; <a href="http://aaronsaray.com/blog/2012/03/13/removing-the-extra-elements-on-zend_form-for-submit-button/">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://aaronsaray.com/blog/2012/03/13/removing-the-extra-elements-on-zend_form-for-submit-button/">Removing the extra elements on Zend_Form for Submit Button</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Have you ever used Zend Form, created a submit button, and had a few extra tags that were just throwing you off?  I know you have&#8230;  You probably did it like me:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1041code25'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p104125"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p1041code25"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'submit'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'submitbutton'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">'ignore'</span><span style="color: #339933;">=&gt;</span>true<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">'label'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Submit This'</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>But, you&#8217;ll notice you have both a DT and a DD from the standard view helpers of HtmlTag.  But, the DT usually contains the label attribute.  In this case, the label element is part of the input now.  It stead of being silly and using CSS to hide that empty DT, let&#8217;s just get rid of it&#8230; add the following to your code:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1041code26'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p104126"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1041code26"><div class="php" style="font-family:monospace;"><span style="color: #000088;">$element</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'submitbutton'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDecorators</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ViewHelper'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HtmlTag'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tag'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'dd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'id'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'-element'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></table></div>

<p>Simply, get the submit button you just added (you could technically add this in your definition of your initial element too&#8230;).  Then, reset the decorators to be the ViewHelper and the HtmlTag.  However, only define the DD tag instead of the full DD/DT suite.  Finally, set the id to the element&#8217;s name plus &#8216;-element&#8217; like the standard view does.</p>
<p>Good to go!</p>
<p><a href="http://aaronsaray.com/blog/2012/03/13/removing-the-extra-elements-on-zend_form-for-submit-button/">Removing the extra elements on Zend_Form for Submit Button</a> is a post from: <a href="http://aaronsaray.com">Aaron Saray</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronsaray?a=bJG1_zVmwLQ:iS7B4qV-v_4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronsaray?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronsaray?a=bJG1_zVmwLQ:iS7B4qV-v_4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/aaronsaray?i=bJG1_zVmwLQ:iS7B4qV-v_4:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronsaray/~4/bJG1_zVmwLQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss />
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://aaronsaray.com/blog/2012/03/13/removing-the-extra-elements-on-zend_form-for-submit-button/</feedburner:origLink></item>
	</channel>
</rss>

