<?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/" version="2.0">

<channel>
	<title>Stereo Interactive &amp; Design</title>
	
	<link>http://stereointeractive.com/blog</link>
	<description>Development Blog</description>
	<pubDate>Fri, 03 Jul 2009 19:32:31 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/stereointeractive" type="application/rss+xml" /><item>
		<title>Symfony: return javascript response</title>
		<link>http://stereointeractive.com/blog/2009/07/03/symfony-return-javascript-response/</link>
		<comments>http://stereointeractive.com/blog/2009/07/03/symfony-return-javascript-response/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 18:11:47 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=221</guid>
		<description><![CDATA[This is an old trick, but I still find it useful and will post it here in case it will help other symfony developers out there. If you are using the prototype.js library for your ajax requests, the Ajax.Request (and similar) utility methods will automatically evaluate the server&#8217;s response as javascript if the response has [...]]]></description>
			<content:encoded><![CDATA[<p>This is an old trick, but I still find it useful and will post it here in case it will help other symfony developers out there. If you are using the prototype.js library for your ajax requests, the Ajax.Request (and similar) utility methods will automatically evaluate the server&#8217;s response as javascript if the response has the &#8216;text/javascript&#8217; content-type header. <span id="more-221"></span>You can do this by setting your response headers like so:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="co1">// from within a template:</span>
sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getResponse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">setContentType</span><span class="br0">&#40;</span><span class="st_h">'text/javascript'</span><span class="br0">&#41;</span>;
&nbsp;
<span class="co1">// from your action</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getResponse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">setContentType</span><span class="br0">&#40;</span><span class="st_h">'text/javascript'</span><span class="br0">&#41;</span>;
&nbsp;
<span class="co1">// as an action that returns some javascript directly</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getResponse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">setContentType</span><span class="br0">&#40;</span><span class="st_h">'text/javascript'</span><span class="br0">&#41;</span>;
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">renderText</span><span class="br0">&#40;</span><span class="st0">&quot;alert('This is a javascript alert')&quot;</span><span class="br0">&#41;</span>;</pre></div></div>

<p>This proves useful when you want to open up a modal window, show an alert, update multiple areas on a page, or just about anything else with javascript returned from your ajax request.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/07/03/symfony-return-javascript-response/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Firebug and Firefox 3.5</title>
		<link>http://stereointeractive.com/blog/2009/07/01/firebug-and-firefox-35/</link>
		<comments>http://stereointeractive.com/blog/2009/07/01/firebug-and-firefox-35/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 23:30:49 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[css]]></category>

		<category><![CDATA[firebug]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=218</guid>
		<description><![CDATA[I rely on Firebug daily to help me debug javascript and work with css. After upgrading to Firefox 3.5, I updated Firebug to the latest beta release, Firebug 1.4 Beta.
The beta version is of course rough around the edges, and one rough spot is the fact that often when editing css properties of an element [...]]]></description>
			<content:encoded><![CDATA[<p>I rely on <a href="http://getfirebug.com">Firebug</a> daily to help me debug javascript and work with css. After upgrading to <a href="http://www.mozilla.com/en-US/firefox/upgrade.html">Firefox 3.5</a>, I updated Firebug to the latest beta release, Firebug 1.4 Beta.</p>
<p>The beta version is of course rough around the edges, and one rough spot is the fact that often when editing css properties of an element on an html page, the entire style definition would simply disappear from the console. </p>
<p>Fortunately, as of today, the <a href="http://getfirebug.com/releases/firebug/1.5X/">firebug-1.5X.0a07.xpi</a> release fixes the problem. Click the link for 1.5X0a07.xpi within Firefox to update. I haven&#8217;t found any serious problems with the alpha version yet.</p>
<p>As a side note, if any of you are Safari users or are just testing your sites out for safari, make sure you enable the development menu (Preferences > Advanced > Enable Develop Menu) and then you can use the command-option-i to show a Firebug-like inspector. It&#8217;s growing on me each time I use it.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/07/01/firebug-and-firefox-35/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Install/Upgrade Subversion on Mac OS X</title>
		<link>http://stereointeractive.com/blog/2009/05/05/installupgrade-subversion-on-mac-os-x/</link>
		<comments>http://stereointeractive.com/blog/2009/05/05/installupgrade-subversion-on-mac-os-x/#comments</comments>
		<pubDate>Tue, 05 May 2009 15:49:39 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=206</guid>
		<description><![CDATA[This is a great tutorial on SVN and it also includes a Intel disk image of SVN 1.6.1 which makes installing a breeze. 
Subversion With Mac OS X Tutorial.
]]></description>
			<content:encoded><![CDATA[<p>This is a great tutorial on SVN and it also includes a Intel disk image of SVN 1.6.1 which makes installing a breeze. </p>
<p><a href='http://www.rubyrobot.org/tutorial/subversion-with-mac-os-x'>Subversion With Mac OS X Tutorial</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/05/05/installupgrade-subversion-on-mac-os-x/feed/</wfw:commentRss>
		</item>
		<item>
		<title>symfony cache system: cache growing too large</title>
		<link>http://stereointeractive.com/blog/2009/04/10/symfony-cache-system-cache-growing-too-large/</link>
		<comments>http://stereointeractive.com/blog/2009/04/10/symfony-cache-system-cache-growing-too-large/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 17:56:27 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=193</guid>
		<description><![CDATA[Symfony has a really powerful cache mechanism, but if you turn it on and don&#8217;t configure it, it will cache one file for *every possible url*, and in the case of a dynamic site with thousands of pages, this grows to many gigabytes very fast. This is especially a problem if you have a dynamic [...]]]></description>
			<content:encoded><![CDATA[<p>Symfony has a really powerful cache mechanism, but if you turn it on and don&#8217;t configure it, it will cache one file for *every possible url*, and in the case of a dynamic site with thousands of pages, this grows to many gigabytes very fast. This is especially a problem if you have a dynamic search feature, and you have search-friendly URLS where you convert query parameters to /a/friendly/path/like/this. The number of unique paths that generate content on your site is literally infinite, since the URL can include anything the user types in the search box.<span id="more-193"></span></p>
<p>Changing the cache duration (or &#8220;expiration date&#8221;) doesn&#8217;t affect this issue, since there is no cron job that travels through the files and deletes old ones—rather, when symfony encounters a file that is older than the expiration date, it replaces it with a new one. But, you can (and will) end up with thousands of files in your cache, some of which may have been accessed only once and will sit there taking up precious space. </p>
<p>Instead, you have to be more specific about what you want symfony to cache and what you want it to ignore. I generally *turn off* the general cache (in frontend/config/cache.yml) and then go through and specify what partials I want to cache. This is useful because if you set &#8220;contextual: false&#8221; in your partial cache configuration, symfony will use the same partial across every page (say, a header or footer or a &#8220;what&#8217;s new&#8221; block) and will only store that file *once* regardless of the URL used to get to that page. Or, more specifically, it will cache that file once for every combination of parameters you pass into the partial, but we&#8217;ll get to the details in a minute.</p>
<p>As an example, in our main layout.php for our site, we use a partial for our navigation menu &#8212; we have a list of cities that is populated in the database, and there is no reason to fetch this every request. Let&#8217;s say this partial is in our app&#8217;s layout folder (ie not within a module context, but rather the &#8220;global&#8221; context) and is called _headerNav.php.</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;">    <span class="kw2">&lt;?php</span> include_partial<span class="br0">&#40;</span><span class="st_h">'global/headerNav'</span><span class="br0">&#41;</span> <span class="kw2">?&gt;</span></pre></div></div>

<p>We can tell symfony to use/cache this same partial regardless of the context (or &#8220;url&#8221; used to access this page). Since this is a global partial, the settings go inside app/frontend/config/cache.yml:</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">_searchTop:
  enabled:     on
  contextual:  false</pre></div></div>

<p>So now symfony will store this searchTop partial inside:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">cache<span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">env</span><span class="br0">&#93;</span><span class="sy0">/</span>template<span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">hostname</span><span class="br0">&#93;</span><span class="sy0">/</span>all<span class="sy0">/</span>sf_cache_partial<span class="sy0">/</span>global<span class="sy0">/</span>_searchTop.cache</pre></div></div>

<p>rather than</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">cache<span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">env</span><span class="br0">&#93;</span><span class="sy0">/</span>template<span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">hostname</span><span class="br0">&#93;</span><span class="sy0">/</span>all<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>your<span class="sy0">/</span>unique<span class="sy0">/</span>url<span class="sy0">/</span>that<span class="sy0">/</span>is<span class="sy0">/</span>different<span class="sy0">/</span>every<span class="sy0">/</span><span class="kw1">time</span><span class="sy0">/</span>_searchTop.cache</pre></div></div>

<p>Next up, say that rather than having the same exact partial for *every page*, you have a few different contexts&#8230; a few, but not one for every URL that may access that partial. A great example is a blog. Say you want to cache the partial that shows you a blog post summary. You use this partial on your home page, on the blog category page, and the search results page. Once you generate the partial for blog ID #2, you can use that partial on all of those pages. But, you don&#8217;t want to use the same exact cached partial for different blog posts, because that obviously wouldn&#8217;t work. So, you set the cache key:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="kw2">&lt;?php</span> include_partial<span class="br0">&#40;</span><span class="st_h">'blog/post_short'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'post'</span> <span class="sy0">=&gt;</span> <span class="re0">$post</span><span class="sy0">,</span> <span class="st_h">'sf_cache_key'</span><span class="sy0">=&gt;</span><span class="re0">$post</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw2">?&gt;</span></pre></div></div>

<p>This tells symfony to use the same cached partial everytime that sf_cache_key is the same. So, the cache directory&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">cache<span class="sy0">/</span><span class="br0">&#91;</span>app<span class="br0">&#93;</span><span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">env</span><span class="br0">&#93;</span><span class="sy0">/</span>template<span class="sy0">/</span><span class="br0">&#91;</span><span class="kw2">hostname</span><span class="br0">&#93;</span><span class="sy0">/</span>all<span class="sy0">/</span>sf_cache_partial<span class="sy0">/</span>blog<span class="sy0">/</span>_post_short<span class="sy0">/</span></pre></div></div>

<p>ends up containing only 1 file per blog post:</p>
<pre lang="bash"
  103.cache  63.cache  68.cache  74.cache  80.cache  85.cache  90.cache  95.cache
  104.cache  64.cache  69.cache  76.cache  81.cache  86.cache  91.cache  96.cache
</pre>
<p>.... where the cache file name is the sf_cache_key you set when you included the partial. Another nice thing about setting the sf_cache_key is that you can easily idenfity what cache file refers to what object. Otherwise, symfony generates a unique hash key for each cache file... and this can be a problem if you want to manually clear out specific cache files (you'll see this at the end).</p>
<p>If you do this enough then your massive cache which is storing cached files for every single URL that is used to access your site ends up being consolidated into the shared sf_cache_partial directory, which won't get nearly as large.</p>
<p>The trick is that you must set "contextual: false" for your partials... otherwise the partials end up being distributed across a directory structure that resembles the URL used to access the content.</p>
<p>The end goal is to keep you cache directory from being a million files large. This will *only* happen if you have sections of your pages that are **contextual** meaning that symfony will store them inside a directory structure that mirrors the URL that generated the cache in the first place. If you find that you still have lots of cache/.../path/to/your/unique/url/and/it/keeps/going then you should look inside those cache files to find out what is being saved there and either stop caching it, or try to figure out how you can move that into a shared cache file somewhere by setting a shared sf_cache_key.</p>
<p>A major problem with all this caching is that it gets really tough to keep track of what actions on the backend require you to clear out what cache on the frontend. In the case of the blog post, I want to clear out any cache for that particular post. This is what my Post::save() method looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="kw2">public</span> <span class="kw2">function</span> save<span class="br0">&#40;</span><span class="re0">$con</span> <span class="sy0">=</span> <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$return</span> <span class="sy0">=</span> parent<span class="sy0">::</span><span class="me2">save</span><span class="br0">&#40;</span><span class="re0">$con</span><span class="br0">&#41;</span>;
  <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">clearCache</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
  <span class="kw1">return</span> <span class="re0">$return</span>;
<span class="br0">&#125;</span>
&nbsp;
protected <span class="kw2">function</span> clearCache<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="kw1">if</span> <span class="br0">&#40;</span>sfConfig<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="st_h">'sf_cache'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="coMULTI">/* does not work cross app
    $cacheManager = sfContext::getInstance()-&gt;getViewCacheManager();
    $cacheManager-&gt;remove('@sf_cache_partial?module=blog&amp;action=_recentPosts&amp;sf_cache_key=1');
    $cacheManager-&gt;remove('@sf_cache_partial?module= blog&amp;action=_tagList&amp;sf_cache_key=1');
    $cacheManager-&gt;remove('@sf_cache_partial?module= blog&amp;action=_post_short&amp;sf_cache_key='.$this-&gt;getId());
    $cacheManager-&gt;remove('@sf_cache_partial?module=threeOneThird&amp;action=_headerUpdates&amp;sf_cache_key=1');
    $cacheManager-&gt;remove('blog/index');
    */</span>
    <span class="re0">$sf_root_cache_dir</span> <span class="sy0">=</span> sfConfig<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="st_h">'sf_root_cache_dir'</span><span class="br0">&#41;</span>;
    <span class="re0">$cache_dir</span> <span class="sy0">=</span> <span class="re0">$sf_root_cache_dir</span><span class="sy0">.</span><span class="st_h">'/frontend/*/template/*/all'</span>;
&nbsp;
    sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/sf_cache_partial/blog/_post_short/'</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st_h">'.cache'</span><span class="br0">&#41;</span>;
    sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/sf_cache_partial/blog/_tag_list/*'</span><span class="br0">&#41;</span>;
    sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/sf_cache_partial/blog/_recentPosts/*'</span><span class="br0">&#41;</span>;
    sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/sf_cache_partial/threeOneThird/_headerUpdates/*'</span><span class="br0">&#41;</span>;
    sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/third-word/index*'</span><span class="br0">&#41;</span>;
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getStrippedTitle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> 
      <span class="co1">//for some reason this doesn't work, perhaps due to cross app?</span>
      <span class="co1">//$cacheManager-&gt;remove('@blog_show?stripped_title='.$this-&gt;getStrippedTitle());</span>
      <span class="co1">// note this path is incorrect if no_script_name is off</span>
      sfToolkit<span class="sy0">::</span><span class="me2">clearGlob</span><span class="br0">&#40;</span><span class="re0">$cache_dir</span><span class="sy0">.</span><span class="st_h">'/third-word/read/'</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getStrippedTitle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st_h">'.cache'</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>In theory you are supposed to be able to rely on the cacheManager remove cache based on a pretty path like:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;">    <span class="re0">$cacheManager</span><span class="sy0">-&gt;</span><span class="me1">remove</span><span class="br0">&#40;</span><span class="st_h">'[module]/[action]'</span><span class="br0">&#41;</span>;</pre></div></div>

<p>or</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;">    <span class="re0">$cacheManager</span><span class="sy0">-&gt;</span><span class="me1">remove</span><span class="br0">&#40;</span><span class="st_h">'@sf_cache_partial?module=[myModule]&amp;action=_[partialName]&amp;sf_cache_key=1'</span><span class="br0">&#41;</span>;</pre></div></div>

<p>But, if you are clearing your cache across apps (backend actions are trying to clear frontend partials) this totally breaks down because the cacheManager does not understand the routing rules for the other application. So, you have to specify the files you want delete manually. This isn't so bad if you use sfToolkit to remove files using a file pattern.</p>
<p>This post has grown far too long! But hopefully it gives you some insight how you can best utilize the caching system to speed up your site without ending up with gigabytes of useless cache files. </p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/04/10/symfony-cache-system-cache-growing-too-large/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Symfony Propel Enum types</title>
		<link>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/</link>
		<comments>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 19:46:13 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Propel]]></category>

		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=210</guid>
		<description><![CDATA[Propel does not support enum column types in its schemas, since the enum type is not support across all database types. There are a few ways around this.
1) Use another table to list the enum options. Pros: most flexible. Works nicely within symfony. Cons: means more joins in your queries. 
2) Use enum anyway. You [...]]]></description>
			<content:encoded><![CDATA[<p>Propel does not support enum column types in its schemas, since the enum type is not support across all database types. There are a few ways around this.<span id="more-210"></span></p>
<p>1) Use another table to list the enum options. Pros: most flexible. Works nicely within symfony. Cons: means more joins in your queries. </p>
<p>2) Use enum anyway. You can add custom column types using a little known trick in your schema:</p>
<pre class="code" type="php">
status:
  id:
  name: { type: varchar, sqltype:enum, size: "'inactive','active'", default: inactive }
</pre>
<p>Pros: You get your enum. Cons: Not very portable, a bit of a hack.</p>
<p>3) Simulate an enum column using your model. I typically end up doing this for columns that have a finite number of defined options *that will not change*. Pros: Fast. Cons: Not as flexible as optino 1. Example:</p>
<pre class="code" type="php">

class UserProfilePeer extends BaseUserProfilePeer
{
  static protected $USER_TYPE_INTEGERS = array('student', 'supervisor', 'coordinator', 'researcher', 'admin');
  static protected $USER_TYPE_VALUES = null;

  /**
   * Returns a user type label from an index value.
   *
   * @param integer $index
   * @return string user type label
   * @author Scott Meves
   */
  static public function getUserTypeFromIndex($index)
  {
    return self::$USER_TYPE_INTEGERS[$index];
  }

  /**
   * Returns the user type index from a string value
   *
   * @param string $value
   * @return integer $index
   * @author Scott Meves
   */
  static public function getUserTypeFromValue($value)
  {
    if (!self::$USER_TYPE_VALUES)
    {
      self::$USER_TYPE_VALUES = array_flip(self::$USER_TYPE_INTEGERS);
    }

    $values = strtolower($value);

    if (!isset(self::$USER_TYPE_VALUES[$value]))
    {
      throw new PropelException(sprintf('User type cannot take "%s" as a value', $value));
    }

    return self::$USER_TYPE_VALUES[strtolower($value)];
  }

  public static function getUserTypeOptions()
  {
    return self::$USER_TYPE_INTEGERS;
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Symfony: How to render a partial from an action</title>
		<link>http://stereointeractive.com/blog/2009/03/11/symfony-how-to-render-a-partial-from-an-action/</link>
		<comments>http://stereointeractive.com/blog/2009/03/11/symfony-how-to-render-a-partial-from-an-action/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 06:55:27 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=177</guid>
		<description><![CDATA[If you ever find yourself wanting to return the contents of a partial as the entire response for an action, Symfony makes it possible. Using symfony partials with ajax, you have a lot of options of how you want to arrange your templates, but here I&#8217;ll show you what has worked best for me.
Oftentimes I [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever find yourself wanting to return the contents of a partial as the entire response for an action, Symfony makes it possible. Using symfony partials with ajax, you have a lot of options of how you want to arrange your templates, but here I&#8217;ll show you what has worked best for me.</p>
<p>Oftentimes I find myself wanting to return the contents of a partial as the entire response for an ajax request. I do this a lot when I am already using a partial in my template, and then I want to replace that section with the results of an ajax call. We already have a partial set up to display that content, so we might as well reuse it when we have to refresh that area with new content. <span id="more-177"></span></p>
<p>Imagine we have a page that presents a list of articles. In the right sidebar we&#8217;d like to feature a preview of the first article. We&#8217;d also like to allow a &#8220;quick look&#8221; for the other articles. Clicking on the quick look button should load a preview of the selected article in the right sidebar, replaced the default preview.</p>
<p>To do this, I set up a partial that contains the article preview. In the default list template (e.g. listSuccess.php) I include the partial along with the featured article.</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="kw2">&lt;?php</span> include_partial<span class="br0">&#40;</span><span class="st_h">'preview'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'article'</span><span class="sy0">=&gt;</span><span class="re0">$article</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw2">?&gt;</span></pre></div></div>

<p>Then, when someone clicks the quick look button, we want to make an ajax call that returns the new preview content with that particular article. Our action might look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="kw2">public</span> <span class="kw2">function</span> executeLoadPreview<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">article</span> <span class="sy0">=</span> ArticlePeer<span class="sy0">::</span><span class="me2">retrieveByPk</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getRequestParamer</span><span class="br0">&#40;</span><span class="st_h">'articleId'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></div></div>

<p>The most obvious thing to do now would be to set up a standard loadPreviewSuccess.php tempate and within that template simply include the partial just as you would normally.</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;">// loadPreviewSuccess.php
<span class="kw2">&lt;?php</span> include_partial<span class="br0">&#40;</span><span class="st_h">'preview'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'article'</span><span class="sy0">=&gt;</span><span class="re0">$article</span><span class="br0">&#41;</span> <span class="kw2">?&gt;</span></pre></div></div>

<p>This is totally fine, and you may like it, but there is another way to do it. We can just render the contents of the partial directly from our action. Here is what it looks like. (Note that I turn off the web debugging so that it doesn&#8217;t render within the ajax call!)</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span class="kw2">public</span> <span class="kw2">function</span> executeLoadPreview<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  sfConfig<span class="sy0">::</span><span class="me2">set</span><span class="br0">&#40;</span><span class="st_h">'sf_web_debug'</span><span class="sy0">,</span> <span class="kw2">false</span><span class="br0">&#41;</span>;
  sfLoader<span class="sy0">::</span><span class="me2">loadHelpers</span><span class="br0">&#40;</span><span class="st_h">'Partial'</span><span class="br0">&#41;</span>;
&nbsp;
  <span class="re0">$article</span> <span class="sy0">=</span> ArticlePeer<span class="sy0">::</span><span class="me2">retrieveByPk</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getRequestParamer</span><span class="br0">&#40;</span><span class="st_h">'articleId'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp;
  <span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">renderText</span><span class="br0">&#40;</span>get_partial<span class="br0">&#40;</span><span class="st_h">'preview'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'article'</span> <span class="sy0">=&gt;</span> <span class="re0">$article</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></div></div>

<p>Nice! </p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/03/11/symfony-how-to-render-a-partial-from-an-action/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Create zip archive from the command line</title>
		<link>http://stereointeractive.com/blog/2009/03/05/create-zip-archive-from-the-command-line/</link>
		<comments>http://stereointeractive.com/blog/2009/03/05/create-zip-archive-from-the-command-line/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 22:44:28 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[OS X]]></category>

		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=171</guid>
		<description><![CDATA[I never remember how to do this. I like doing it from the terminal better than the &#8220;Compress X Items&#8221; option in the finder, because the finder method will sometimes add hidden files like __MACOSX which I don&#8217;t like seeing floating around.
This is so simple, it&#8217;s stupid. 

zip [name of archive] [filepattern 1] [filepattern2] ...

So [...]]]></description>
			<content:encoded><![CDATA[<p>I never remember how to do this. I like doing it from the terminal better than the &#8220;Compress X Items&#8221; option in the finder, because the finder method will sometimes add hidden files like __MACOSX which I don&#8217;t like seeing floating around.</p>
<p>This is so simple, it&#8217;s stupid. <span id="more-171"></span></p>
<pre class="code" lang="bash">
zip [name of archive] [filepattern 1] [filepattern2] ...
</pre>
<p>So if you wanted to compress all of your PHP files from a directory:</p>
<pre class="code" lang="bash">
zip phpArchive.zip *.php
</pre>
<p>If you want to zip up all the files in the current directory, including files within directories, but still only include files that match a pattern:</p>
<pre class="code" lang="bash">
zip -r phpArchive.zip . -i \*.php
</pre>
<p>Now, if only I would do this often enough so I could remember it without wasting 5 minutes reading the man page.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/03/05/create-zip-archive-from-the-command-line/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Recursively delete .svn directories</title>
		<link>http://stereointeractive.com/blog/2009/02/17/recursively-delete-svn-directories/</link>
		<comments>http://stereointeractive.com/blog/2009/02/17/recursively-delete-svn-directories/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 21:32:44 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=164</guid>
		<description><![CDATA[This came in handy today when I copied a directory from another project and didn&#8217;t recognize that it was under version control in that project. Needless to say, my current project got very confused during an svn commit when it encountered this copied directory. To reconcile the situation, I had to recursively delete all of [...]]]></description>
			<content:encoded><![CDATA[<p>This came in handy today when I copied a directory from another project and didn&#8217;t recognize that it was under version control in that project. Needless to say, my current project got very confused during an svn commit when it encountered this copied directory. To reconcile the situation, I had to recursively delete all of the .svn directories from the copied directory, and then check it in as a fresh copy to the new project. <span id="more-164"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="kw2">find</span> . <span class="re5">-type</span> d <span class="re5">-name</span> .svn <span class="re5">-exec</span> <span class="kw2">rm</span> <span class="br0">&#123;</span><span class="br0">&#125;</span> \;</pre></div></div>

<p>Update 1: Thanks to <a href="http://wizardishungry.com">Jon</a> for this improved method!</p>
<p>Update 2: I have this in my notes too, but I don&#8217;t know enough about the shell to know which is better.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="kw2">find</span> . <span class="re5">-iname</span> <span class="st0">'.svn'</span> <span class="re5">-print0</span> | <span class="kw2">xargs</span> <span class="re5">-0</span> <span class="kw2">rm</span> <span class="re5">-rf</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/02/17/recursively-delete-svn-directories/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SVN merge trunk changes to your branch</title>
		<link>http://stereointeractive.com/blog/2009/02/17/svn-merge-trunk-changes-to-your-branch/</link>
		<comments>http://stereointeractive.com/blog/2009/02/17/svn-merge-trunk-changes-to-your-branch/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 17:43:59 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=157</guid>
		<description><![CDATA[I always have to look up the documentation on how to merge a whole SVN branch to another. Today there were bug fixes to trunk of my project that I wanted to port into my branch. I expected this to be easy since I hadn&#8217;t made many changes to my branch, and no changes to [...]]]></description>
			<content:encoded><![CDATA[<p>I always have to look up the documentation on how to merge a whole SVN branch to another. Today there were bug fixes to trunk of my project that I wanted to port into my branch. I expected this to be easy since I hadn&#8217;t made many changes to my branch, and no changes to the same files that were modified in the trunk.<span id="more-157"></span></p>
<p>Using <a href='http://svnbook.red-bean.com/en/1.4/svn.branchmerge.commonuses.html'>Common Use-Cases</a> as a reference, this is what I did:</p>
<p>From within my branch:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="kw2">svn</span> log</pre></div></div>

<p>This displays the revision number for when my branch was created:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="re5">------------------------------------------------------------------------</span>
r23 | stereosv | <span class="nu0">2009</span>-02-<span class="nu0">17</span> <span class="nu0">11</span>:<span class="nu0">42</span>:<span class="nu0">28</span> <span class="re5">-0500</span> <span class="br0">&#40;</span>Tue, <span class="nu0">17</span> Feb <span class="nu0">2009</span><span class="br0">&#41;</span> | <span class="nu0">1</span> line
&nbsp;
creating branch <span class="kw1">for</span> xyz</pre></div></div>

<p>Now I need to find out what revision number the trunk is at. Perfoming an &#8220;svn update&#8221; within the trunk shows me what version it&#8217;s at.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="sy0">&gt;</span> <span class="kw2">svn</span> update
At revision 25.</pre></div></div>

<p>In my case the trunk is at revision 25&#8230; implying there were only two commits since the time I checked out my branch. Nice.</p>
<p>Now, it&#8217;s time to carry merge these changes into my branch. Back in my branch directory, it&#8217;s time to put these revision numbers to good use.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="kw2">svn</span> merge <span class="re5">-r</span> <span class="nu0">23</span>:<span class="nu0">25</span> <span class="kw2">svn</span>+<span class="kw2">ssh</span>:<span class="sy0">//</span>username<span class="sy0">@</span>svnserver<span class="sy0">/</span>home<span class="sy0">/</span>username<span class="sy0">/</span><span class="kw2">svn</span><span class="sy0">/</span>project<span class="sy0">/</span>trunk</pre></div></div>

<p>What this does is merge the changes that were made between revision 23 (when I created my branch) and revision 25 (the most recent revision of the trunk) in the trunk into my working copy.</p>
<p>Now, it&#8217;s time to check in my branch, with the updated changes from the trunk.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span class="kw2">svn</span> ci <span class="re5">-m</span> <span class="st0">&quot;Merged trunk changes r23:25 into my branch&quot;</span></pre></div></div>

<p>SVN 1.5 has made some improvements to the way merging works.. So check your SVN version with &#8220;svn &#8211;version&#8221; to make sure you are using the right syntax for your version. </p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/02/17/svn-merge-trunk-changes-to-your-branch/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Symfony Cross Application Links</title>
		<link>http://stereointeractive.com/blog/2009/02/17/symfony-cross-application-links/</link>
		<comments>http://stereointeractive.com/blog/2009/02/17/symfony-cross-application-links/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 14:14:25 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=152</guid>
		<description><![CDATA[This blog post by Fabien Potencier describes how to use symfony 1.2 to create link between your applications within a symfony project. This has been difficult in the past because applications within a symfony project shared only model classes and basic project configuration, but routing was handled by unique application-based configuration. 
In symfony 1.2, there [...]]]></description>
			<content:encoded><![CDATA[<p>This blog post by Fabien Potencier describes how to use symfony 1.2 to create link between your applications within a symfony project. This has been difficult in the past because applications within a symfony project shared only model classes and basic project configuration, but routing was handled by unique application-based configuration. <span id="more-152"></span></p>
<p>In symfony 1.2, there is a new sfRoutingConfigHandler class that can be used to evaluate specific routing configuration (even if that configuration lives within another application), and you can pass that configuration class into a new sfPatternRouting::setRoutes() method which will then allow you to generate your routes.  Read the full details on the symfony project blog:</p>
<p><a href='http://www.symfony-project.org/blog/2009/02/17/cross-application-links'>Blog | Cross Application Links | symfony | Web PHP Framework</a>.</p>
<p>This is a great feature and it represents how making a framework more modular can bring many benefits and increase flexibility. </p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/02/17/symfony-cross-application-links/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
