<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Court Ewing</title>
  <link href="http://epixa.com/atom.xml" rel="self"/>
  <link href="http://epixa.com/"/>
  <updated>2014-02-12T17:02:52-05:00</updated>
  <id>http://epixa.com/</id>
  <author>
    <name>Court Ewing</name>
    <email>court@epixa.com</email>
  </author>

  
  
    <entry>
    <title>Pub Standards Lancaster</title>
    <link href="http://epixa.com/2013/02/pub-standards-lancaster.html"/>
    <id>/2013/02/pub-standards-lancaster</id>
    <updated>2013-02-11T17:00:00Z</updated>
    <content type="html"><![CDATA[<p>Pub Standards is a monthly meetup of developers, designers, founders and people-who-like-to-build-stuff.  The practice
began in London in 2005 and has since spread to other cities across the world. Starting <strong>March 14th</strong>,
<a href="http://pubstandards.us">Pub Standards Lancaster</a> begins meeting on the <strong>second Thursday</strong> of every month from
<strong>6pm</strong> onwards.</p>

<p>Nearly two years ago, <a href="https://twitter.com/eamonleonard">Eamon Leonard</a> convinced me to start a new Pub Standards
chapter in my hometown of Lancaster, PA. <a href="https://twitter.com/kapowaz">Ben Darlow</a> graciously customized a Pub Standards
beermat logo, I bought the pubstandards.us domain, and I started talking to my local network of developers.</p>

<p>Unfortunately, as I was actively trying to increase my presence on the web, I was simultaneously neglecting my budding
network of developers/designers in the Lancaster community, and the dream of a local Pub Standards died before it
really began.</p>

<p>That was until a few weeks ago, when I was inspired again to get this ball rolling by the urging of Eamon and an
awesome turn out of tech talent at a local party/meetup downtown in the <a href="http://www.theinfantree.com/">Infantree</a>
studio.</p>

<p>With a population of only 60,000 urban/500,000 metro, Lancaster is no doubt the smallest city with a Pub Standards
chapter, but its thriving arts community coupled with its wide range of design/dev shops and startups makes it the best
place in central PA for just such a meetup.</p>

<h2>For Lancaster web folk that are interested:</h2>

<p>We have not yet selected the bar in which Pub Standards will meet. Custom dictates that Pub Standards is to be held at
the same bar every month, so we definitely want to choose a pub that has great drinks, isn&#39;t so loud that we can&#39;t chat,
and that has enough space for a group every second Thursday at 6pm.</p>

<p>I imagine the upcoming Federal Taphouse would be a great option, but that likely will not be opening in time for the
first meetup.  Other bars under consideration are the Dispensing Company and the Spring House Taproom.</p>

<p>If you have any other pub suggestions or have a preference for one of these in particular, let me know
<a href="https://twitter.com/courtewing">@courtewing</a>.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Common, Cryptic PHP Errors</title>
    <link href="http://epixa.com/2012/04/common-cryptic-php-errors.html"/>
    <id>/2012/04/common-cryptic-php-errors</id>
    <updated>2012-04-30T17:00:00Z</updated>
    <content type="html"><![CDATA[<p>If you&#39;ve been programming for awhile, then you&#39;ve probably experienced your fair share of cryptic error messages.  It&#39;s understandable that building in detailed error messages that are clear to even novice developers is not always a high priority for programming languages when there are so many other features to create and issues to address.  The PHP language has decent error messages, but it is by no means an exception to this rule.</p>

<p>The following three error messages are as cryptic as they are common, but fortunately they are all easy to fix.</p>

<h2>Fatal error: Parse error: syntax error, unexpected T<em>PAAMAYIM</em>NEKUDOTAYIM in /path/to/index.php on line 48</h2>

<p>Paamayim Nekudotayim is hebrew for &quot;twice colon&quot;, and it is the term adopted by Andi Gutmans and Zeev Suraski when they wrote the Zend engine for PHP 3.  The more technical term for this is the <a href="http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php">Scope Resolution Operator</a>, and it is used for accessing static properties and methods on classes.  When you see this error, you are probably trying to access a static method or property on a non existent class name.</p>

<p>If you&#39;ve never experienced this error before, chances are it wouldn&#39;t take you too long to hunt down the problem.  Writer daleV from Greek Gumbo created <a href="http://www.geekgumbo.com/2011/01/30/paamayim-nekudotayim/">this</a> excellent write up detailing this particular bug last year.</p>

<h2>Fatal error: Can&#39;t use function return value in write context in /path/to/index.php on line 48</h2>

<p>This error is a little more insidious than T<em>PAAMAYIM</em>NEKUDOTAYIM since, without experiencing it before, you may not realize what the problem is with a given line of code even if you were staring straight at it.  This issue crops up when you try to pass the returned value from a function directly into either the isset() or empty() functions.  This is easily resolved by storing the returned value in a variable first, but it does seem a little inconsistent, especially for new developers that have no concept of a construct versus a built-in function.</p>

<p>At the time of this writing, there is actually an <a href="https://wiki.php.net/rfc/empty_isset_exprs">RFC</a> that is in the voting phase for inclusion into the PHP core that addresses this issue for the empty() function.  During the course of discussion about the RFC, it was decided that it was a bad idea to change this behavior for isset() as it is semantically confusing.</p>

<h2>Fatal error: Exception thrown without a stack frame in Unknown on line 0</h2>

<p>This is about as bad as error messages could possibly get as it requires you to have detailed knowledge about the technical implementation of the language for it to make any sense whatsoever.  Also, no matter where this error occurs in your application, the error message still says that it happened in file &quot;Unknown&quot; and on line &quot;0&quot;.</p>

<p>This error is triggered when any exception is thrown but not caught from within a class destructor (i.e. __destruct()).</p>

<p>When this happens, you do not really have many options other than hunting down the destructors in all of your objects to see which one may fail.  May I suggest: <code>grep --color -rn &quot;n __destruct&quot;</code> to help hunt down the issue in a linux terminal.</p>

<p><strong>Edit 2012-05-01:</strong> Larry Garfield has <a href="http://epixa.com/2012/04/common-cryptic-php-errors.html#comment-514728799">pointed out</a> that exceptions being thrown from inside a destructor is not the only way this error can be triggered.  The error is actually triggered any time an exception is thrown outside of the &quot;normal&quot; flow of a the program.  Another place that this could occur, for example, is when an exception is thrown from inside another exception.  Thanks Larry!</p>

<p>You can save yourself a whole lot of frustration in the future if you keep these three error messages in the back of your mind.</p>
]]></content>
  </entry>
  
  
  
  
  
  
  
  
    <entry>
    <title>Talk: Building Cloud-Ready Apps</title>
    <link href="http://epixa.com/2012/04/building-scalable-apps-talk.html"/>
    <id>/2012/04/building-scalable-apps-talk</id>
    <updated>2012-04-02T17:00:00Z</updated>
    <content type="html"><![CDATA[<p>In March 2012, the Singapore PHP User Group was running a lab entitled &quot;PHP In the Cloud&quot;.  I put this talk together for them on relatively short notice, but overall I think it turned out pretty well.</p>

<p>In the talk, I mention four things that you can do to help ensure that your app can scale horizontally in the cloud:</p>

<ol>
<li>Store your file uploads on an external file storage service such as Amazon S3.</li>
<li>Do not keep your database on the localhost.</li>
<li>Use an external memcache server or service for PHP session storage.</li>
<li>Keep your VCS repo lean.</li>
</ol>

<iframe src="http://player.vimeo.com/video/38895356" width="600" height="375" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>A New Paradigm Rises to Save the Modern Web</title>
    <link href="http://epixa.com/2012/04/array-oriented-programming.html"/>
    <id>/2012/04/array-oriented-programming</id>
    <updated>2012-04-01T17:00:00Z</updated>
    <content type="html"><![CDATA[<p>This was my April Fools day post for 2012.  To clarify a few things:</p>

<ul>
<li>As far as I know, array-oriented programming is not a thing.  I sure hope it never becomes a thing.</li>
<li>The code that I provided may have some cool components, but it is not good overall.  It is very inflexible and extremely fragile.  I broke it a half dozen times just trying to make simple changes, and it took me 10x longer to write than would be necessary in another coding style.</li>
<li>Verbosity should not be a goal of any paradigm.  If you choose to be verbose with your code, so be it.  Good paradigms, like object-oriented and functional programming, empower you to make that sort of decision yourself.</li>
<li>If you dig the usage of anonymous functions here, then I highly recommend that you try out some functional programming.  It is fun.</li>
<li>The new array syntax in PHP 5.4 is rad as hell.</li>
<li>No core developers were harmed in the making of this blog article.</li>
</ul>

<p>April Fools!</p>

<hr>

<p>Programming on the web has come a long way since the wild-west early days of the 90s, and nowhere has this been more evident than in the PHP community.  The earliest &quot;apps&quot; made with PHP were little more than some odd scripting bits that helped web pioneers and hobbyists to more easily maintain their HTML websites.  At the turn of the century, larger, procedural PHP apps started to pop up that would eventually change the web as we knew it.  Less than a decade later, the widespread adoption of object-oriented programming throughout most web development communities had led to some of the most sophisticated triumphs of software engineering (or hackery) in history.</p>

<p>But just as procedural coding proved insufficient for developing the types of applications that the consumers of the web demanded, the usefulness of object-oriented programming is rapidly reaching its limits.  Object-oriented programming ultimately results in highly complex, bloated, and inconsistent code bases that cannot sustain the growing demand they will no doubt receive.  Once an object-oriented app reaches a certain mass, those problems begin to create cracks in its very foundation.</p>

<p>To free us from these constraints, some look to new systems that boast event-driven, functional foundations such as node.js.  Communities behind these systems make bold claims about the impact they will have on the web of tomorrow, but while this approach certainly has its benefits, it suffers from the very huge obstacle of being completely incompatible with their existing app architectures. To truly revolutionize the web as a whole, a new system or paradigm must allow users to incrementally update their existing apps and workflows.</p>

<p>Fortunately, there is now a new paradigm that originated within the PHP community that is rapidly changing the way we develop web and mobile apps.  Array-oriented programming (AOP) combines all of the structure of object-oriented systems with the ease-of-use and efficiency that could exist in procedural apps, and it does so in a highly consistent way.  Best of all, it can be done in any programming language that supports arrays, and it can be used to build entirely new apps or even incrementally refactored into existing apps regardless of whether they were procedural or object-oriented to begin with.</p>

<p>Array-oriented programming is based on one driving principle, <em>an entire program structure and flow is defined as an array</em>.  It really is as simple as it sounds.</p>

<p>AOP is not a new concept, but it is just now gaining traction in the web development community.  There are countless articles scattered across the web that go into great detail about the technical intricacies of this revolutionary paradigm, so I won&#39;t bore you by driving in all of those same points.  Instead, let&#39;s take a look at a complete array-oriented program:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$app</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;session&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(),</span>
    <span class="s1">&#39;request&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
        <span class="s1">&#39;uri&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
        <span class="s1">&#39;data&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">()</span>
    <span class="p">),</span>
    <span class="s1">&#39;response&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;body&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
        <span class="s1">&#39;headers&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">()</span>
    <span class="p">),</span>
    <span class="s1">&#39;errors&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="mi">404</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$request</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$response</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;404 Not Found&#39;</span><span class="p">;</span>
            <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">][]</span> <span class="o">=</span> <span class="s1">&#39;Status: 404&#39;</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">),</span>
    <span class="s1">&#39;routes&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;GET /&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$request</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$response</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$session</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$name</span> <span class="o">=</span> <span class="nb">isset</span><span class="p">(</span><span class="nv">$session</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$session</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">:</span> <span class="s1">&#39;World&#39;</span><span class="p">;</span>
            <span class="nb">ob_start</span><span class="p">();</span>
            <span class="c1">// not shown, but your standard php template</span>
            <span class="k">include</span> <span class="s1">&#39;../template/home.phtml&#39;</span><span class="p">;</span>
            <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">ob_get_contents</span><span class="p">();</span>
            <span class="nb">ob_end_clean</span><span class="p">();</span>
        <span class="p">},</span>
        <span class="s1">&#39;POST /&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$request</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$response</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$session</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$request</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">]))</span> <span class="p">{</span>
                <span class="nv">$session</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$request</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">];</span>
            <span class="p">}</span>
            <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">][]</span> <span class="o">=</span> <span class="s1">&#39;Location: /&#39;</span><span class="p">;</span>
            <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">),</span>
    <span class="s1">&#39;route&#39;</span> <span class="o">=&gt;</span> <span class="k">null</span><span class="p">,</span>
    <span class="s1">&#39;bootstrap&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;session&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$app</span><span class="p">)</span> <span class="p">{</span>
            <span class="nb">session_start</span><span class="p">();</span>
            <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;session&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="o">&amp;</span><span class="nv">$_SESSION</span><span class="p">;</span>
        <span class="p">},</span>
        <span class="s1">&#39;request&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$app</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;REQUEST_METHOD&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;is_post&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;uri&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;/&#39;</span> <span class="o">.</span> <span class="nx">trim</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;REQUEST_URI&#39;</span><span class="p">],</span> <span class="s1">&#39;/&#39;</span><span class="p">);</span>
            <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;method&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">strtoupper</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;REQUEST_METHOD&#39;</span><span class="p">]);</span>
            <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;data&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$_REQUEST</span><span class="p">;</span>
        <span class="p">},</span>
        <span class="s1">&#39;router&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$app</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$route</span> <span class="o">=</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;method&#39;</span><span class="p">]</span> <span class="o">.</span> <span class="s1">&#39; &#39;</span> <span class="o">.</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">][</span><span class="s1">&#39;uri&#39;</span><span class="p">];</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;routes&#39;</span><span class="p">][</span><span class="nv">$route</span><span class="p">]))</span> <span class="p">{</span>
                <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;route&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;errors&#39;</span><span class="p">][</span><span class="mi">404</span><span class="p">];</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;route&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;routes&#39;</span><span class="p">][</span><span class="nv">$route</span><span class="p">];</span>
        <span class="p">}</span>
    <span class="p">),</span>
    <span class="s1">&#39;dispatch&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$app</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$route</span> <span class="o">=</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;route&#39;</span><span class="p">];</span>
        <span class="nv">$route</span><span class="p">(</span><span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">],</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">],</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;session&#39;</span><span class="p">]);</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;bootstrap&#39;</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$bootstrap</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$bootstrap</span><span class="p">(</span><span class="nv">$app</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;dispatch&#39;</span><span class="p">](</span><span class="nv">$app</span><span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">][</span><span class="s1">&#39;headers&#39;</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$header</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">header</span><span class="p">(</span><span class="nv">$header</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">][</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$app</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">][</span><span class="s1">&#39;body&#39;</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div>

<p>As you can see, this is essentially a &quot;Hello World&quot; app on steroids, and its structure -- which is completed defined in arrays, is flexible and intuitive.  This simple structure could be used to build both simple and complex apps alike.</p>

<p>At this point, I&#39;d like to answer some of the common questions that people have when they first stumble upon array-oriented programming.</p>

<h3>Q: Isn&#39;t this overly verbose?</h3>

<p>Can there be such a thing?  Way back in the day, there used to be a programming language called &quot;perl&quot; that was very succinct.  People tried to make simple programs with perl, but they found its succinctness to be far too inflexible for the demands of even the early web.  Fortunately for all of us, PHP did not evolve to emulate perl and instead evolved to emulate Java, and perl has since disappeared entirely.  As a result, PHP has curly braces so that servers do not get confused, and there is now the long-standing tradition of building ultra-architected application architectures regardless of the nature of the final product.  Array-oriented programming caters to that tradition.</p>

<h3>Q: Can we use the short array syntax from PHP 5.4?</h3>

<p>Of course you can!  But don&#39;t.  You see, there are still some rogue fans of the silly concept of succinct code that have voting rights for the PHP core.  We call these people &quot;perlites&quot; and they recently pushed forth that radically antiquated short array syntax.  The problem is, without the keyword &quot;array&quot; to indicate exactly what you&#39;re creating, it is difficult for both the developer and even the interpreter itself to figure out what you&#39;re trying to do.  It is best to stick with the more verbose, traditional array() syntax.</p>

<h3>Q: How is this better than object-oriented programming?</h3>

<p>The biggest problems with object-oriented programming is clarity and consistency.  What are objects?  Where do they exist?  What are they named?  Who creates them?  These fundamental questions are never completely answered in an object-oriented paradigm.  With array-oriented programming, everything is an array.  It doesn&#39;t get much more clear or consistent than that!</p>

<p>So there you have it.  Array-oriented programming is changing the face of modern software development, and it is not too late to get on board.  Its benefits are without question, and I&#39;m confident that once you start developing applications in the paradigm, you will wonder why you ever bothered to write programs any other way.</p>

<p>Hacker News: <a href="http://news.ycombinator.org/item?id=3783641">news.ycombinator.org/item?id=3783641</a></p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>2011: My Extraordinary Year in Review</title>
    <link href="http://epixa.com/2012/01/2011-an-extraordinary-year-in-review.html"/>
    <id>/2012/01/2011-an-extraordinary-year-in-review</id>
    <updated>2012-01-03T17:00:00Z</updated>
    <content type="html"><![CDATA[<p>Wow.  What a year.  I am sure that probably sounds a bit cheesy, but it is an honest sentiment.  A year ago today, I&#39;m sure I felt like 2011 was going to be productive, but I never would have imagined that the year would be defined by such profound personal and professional changes.</p>

<p>For the uninformed, I started working at <a href="http://echolibre.com">Echolibre</a> in June of the previous year, and it was my first telecommuting gig.  It took a few months to get completely accustomed to that type of workflow, so I guess you could say that I didn&#39;t really feel at &quot;home&quot; when actually working full-time out of my house until this year.  In February, I think I finally came into my own as a telecommuting developer, and I documented my tips for staying productive in my first <a href="http://epixa.com/2011/02/how-to-stay-productive-when-you-work-from-home.html">article</a> of the year.</p>

<p>In the meantime, <a href="http://twitter.com/davidcoallier">David Coallier</a>, <a href="http://twitter.com/eamonleonard">Eamon Leonard</a>, and <a href="http://twitter.com/h">Helgi Þormar Þorbjörnsson</a> had been planning and working on the then-secret <a href="http://orchestra.io">Orchestra</a> platform.  I was eager to cut my teeth on the project, but we were self-bootstrapping its development through the consultant work, so every minute any of us spent on the project was one less dollar we had to keep the project afloat.  Finally, I logged my first commit to Orchestra in March.</p>

<p>Early in the same month, a theme of blog articles started to spring up throughout the web.  In numerous &quot;Ideas of March&quot; posts, open source developers discussed the merits of knowledge sharing through traditional blogging rather than through social networks and micro-blogging services such as twitter.  This struck a chord with me as many of these authors had inspired me through their own blogs over the years.  I had been trying to think of a way to explain my feelings on the matter for some time, so I jumped on the bandwagon with my own plea to <a href="http://epixa.com/2011/03/ideas-of-march-think-about-the-little-guy.html">&quot;Think About the Little Guy&quot;</a>.</p>

<p>When May rolled around, it was time to launch the first of three new client applications on which I worked. <a href="http://redeemandget.com">Redeem&amp;Get</a> is an application that allows businesses to manage coupon campaigns and customers; it is designed to give businesses an easy way to honor online deals and to maximize the benefits associated with the influx of new customers.  At Echolibre, I managed the technical development of the project, from the very first line of code until the beta launch.</p>

<p>June marked another important client milestone at Echolibre as we helped to launch the <a href="http://rentview.com">RentView</a> beta.  RentView is the product of many months of hard work and over a decade of property management experience by its co-founders Colin Napper and Andreas Riha.  The application is the culmination of their grand vision: to make the process of managing rental properties clearer for letting agents, landlords, and tenants while dramatically cutting the usual wastes in time and money associated with managing and renting properties.  I joined the project after it was well underway, but I&#39;m happy to have managed it through its final months of development.</p>

<p>In late July and into August, I started playing around with <a href="http://symfony.com/">Symfony 2</a>.  It is a really impressive example of the power you can wield with all of the modern features of PHP 5.3 in a full-blown application framework.  For a few weeks, I was actually completely hooked, and I even thought about making the switch from Zend Framework permanent.  During that time, I wrote one of my initially-least successful blog articles about <a href="http://epixa.com/2011/08/create-and-validate-a-choice-list-in-a-symfony-2-form.html">choice lists</a> in Symfony 2 forms.  Despite its lackluster traffic at first, the article has surprisingly grown into one of the biggest traffic generators from search engines over the long term.</p>

<p>Where the choice list article has proven to be a long term traffic boon, my second article in August was by far my biggest initial traffic-draw.  More people visited <a href="http://epixa.com/2011/08/how-php-is-broken-and-how-it-can-be-fixed.html">&quot;How PHP is Broken and How it Can Be Fixed&quot;</a> in the first three days than had visited my entire site in the previous two months.  The responses in the comments, twitter, and google+ were numerous, and the discussion became heated.  Feeling that any positive critiques I may have about the PHP project were being overshadowed by the confrontational nature of the article, I decided to write a follow up to the article that would hopefully be more constructive.</p>

<p>August concluded with a bang when the <a href="http://blog.orchestra.io/post/9291203706/orchestra-engine-yard">news</a> broke that <a href="http://engineyard.com">Engine Yard</a> acquired Orchestra.  It is hard to quantify how big of an event this was for us.  We have an amazing team of developers that are entrenched in the open source and PHP communities, but Orchestra was only introduced in 2011 -- years after the Platform as a Service industry was pioneered.  Fortunately for us, Engine Yard was one such pioneer, and their experience and product are in a league of their own.  Together, all of the pieces started falling together, and as a result, Orchestra will truly shine in 2012 and beyond.</p>

<p>At this point, I wanted to start hacking away at the Orchestra platform, but we still had responsibilities at Echolibre.  I worked on our final project at Echolibre throughout September and into October: <a href="http://worldirish.com">WorldIrish</a> has the ambitious goal of compiling the definitive online catalog of the &quot;Irish Experience&quot; throughout the world.  Despite still being in beta, it has networked together more than 11,000 people who wish to share their own Irish stories, ideas, and experiences.</p>

<p>Three days after completing my work on WorldIrish, I was officially hired by Engine Yard to work full-time on the Orchestra platform.  I guess you could call this a &quot;dream come true&quot; moment for me.  Since then, I&#39;ve been spending most of my time within the web application and APIs that power the platform.  I wish I could talk about everything we&#39;re planning and/or working on because it is so damn cool.</p>

<p>As if October was not awesome enough, Elyse and I brought our month of October to an end with the purchase of our first house.  It was relatively unexpected, but it is beautiful, and it is home, and we love it.</p>

<p>Compared to October, November was largely uneventful.  I used this time to finally get back to something I promised weeks before; I wrote my <a href="http://epixa.com/2011/11/follow-up-how-php-is-broken-and-how-it-can-be-fixed.html">followup</a> to my &quot;How PHP is Broken and How it Can Be Fixed&quot; article.  The followup generated less traffic than its predecessor, but I think I did a much better job offering criticisms of the PHP project while attempting to explain some of the steps that are being taken for improvement as well as offering some practical suggestions to improve the process further.  It is what I wanted my original article to be, so I&#39;m more than happy with it.</p>

<p>As the year came to a close, I flew out to hang out with the team and see the new Orchestra offices on Barrow Street in Dublin, Ireland.  For the record, the offices are gorgeous.  While I do love working from home, the offices are cool enough that I am <em>almost</em> jealous of the crew that works out of Dublin.  They are still doing a lot of work on the space over there, but I&#39;m confident there will be a bunch of pictures posted of the joint when it is all finished.</p>

<p>In my final days in Ireland, when I sat in David Coallier&#39;s kitchen in front of the fireplace drinking hot port until god-knows-when, I was awestruck when I thought back to all of the things that happened in my life this year.  2011 was an extraordinary year for me, and I cannot wait to see what awesome things await in 2012.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Follow-up: How PHP is Broken and How It Can Be Fixed</title>
    <link href="http://epixa.com/2011/11/follow-up-how-php-is-broken-and-how-it-can-be-fixed.html"/>
    <id>http://epixa.com/?p=426</id>
    <updated>2011-11-14T22:53:46Z</updated>
    <content type="html"><![CDATA[<p>A few weeks ago I wrote an <a href="http://epixa.com/2011/08/how-php-is-broken-and-how-it-can-be-fixed.html">article</a> in which I complained about a few aspects of the PHP development process that I thought were inexcusable and harmful.  The article was surprisingly well-received with only a handful of people responding by demeaning me; given the nature of the article, I&#39;d say that is a big win!  The generally positive response does not make up for the flaws in the article itself, however.  You see, I started out writing the article with the serious intention of making not only an honest critique but also providing some practical feedback for how the process could be improved.  I feel my critique was completely honest, but I failed spectacularly in my second goal, and any merit that the article had was overshadowed by its negative tone.</p>

<p>It is no secret that the PHP development process has never been a shining example of project organization or quality assurance.  Until recently, some of the most important aspects of any project&#39;s development cycle were either entirely lacking or were ill-defined.  Worse, there was little in the form of systemic quality assurance.  Fortunately, the core devs did not ignore these issues, and they&#39;ve been pushing really hard to improve on these areas over the past few years:  They&#39;ve created a new <a href="https://wiki.php.net/rfc/releaseprocess">release process</a>, a new <a href="https://wiki.php.net/rfc/voting">voting procedure</a>, and have been building up the automated <a href="http://gcov.php.net/PHP_5_4/lcov_html">test coverage</a>.  They&#39;re shaping the development process into a more open, clear, and modern process that the whole community can be proud of.</p>

<p>This type of transformation takes time, however, and they are not at the finish line yet.  There are specific characteristics of the development team and process that are still very much a huge problem today.  An acceptance of failing unit tests along with a lack of an automated release process that incorporates testing requirements resulted in the recent disaster that was the PHP 5.3.7 release.  A lack of clear responsibilities continues to disrupt developer trust in the PHP project.  Insufficient means of communication and insufficient use of those means frequently keeps the large number of non-contributing PHP developers in the dark.  I&#39;ll address each of these individually for clarity sake:</p>

<h2>Automated tests are ineffective if failures are acceptable</h2>

<p>So much progress has been made in recent years with the PHP test suite -- the coverage for PHP 5.3 is at 70%.  Obviously this isn&#39;t ideal, but PHP is a massive project, so it is understandable that it takes some serious time to build the testing suite toward 100% coverage.  The big problem with the automated PHP tests is not that there are not enough but rather that it is not a requirement that tests pass.  To make matters worse, it does not appear that new code is required to have significant test coverage either.  At the time of this writing, there are 128 failing unit tests in PHP 5.3 (the current stable branch), and there are 129 failing unit tests in PHP 5.4.  There is actually a small decrease in test coverage between the two versions as well (70.2% in 5.3 vs 70.0% in 5.4); I&#39;m not sure whether this is the result of existing tests being removed or new code being committed without corresponding tests, but it is definitely not a trend that should continue.</p>

<p>The consequences of accepting failing tests were never more apparent than with the stable release of PHP 5.3.7.  The details of which have been outlined numerous times all over the place (including in my last post), but the gist is that a serious bug that broke a common security component was introduced into the PHP repository, the automated tests actually identified that the bug existed, but the release happened anyway.  There has been no official explanation for how this happened, but it appears to be the result of an unfortunate human error.  At the time there were close to 200 tests failing, so it seems reasonable to assume that a human may have missed that one of those failed tests was actually due to a severe issue.</p>

<p>There are a couple things that could be done in order to solve this problem.  Defining a coverage goal would be an excellent starting point.  Ideally this goal would be 100%, but any goal above 80% would likely be a huge step in the right direction.  Once a sufficient coverage goal has been defined, all new features committed to the HEAD should be required to have corresponding tests that match or exceed the coverage goal.  Unless existing tests are removed, this will ensure that the test coverage can only increase over time.  In addition, all current automated tests should run successfully.  There appears to be an effort to identify which tests should be expected to fail, but that only partly addresses the problem.  If a test is no longer applicable for some reason, then it should be removed.  If it is applicable, then a bug exists that needs to be addressed.</p>

<p>The coverage goal and a requirement that all new commits need to exceed that goal can be done within the existing development process.  Those are the easy parts of the issue to address.  The more difficult issue is resolving the errors from the existing tests.  Theoretically, more contributors could help a lot here; some of the failing tests probably belong to components that no longer have active maintainers, so the currently active core developers may not be the best to address the issue.  Realistically, the hardest contributors to find are those that are comfortable writing C, and this is also the most difficult type of contribution to make when you&#39;re not already involved in the project.  Resolving all of the failing tests will no doubt require both an increased effort by the existing core developers as well as an increase in the number of contributors.</p>

<h2>Developer trust is shaken due to lack of communication</h2>

<p>The developers managing the PHP project are only human, so mistakes are not only reasonable but also inevitable.  The community (none more so than myself) needs to accept that fact and remember this when reacting to future mistakes.  Nonetheless, incidents such as the failed release of 5.3.7 have shaken the trust that many community members place in the core developers to manage the project in a professional and stable way, and as a result there is a whole lot of mudslinging that happens when a mistake occurs.</p>

<p>Communication is the key, here.  In my opinion, the worst single part of the release of PHP 5.3.7 was not the human error in deployment but rather a breakdown in sufficient communication.  The two official means for people to follow important PHP announcements are the php.announce mailing list and the main news feed on the homepage of PHP.net.  We are rapidly approaching 2012, but PHP has no developer blog much less an official social networking account (e.g. Twitter, Google+) to follow for technical updates.</p>

<p>The php.announce mailing list used to include security advisories in addition to releases, but this appeared to stop long ago.  The announcement mailing list really should include all new releases, security advisories, and notices of unstable releases (e.g. 5.3.7).  This should allow any one of the core developers to immediately draw attention to any stability-related/critical issues to anyone subscribed to the list.  After 5.3.7 was released, it took four days for any official word to come down the chute that a problem existed.  In that time, any number of people could have upgraded their production environments to the broken release, and it didn&#39;t have to play out that way!  At least two core developers jumped on and fixed the issue the next day after release.  That&#39;s pretty damn good turn-around.  Unfortunately, it was still three days before an official notice was posted and a total of five days before a new release fixed the issue.  In this case, a swift reaction from core developers was overshadowed by less-than-ideal communication, and that is truly a shame.</p>

<p>It would be nice to see an official development blog for PHP where any of the core developers could post articles about features that are being worked on and, more importantly, post-mortems for when things go to crap (again, 5.3.7).  I know the core PHP developers didn&#39;t just brush 5.3.7 away from their minds the moment it happened.  I know this because since then the number of failing unit tests has plummeted.  I know this because I&#39;ve been personally assured by a few core developers that measures are being taken to make sure similar problems do not happen for future releases.  I do <em>not</em> know this based on any form of official communication from those managing the PHP project, and that is unfortunate.</p>

<p>We, the community, know that the core developers are working.  We know that they&#39;re trying hard to make sure the core is stable.  We know that they are introducing cool new features to help keep PHP competitive and modern.  But we know all of this only because we&#39;ve heard it through the grapevine.  A developer blog would allow the core developers to speak, on their own terms, about failures that happen and what steps they&#39;re taking to avoid them.  This is frequently all that is required to turn a horribly unfortunate situation into a positive experience for the community as a whole.  If ever you needed a better example of that, compare the reactions from people losing their accounts and credit card information to Sony versus people losing their accounts and credit card information to Valve.  For the former, the near-universal response was outrage.  For the latter, most people responded positively.  The gaming community did not rip Valve a new one because Valve did an excellent job communicating with them.  Despite overwhelming failure, the community <em>trusts</em> Valve due to little more than communication alone.</p>

<p>Also, the features the core developers are working on are pretty damn sweet, so it definitely would be awesome to hear more from them about those ongoing pieces of development.  I don&#39;t know if it would help on the &quot;trust&quot; front, but it would be awesome.</p>

<h2>PHP itself is not broken; my title is sensational rubbish</h2>

<p>I preserved the title from the previous article so that people can quickly make the connection between the two, but the original title really does not reflect my thoughts on the matter.</p>

<p>The PHP community is doing really awesome things.  From extraordinary second generation frameworks down to one-click install applications that have unparalleled portability, the extent to which we lead the web is still amazing and humbling to me.  The core PHP developers have long been a key component of that, and none of progress that modern PHP applications have made would be possible without their ongoing efforts.  As a result of those efforts, PHP is a stable, secure, and beautifully-practical language that is both easy for novices to wrap their heads around and experts to build the most-used web applications the world has ever seen.  PHP is not broken, but there are areas that can definitely be improved.  Fixing unit tests and polishing methods of communication should seem minor in comparison to the monumental accomplishments of the past 15 years.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>How PHP is Broken and How It Can Be Fixed</title>
    <link href="http://epixa.com/2011/08/how-php-is-broken-and-how-it-can-be-fixed.html"/>
    <id>http://epixa.com/?p=386</id>
    <updated>2011-08-31T15:49:05Z</updated>
    <content type="html"><![CDATA[<p><strong>Edit (Nov 14 2011 6:03pm)</strong> The follow-up article is posted <a href="http://epixa.com/2011/11/follow-up-how-php-is-broken-and-how-it-can-be-fixed.html">here</a>.</p>

<p><strong>Edit (Aug 31 2011 8:05pm):</strong> When I started writing this article, my intentions were to criticize the PHP core developers for what I consider to be a severely broken process.  I do want to make that clear.  As a member of the community and a long-time PHP programmer, I find it indescribably irritating that a failure as significant as the release of PHP 5.3.7 could happen without the dev team at least backing up the release of PHP 5.3.8 with an analysis of exactly what happened and exactly what measures were being considered so that it never happened again.  The problem here is not that a human made an error, the problem is that there were no measures in place to stop that error from happening, and so far there hasn&#39;t been (or I haven&#39;t seen) an official explanation of what measures will be put in place.</p>

<p>My irritation aside, this blog article does not do a good job identifying exactly what part of the process is broken, and it does an even worse job presenting practical solutions.  The tone I set from the start of the article is more that of an offended user than someone interested in finding solutions, and it is certainly not inline with my original intentions.  The core devs are no doubt responsible for the process in which they work, but they are also the group of people that will ultimately fix this problem.</p>

<p>I will be writing a follow-up to this article in the coming days that will hopefully address the concerns I have about PHP&#39;s development process without so much visceral rhetoric.  Blog articles are a great way to present ideas to the public, but they are not a means to really enact change, so if I think my ideas can make a difference for the better, I will bring them to the PHP internals mailing list as well.</p>

<hr>

<p>PHP&#39;s development process has been broken for a long time, and the failures of that process have swelled since the first ripples began to appear many years ago.  The process didn&#39;t necessarily take a downward turn at any point; rather, it seems there was never really a sufficient or sustainable workflow from the start.  This is no surprise given the very fluid history of PHP though, and the lack of any sustainable processes may have even been one of the key things that allowed PHP to evolve so quickly into one of the most used programming languages in the world.  But that early success doesn&#39;t make the PHP development process any less broken.</p>

<p>Before I continue, I want to be perfectly clear: There are many reasons that people bring up for disliking PHP, and I will not be entertaining most of them here.  If you do not like PHP because of things such as an inconsistent API, seemingly half-hearted additions (e.g. object model or namespace support), or any of the other language-specific beefs that spring up whenever someone leaps on their e-soapbox, please move along.  This isn&#39;t the post for you.  All things considered, I like PHP, and I think it is the best option for developing most of the applications that we see on the web today.</p>

<h2>How PHP is Broken</h2>

<p>The serious problems -- the ones that actually have long-term consequences, stem from the development process.</p>

<p>Through most of PHP&#39;s 16 year lifespan, it had a completely arbitrary release process.  When core devs felt like they wanted to push a release, they got together, patched up some of the code that had been contributed for the many weeks, months, or years since the previous release, and tossed it out into the wild.  The consequences of this still linger throughout the community (and the entire web) today: without any clear release planning, it was more efficient for organizations to leave their PHP versions un-upgraded than it was to incrementally upgrade their versions in a timely manner.</p>

<p>In addition to no sensible release cycle, the way new features were discussed, approved, or rejected was largely informal, difficult to follow, and without any sufficient time constraints.  It was hard for anyone that didn&#39;t follow the mailing list and wiki word for word, every day to have much of any idea about what was going on.</p>

<p>PHP&#39;s test coverage is not good.  To make matters worse, passing the existing unit tests is <strong>not a requirement for acceptance</strong> in the core.  Why even write the unit tests if someone can simply choose to ignore them when merging in their code?  This has to be the type of thing that <a href="http://sebastian-bergmann.de">Sebastian Bergmann</a> has nightmares about.</p>

<p>Don&#39;t worry though, just because it is acceptable to commit code that breaks the unit tests doesn&#39;t mean that this will actually affect the stability of the releases, right?  I mean, the <strong>stable</strong> releases of PHP at least pass the tests that they do have, right? <strong>Wrong</strong>.  Surely you&#39;ve all heard about the fiasco that was the PHP 5.3.7 release, but just in case you need a quick refresher:</p>

<p>Eleven days ago, PHP 5.3.7 was <a href="http://www.php.net/archive/2011.php#id2011-08-18-1">released</a> as stable.  One day <strong>prior</strong> to the release, a major bug was <a href="https://bugs.php.net/bug.php?id=55439">reported</a> that identified an issue where using crypt() with md5 hashes was broken so badly that it was completely unusable across all platforms.  Four days after the stable release, PHP.net finally got around to officially <a href="http://www.php.net/archive/2011.php#id2011-08-22-1">announcing</a> the problem and a day after that they released PHP 5.3.8 with a fix.  To their credit, many of the core devs did get the <a href="https://plus.google.com/113641248237520845183/posts/g68d9RvRA1i">word</a> <a href="https://plus.google.com/104059770182664001692/posts/fYqq8HGHF8h">out</a> about this issue very quickly, but why it took four days to officially acknowledge the problem is completely beyond me.</p>

<p>The delay in an official acknowledgement of this issue is certainly disturbing, but here&#39;s the kicker: Even at only 70% code coverage, this bug <strong>was</strong> identified by the unit tests.  The tests that were in place to make sure that bugs like this couldn&#39;t happen did their jobs -- they failed when they were suppose to fail.  Without any automatic testing constraints in place for packaging releases, those failures went unnoticed, and a &quot;stable&quot; release of PHP with an application-breaking bug was released to the masses.  For this to happen, one of two things had to occur: someone released a stable version without running tests on newly added code, or, more likely, someone didn&#39;t notice that there was a really important test failing because <strong>PHP 5.3 has <a href="http://gcov.php.net/viewer.php?version=PHP_5_3">192 failing unit tests</a></strong>!  What on earth is the point of writing unit tests when you consider it OK that some of the tests fail?  The acceptance of these failures is perhaps the most backward-thinking decision that I have ever seen the PHP dev team make.</p>

<h2>How This Can Be Fixed</h2>

<p>PHP has made huge progress in recent months in getting its development process into an acceptable state.  There is finally a detailed <a href="https://wiki.php.net/rfc/releaseprocess">release process</a> in place, so we know when to expect new code.  There is finally a simple and visible <a href="https://wiki.php.net/rfc/voting">voting process</a> on new feature proposals, so we know what to expect in those upcoming releases.  If the release of 5.3.7 is one of the worst blunders by the PHP dev team ever, then I&#39;d say the addition of these two processes into the overall workflow is perhaps the single greatest decision they have ever made.  Only in time will we be able to see what affect these two additions will have, but already the community is seeing clearer communications and expectations when dealing with proposals and releases.</p>

<p>Stop breaking tests.  Stop it.  Just, stop.  The argument that is immediately brought up whenever someone like me talks about an issue like this is along the lines of &quot;nothing is stopping you from contributing&quot;, but that isn&#39;t at all relevant here.  Perhaps this argument would carry some weight if you were just considering the mountain of test failures that exist from the past, but that isn&#39;t all we&#39;re considering.  PHP 5.4 has 26 <strong>more</strong> failed unit tests than PHP 5.3, and PHP HEAD has more still.  Stop accepting code that isn&#39;t unit tested or that breaks existing tests.</p>

<p>Fix the broken tests.  I know I just said that maybe you could argue for more contributors in this case, but really that is only one side of the coin.  As a PHP user, it is <strong>not</strong> my responsibility to contribute to PHP.  That&#39;s not how open source works, and it never will be how open source works.  But as a user of the software, I <strong>can</strong> be upset when it <strong>doesn&#39;t work</strong>.  I can be even more upset when it doesn&#39;t work due almost entirely to human negligence.</p>

<p>As core developers, you <strong>do</strong> have a responsibility to personally write good code and to, as a group, manage the project in a responsible manner.  If you do both of these things -- if you do things like writing well-tested code and don&#39;t accept bush league crap like untested code (or worse, code that actually breaks tests), then I will be the first one to step to your defense whenever people get on your back.</p>

<h2>More Contributors is Not the Solution</h2>

<p>Throwing new contributors at the project will not fix these problems.  If you want to expand the test coverage, improve the documentation, or do anything else that makes PHP better, then new contributors are the way to go.  However, falling back on cavalier attitudes like the ones behind the statement &quot;nothing is stopping you from contributing&quot; is both insulting and counter-productive.  It does absolutely nothing but decrease peoples&#39; desire to contribute even more.  As core developers, fixing the mistakes in the core development is your responsibility.  Just because you are volunteering your time doesn&#39;t make this any less your responsibility.  Volunteering is the act of taking on responsibilities at no cost, and that is something you chose to do.  So, unless you&#39;re throwing in the towel and walking away from the project, don&#39;t insult the community by trying to offload your responsibilities (and failures) on us.</p>

<p>Also, stop it with stupid reactions like <a href="http://twitter.com/PierreJoye/status/105690441105682432" title="Tweet says: Do not blame anyone if you did not run tests and report issues using RCs. Do not.">this</a> (Sorry to single you out, Pierre. You are certainly not the only one with this attitude).  If you are a core developer that helps to write and manage a project that powers websites and applications for billions of combined users, you don&#39;t get the luxury of demanding that people remain silent when your team makes an absolutely egregious mistake like the PHP 5.3.7 release just because those people didn&#39;t help you identify a mistake that your own processes <strong>should</strong> have identified.  Next time we moan about features taking too much time to develop, feel free to play the &quot;contribute or stfu&quot; card.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Create and Validate a Choice List in a Symfony 2 Form</title>
    <link href="http://epixa.com/2011/08/create-and-validate-a-choice-list-in-a-symfony-2-form.html"/>
    <id>http://epixa.com/?p=359</id>
    <updated>2011-08-16T19:00:56Z</updated>
    <content type="html"><![CDATA[<p>There is a lot of magic going on in the Symfony 2 form component, and while this magic is frequently convenient and borderline awe-inspiring, it sometimes has the unpleasant side effect of making it unclear how to do more fine-grained tasks within the form.  A standard select list can be created using Symfony&#39;s <a href="http://symfony.com/doc/current/reference/forms/types/choice.html">choice</a> field type; it is pretty clear how to create a new choice field with simple, non-dynamic options (e.g. gender), but it gets a little more complicated when you want to create and validate a dynamically generated choice list.</p>

<p>When creating your choice field, you can specify which options are available by either passing an array of options (&quot;choices&quot;) or by passing a custom object that implements \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface (&quot;choice_list&quot;).  For this article, I will be focussing on the latter, but this can all be very easily adapted to a simple choices array.</p>

<h2>Choice Lists and Doctrine 2 Entities</h2>

<p>If the model that you bind to your form type is a doctrine 2 entity, then chances are the vast majority of your choice field&#39;s form logic will be taken care of for you.  If you add a form field that matches an entity property that has an association to another entity, then Symfony guesses the correct form field type, retrieves the form field options, and even validates your input to make sure it is a valid option.  It is, for the lack of a better term, awesome:</p>

<p>We&#39;ll need an entity:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Entity</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Doctrine\\ORM\\Mapping</span> <span class="k">as</span> <span class="nx">ORM</span><span class="p">;</span>

<span class="sd">/**</span>
<span class="sd"> * @ORM\\Entity</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Post</span>
<span class="p">{</span>
    <span class="c1">// ... other post properties</span>

    <span class="sd">/**</span>
<span class="sd">     * @ORM\\ManyToOne(targetEntity=&quot;Epixa\\Entity\\Category&quot;)</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$category</span><span class="p">;</span>

    <span class="c1">// ... appropriate getters an setters</span>
<span class="p">}</span>
</code></pre></div>

<p>We&#39;ll also need a form type:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Form\\Type</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Symfony\\Component\\Form\\AbstractType</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\FormBuilder</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">PostType</span> <span class="k">extends</span> <span class="nx">AbstractType</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">buildForm</span><span class="p">(</span><span class="nx">FormBuilder</span> <span class="nv">$builder</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$options</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// ... add other appropriate form fields</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="s1">&#39;category&#39;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getDefaultOptions</span><span class="p">(</span><span class="k">array</span> <span class="nv">$options</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">array</span><span class="p">(</span>
            <span class="s1">&#39;data_class&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Epixa\\Entity\\Post&#39;</span>
        <span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="s1">&#39;epixa_post&#39;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>Tie it all together with your action:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">public</span> <span class="k">function</span> <span class="nf">addAction</span><span class="p">(</span><span class="nv">$topicId</span><span class="p">,</span> <span class="nx">Request</span> <span class="nv">$request</span><span class="p">)</span>
<span class="p">{</span>
    <span class="nv">$post</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\\Epixa\\Entity\\Post</span><span class="p">(</span><span class="nv">$topic</span><span class="p">);</span>

    <span class="nv">$form</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">createForm</span><span class="p">(</span><span class="k">new</span> <span class="nx">\\Epixa\\Form\\Type\\PostType</span><span class="p">(),</span> <span class="nv">$post</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getMethod</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">bindRequest</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="nv">$form</span><span class="o">-&gt;</span><span class="na">isValid</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ... persist the $post in the db and redirect away</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;form&#39;</span> <span class="o">=&gt;</span> <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">createView</span><span class="p">()</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<p>With that code in place, your form will have a select field that lists all categories as options, and validation will ensure that not only is a category provided but also that the category is one of the available options.  <em>Note: your category entity will need to have a __toString() method defined as this is used as the human-readable component of a select option.</em></p>

<h2>Creating and Validating Non-Entity Models</h2>

<p>Sometimes it is necessary to use a model in your form type that is not itself a Doctrine entity.  Personally, I have encountered this mostly when dealing with deletion forms.  Consider this scenario: let&#39;s say you are adding functionality to delete a specific Category entity (the same category that is referenced in our previous Post example), but in order to delete a category, you need to choose where all of its child posts should be moved.  In this case, you want to display a select field with all possible categories, but you don&#39;t have the wonderful benefits of a doctrine entity with an association defined.</p>

<p>In this situation, create a new model to represent your deletion parameters, attach it to a form that is designed to render and validate the available parameters, and then use that model to perform the necessary business logic to move the child posts and delete the category.  Again, let&#39;s go with an example.</p>

<p>The model here is a little more complex than the previous entity; pay careful attention to the &quot;assert&quot; annotations that I use here:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Model</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Epixa\\Entity\Category</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Validator\\Constraints</span> <span class="k">as</span> <span class="nx">Assert</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\Extension\\Core\\ChoiceList\\ChoiceListInterface</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Validator\\ExecutionContext</span><span class="p">;</span>

<span class="sd">/**</span>
<span class="sd"> * @Assert\\Callback(methods = {&quot;isInheritingCategoryValid&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">CategoryDeletionParams</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * @Assert\\NotBlank()</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$inheritingCategoryId</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$choices</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setInheritingCategoryId</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">inheritingCategoryId</span> <span class="o">=</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span><span class="nv">$id</span><span class="p">;</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getInheritingCategoryId</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">inheritingCategoryId</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setInheritingCategoryChoices</span><span class="p">(</span><span class="nx">ChoiceListInterface</span> <span class="nv">$choices</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">choices</span> <span class="o">=</span> <span class="nv">$choices</span><span class="p">;</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getInheritingCategoryChoices</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">choices</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">isInheritingCategoryValid</span><span class="p">(</span><span class="nx">ExecutionContext</span> <span class="nv">$context</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$choiceList</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getInheritingCategoryChoices</span><span class="p">();</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$choiceList</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">\LogicException</span><span class="p">(</span><span class="s1">&#39;No choice list configured&#39;</span><span class="p">);</span>
        <span class="p">}</span>
        
        <span class="nv">$choices</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getInheritingCategoryChoices</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getChoices</span><span class="p">();</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getInheritingCategoryId</span><span class="p">(),</span> <span class="nv">$choices</span><span class="p">))</span> <span class="p">{</span>
            <span class="nv">$propertyPath</span> <span class="o">=</span> <span class="nv">$context</span><span class="o">-&gt;</span><span class="na">getPropertyPath</span><span class="p">()</span> <span class="o">.</span> <span class="s1">&#39;.inheritingCategoryId&#39;</span><span class="p">;</span>
            <span class="nv">$context</span><span class="o">-&gt;</span><span class="na">setPropertyPath</span><span class="p">(</span><span class="nv">$propertyPath</span><span class="p">);</span>
            <span class="nv">$context</span><span class="o">-&gt;</span><span class="na">addViolation</span><span class="p">(</span><span class="s1">&#39;Invalid category&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(),</span> <span class="k">null</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>The NotBlank assertion on the $inheritingCategoryId ensures that a category id is required.  The Callback assertion on the class ensures that the given category id is actually one of the available options.  <em>Note: Callback assertions cannot be placed on properties.</em></p>

<p>Now for the form type:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Form\\Type</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Symfony\\Component\\Form\\AbstractType</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\FormBuilder</span><span class="p">,</span>
    <span class="nx">Epixa\\Model\\CategoryDeletionParams</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">DeleteCategoryType</span> <span class="k">extends</span> <span class="nx">AbstractType</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">buildForm</span><span class="p">(</span><span class="nx">FormBuilder</span> <span class="nv">$builder</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$options</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">])</span> <span class="o">||</span> <span class="o">!</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">]</span> <span class="nx">instanceof</span> <span class="nx">CategoryDeletionParams</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">\LogicException</span><span class="p">(</span><span class="s1">&#39;No valid options provided&#39;</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$deletionParams</span> <span class="o">=</span> <span class="nv">$options</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">];</span>

        <span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="s1">&#39;inheritingCategoryId&#39;</span><span class="p">,</span> <span class="s1">&#39;choice&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
            <span class="s1">&#39;label&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Move all posts to:&#39;</span><span class="p">,</span>
            <span class="s1">&#39;choice_list&#39;</span> <span class="o">=&gt;</span> <span class="nv">$deletionParams</span><span class="o">-&gt;</span><span class="na">getInheritingCategoryChoices</span><span class="p">()</span>
        <span class="p">));</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getDefaultOptions</span><span class="p">(</span><span class="k">array</span> <span class="nv">$options</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">array</span><span class="p">(</span>
            <span class="s1">&#39;data_class&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Epixa\\Model\\CategoryDeletionParams&#39;</span>
        <span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="s1">&#39;epxia_delete_category&#39;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>In this form type, we have to do a little more leg work than we did before.  The form builder doesn&#39;t have enough information to guess all of the field&#39;s details like it did with the doctrine entity, so we needed to specify that this is a &quot;choice&quot; field, with a custom label, and populated by a specific choice_list.</p>

<p>Next up?  You guessed it; the action:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">public</span> <span class="k">function</span> <span class="nf">deleteAction</span><span class="p">(</span><span class="nv">$id</span><span class="p">,</span> <span class="nx">Request</span> <span class="nv">$request</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// ... retrieve $category entity that matches the $id</span>

    <span class="c1">// This should be located in its own service. I am including it here to get the message across.</span>
    <span class="nv">$entityName</span> <span class="o">=</span> <span class="s1">&#39;Epixa\\Entity\\Category&#39;</span><span class="p">;</span>
    <span class="nv">$em</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getDoctrine</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getEntityManager</span><span class="p">();</span>
    <span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="nv">$entityName</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;c&#39;</span><span class="p">);</span>
    <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">&#39;c.id &lt;&gt; :category_id&#39;</span><span class="p">);</span> <span class="c1">// we don&#39;t want to include the category we&#39;re deleting</span>
    <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">setParameter</span><span class="p">(</span><span class="s1">&#39;category_id&#39;</span><span class="p">,</span> <span class="nv">$category</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">());</span>
    <span class="nv">$choiceList</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\\Symfony\\Bridge\\Doctrine\\Form\\ChoiceList\\EntityChoiceList</span><span class="p">(</span><span class="nv">$em</span><span class="p">,</span> <span class="nv">$entityName</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$qb</span><span class="p">);</span>

    <span class="nv">$deletionParams</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\\Epixa\\Model\\CategoryDeletionParams</span><span class="p">();</span>
    <span class="nv">$deletionParams</span><span class="o">-&gt;</span><span class="na">setInheritingCategoryChoices</span><span class="p">(</span><span class="nv">$choiceList</span><span class="p">);</span>

    <span class="nv">$form</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">createForm</span><span class="p">(</span><span class="k">new</span> <span class="nx">\\Epixa\\Form\\Type\\DeleteCategoryType</span><span class="p">(),</span> <span class="nv">$deletionParams</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getMethod</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">bindRequest</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="nv">$form</span><span class="o">-&gt;</span><span class="na">isValid</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ... move all child posts to the category identified by $deletionParams-&gt;getInheritingCategoryId()</span>
            <span class="c1">// ... delete $category and redirect away</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;form&#39;</span> <span class="o">=&gt;</span> <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">createView</span><span class="p">()</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<p>The controller above is a little rough.  I included a lot of logic in there that should really go into a separate service, but I didn&#39;t want the complication of the example getting in way of the meat of the issue.</p>

<p>That&#39;s it!  When you render the form, it will provided a Symfony 2 choice field rendered as a select field that is populated with all of the categories (except the one we&#39;re deleting).  When you submit the form, it will check to make sure that not only is a category selected but also that the selection is actually one of the categories in the system.</p>

<p>I&#39;m still only breaking the surface of the Symfony 2 form component, and I am finding that for all of incredible convenience that is provided for very common functionality there is likely an equal amount of frustration when trying to implement more specific pieces of functionality.  That said, the component is certainly powerful, and I haven&#39;t yet come across a scenario that it couldn&#39;t handle.</p>

<p><strong>Know of an easier way to do this?</strong> By all means let me know!  I am eager to simplify processes like this as I expect to be doing this kind of thing frequently.</p>

<h2>Edit (Aug 08 2010 4:40pm):</h2>

<p><a href="http://webmozarts.com/">@Bernhard</a> has provided an approach that seems to be much more in line with the usage that symfony devs envisioned.  He notes that the <a href="http://symfony.com/doc/current/reference/forms/types/entity.html">entity</a> field type takes care of validation for you and provides a convenient way to populate the select options as well.  I&#39;ve revised his example code only so much as to fit with the previous examples and execute properly:</p>

<p>Deletion parameters model:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Model</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Symfony\\Component\\Validator\\Constraints</span> <span class="k">as</span> <span class="nx">Assert</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">CategoryDeletionParams</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$targetCategory</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     * @Assert\\NotBlank()</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$inheritingCategory</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>

    <span class="c1">// ... appropriate setters and getters</span>
<span class="p">}</span>
</code></pre></div>

<p>Form type:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Epixa\\Form\\Type</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Symfony\\Component\\Form\\AbstractType</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\FormBuilder</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\FormEvents</span><span class="p">,</span>
    <span class="nx">Symfony\\Component\\Form\\Event\\DataEvent</span><span class="p">,</span>
    <span class="nx">Doctrine\\ORM\\EntityRepository</span><span class="p">,</span>
    <span class="nx">Epixa\\Model\\CategoryDeletionParams</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">DeleteCategoryType</span> <span class="k">extends</span> <span class="nx">AbstractType</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">buildForm</span><span class="p">(</span><span class="nx">FormBuilder</span> <span class="nv">$builder</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$options</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// creates the inheriting select field whenever the data (deletion params model) is set</span>
        <span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">FormEvents</span><span class="o">::</span><span class="na">PRE_SET_DATA</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nx">DataEvent</span> <span class="nv">$event</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$builder</span><span class="p">){</span>
            <span class="nv">$data</span> <span class="o">=</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">();</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$data</span> <span class="nx">instanceof</span> <span class="nx">CategoryDeletionParams</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">return</span><span class="p">;</span> <span class="c1">// $data is null when form is first constructed</span>
            <span class="p">}</span>

            <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getForm</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">create</span><span class="p">(</span><span class="s1">&#39;inheritingCategory&#39;</span><span class="p">,</span> <span class="s1">&#39;entity&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
                <span class="s1">&#39;label&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Move all posts to:&#39;</span><span class="p">,</span>
                <span class="s1">&#39;class&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Epixa\\Entity\\Category&#39;</span><span class="p">,</span>
                <span class="s1">&#39;query_builder&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">(</span><span class="nx">EntityRepository</span> <span class="nv">$repo</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$data</span><span class="p">){</span>
                    <span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$repo</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;c&#39;</span><span class="p">);</span>
                    <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">&#39;c.id &lt;&gt; :category_id&#39;</span><span class="p">);</span>
                    <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">setParameter</span><span class="p">(</span><span class="err">‘</span><span class="nx">category_id</span><span class="err">’</span><span class="p">,</span> <span class="nv">$data</span><span class="o">-&gt;</span><span class="na">getTargetCategory</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">());</span>
                    <span class="k">return</span> <span class="nv">$qb</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">))</span><span class="o">-&gt;</span><span class="na">getForm</span><span class="p">());</span>
        <span class="p">});</span>
    <span class="p">}</span>

    <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div>

<p>Action:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">deleteAction</span><span class="p">(</span><span class="nv">$id</span><span class="p">,</span> <span class="nx">Request</span> <span class="nv">$request</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// ... retrieve $category that matches $id</span>

    <span class="nv">$params</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\\Epixa\\Model\\CategoryDeletionParams</span><span class="p">(</span><span class="nv">$category</span><span class="p">);</span>
    <span class="nv">$form</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">createForm</span><span class="p">(</span><span class="k">new</span> <span class="nx">\\Epixa\\Form\\Type\\DeleteCategoryType</span><span class="p">(),</span> <span class="nv">$params</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getMethod</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">bindRequest</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="nv">$form</span><span class="o">-&gt;</span><span class="na">isValid</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ... move child posts to inheriting category, delete target category, redirect away</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">&#39;form&#39;</span> <span class="o">=&gt;</span> <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">createView</span><span class="p">()</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<p>I think this approach is much clearer than my original example.  Thanks Bernhard!</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Ideas of March - Think About the Little Guy</title>
    <link href="http://epixa.com/2011/03/ideas-of-march-think-about-the-little-guy.html"/>
    <id>http://epixa.com/?p=336</id>
    <updated>2011-03-15T16:43:33Z</updated>
    <content type="html"><![CDATA[<p>When I first started diving head-first into the open source community, the blogosphere was by far the most helpful resource around.  I tried to consume as much of the information as I could by visiting individual sites directly, but as the number of awesome blogs out there increased, I had to start getting my daily dose of near-overwhelming programming goodness through RSS.  Shortly after doing so, I&#39;d have hundreds of articles to browse through every single day; this was truly a great time to get involved with open source.</p>

<p>Since then, something has changed.  Writing blog articles is almost as time consuming as reading a couple dozen active blogs a day, and authors feel compelled to write only when they have a lot to say on a subject.  Microblogging services such as twitter and identi.ca have made sharing thoughts and ideas much quicker, and they give the appearance of more active discussions because it is just so damn easy to write 140 characters about pretty much anything.</p>

<p>In recent years, and especially in recent months, my RSS reader has slowed down significantly.  I have no less subscriptions than I did years ago, but there are only a fraction of the numbers articles each day in my feed.  Since blogs had such a significant impact on me, this recent trend is absolutely crushing.</p>

<p>A lot of people are talking about Chris Shiflett&#39;s <a href="http://shiflett.org/blog/2011/mar/ideas-of-march">Ideas of March</a> plea.  Chris Cornutt <a href="http://blog.phpdeveloper.org/?p=340">rightfully points out</a> that blogs are a fantastic way for people to archive their thoughts and experiences and share their knowledge.  Elizabeth Naramore <a href="http://www.naramore.net/blog/the-ide-a-s-of-march">emphasizes</a> that blogs help spur great conversations, and I personally believe these conversations can be as useful, if not more useful, than the articles themselves.</p>

<p>One key point that I feel like many people are missing is how unbelievably important blogging is to the new guy.  When you&#39;re getting involved with any community, the first thing you do is start reading what those community members have to say.  You look for aggregator sites such as <a href="http://phpdeveloper.org">PHP Developer</a> and <a href="http://planet-php.net">Planet PHP</a>, and that immediately gives you access to the complete modern history of the community.  At your fingertips is all of the shared knowledge that the best minds in the community have to offer.</p>

<p>When the community archives its collective knowledge on blogs, then new community members not only have an invaluable resource, but they also have the means to get involved in a real way.  When you post a comment on a blog, it does not matter who you are; you do not need to prove your worth in order to get well-known &quot;followers&quot; so that your message gets heard.  A person&#39;s contribution to the discussion is valued strictly on its quality rather than how prominent the individual is in the community.  When that happens, the whole community wins.</p>

<p>Like many have already pledged to do, I will try to do more blogging this month in the spirit of the Ideas of March, and hopefully that habit will linger for some time to come.  At the same time, I eagerly await the onslaught of blog articles in my dwindling RSS feed.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>How to Stay Productive When You Work from Home</title>
    <link href="http://epixa.com/2011/02/how-to-stay-productive-when-you-work-from-home.html"/>
    <id>http://epixa.com/?p=300</id>
    <updated>2011-02-26T20:57:29Z</updated>
    <content type="html"><![CDATA[<p>Working at home is great.  You have seemingly endless flexibility, you can set up your work environment exactly the way you want it, and you do not have to deal with the compromises that you often make when sharing a workspace with others.</p>

<p>Since starting work with <a href="http://echolibre.com">Echolibre</a> in June of last year, I have learned a lot about how to work effectively and efficiently at home.  I avoid the common pitfalls that make working from a home-office distracting and/or unproductive by the following principles:</p>

<h2>Find a dedicated space to call your own</h2>

<p>Before I began working from home, I had visions that doing so would involve lounging on the couch, sitting outside in the sunshine, and working pretty much anywhere other than a traditional desk, chair, small-office-plant type of environment.  I quickly learned that I am more productive and organized when I have a dedicated work area.  A dedicated space is any area of your house that is used for nothing other than your work -- it doesn&#39;t second as a dining room table, it isn&#39;t in the middle of your living room, and it isn&#39;t even a place to throw household mail.  It is a place that you can always go to work without having to bother with the distractions of a normal household.</p>

<p>Don&#39;t get me wrong, working on the couch, outside, or in book stores/coffee houses can be really beneficial.  I&#39;ve found that I can often jumpstart my creativity by working in a fresh place.  But a stable, dedicated space is ultimately where I am most productive on a regular basis.</p>

<h2>Create a routine and try to stick to it</h2>

<p>Set up a daily/weekly routine.  It is awesome that you can deviate from that routine when necessary, but deviate from that routine <em>only</em> when necessary.  Constant delays to your schedule will only prolong the amount of time in the day that you are ultimately dedicating to work.  Seemingly &quot;little&quot; things such as watching a bunch of novelty videos online will make it seem like you are far less productive, and you will have to work much longer hours in order to make up for it.</p>

<p>If you don&#39;t tend to rise early, then go nuts and wake up at 9am, but do so consistently.  You&#39;ll find that with a regular routine, it will be easier to fit other activities in your schedule (see &quot;Get out more&quot; below).  I challenge anyone to cultivate a healthy social life, regular exercise, and a work/personal life balance when their work schedule completely varies from day to day.</p>

<h2>Get out more</h2>

<p>If you&#39;re lucky, your significant other will also work from home, so you&#39;ll have at least some social interaction throughout the day, but this is not enough.  Go out with friends, take your significant other out to dinner and a show, get a cup of coffee and take some time to relax in a public space.  It is too easy to stay home, and you will begin to feel lethargic and uninspired.</p>

<h2>Get dressed</h2>

<p>Pajamas are the enemy here.  You&#39;re not going out, so you don&#39;t feel like you need to be presentable to the world, and those flannel pj&#39;s you have are really quite comfortable.  It will be really tempting to stay in your lounging or sleeping clothes, but make getting dressed part of your routine.  You don&#39;t need to dress up in business-wear or anything, but at least wear clothes that you would wear out to family restaurant or to run errands.  Wearing PJs all day should be an event that is worth noting -- it should be something that happens infrequently enough that it feels rewarding to do so.</p>

<h2>Love what you do</h2>

<p>The easiest way to become unproductive, uncreative, and outright bored while working from home is to simply not enjoy the work that you do.  Half of your life is spent working, and never is this more evident than when you spend the vast majority of your time in one place.  If you don&#39;t absolutely love what you do, then it will be that much more difficult to avoid the myriad of other things that you prefer to do at home in your free time.</p>

<p>Plus, you only live once, so why waste any of that precious time doing something that you do not find rewarding?</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>A Simple Alternative to Global Registry Dependency</title>
    <link href="http://epixa.com/2010/12/a-simple-alternative-to-global-registry-dependency.html"/>
    <id>http://epixa.com/?p=303</id>
    <updated>2010-12-06T17:03:12Z</updated>
    <content type="html"><![CDATA[<p>Anyone that has written object oriented code has had to use one class from within another class.  The quick and dirty way to implement this is to simply hardcode the object instantiation within the current class, but this can cause you more hassle in the long run.  Unfortunately, this method provides you with no means of overriding or changing that dependency on the fly, so future modifications and testing suffer.</p>

<p>The obvious solution to this hard-coding issue is to instead rely on objects being explicitly passed via a constructor and/or mutators.  If your service requires a database adapter, create a <strong>setDbAdapter()</strong> method and whenever you instantiate a new service object, pass in the adapter.  This solution provides an incredible amount of flexibility, but it does force you to set an adapter on every single service instantiation.  For most applications, only one database adapter will ever be required, so it is tedious at best to pass in the adapter to each and every service.</p>

<p>This is where many developers (and frameworks) turn to a global registry.  During the bootstrap process, they will configure a database adapter and store it in a singleton registry, and then their service object would retrieve the adapter from the registry.  This gives you flexibility when configuring and setting your adapter, and it allows you to instantiate a new service without having to explicitly set commonly used dependencies, but you are ultimately just replacing one hardcoded object call with another.  This means you are still limited in your ability to unit test the class properly, and you will have a difficult time debugging if you ever need to find out exactly when and where your database adapter was configured.</p>

<h2>The Simple Solution</h2>

<p>Use static methods to set a default database adapter for all services that need it but still allow database adapters to be set explicitly.  In your bootstrap process, you configure your database adapter just like you would normally, then you set the adapter as the &quot;default&quot; adapter for all services.  The service should have a <strong>getDbAdapter()</strong> method that pulls either the adapter set on that instance or, if there is no adapter set, it uses the default adapter instead.</p>

<p>This is what your abstract service could look like (adapted from my <a href="https://github.com/epixa/Epixa/blob/master/library/Epixa/Service/AbstractDoctrineService.php">doctrine2 entity manager service</a>):</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Epixa\\Service</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Epixa\\Exception\\ConfigException</span><span class="p">,</span>
    <span class="nx">Zend_Db_Adapter_Abstract</span> <span class="k">as</span> <span class="nx">DbAdapter</span><span class="p">;</span>

<span class="k">abstract</span> <span class="k">class</span> <span class="nc">AbstractDbService</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$dbAdapter</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>

    <span class="k">protected</span> <span class="k">static</span> <span class="nv">$defaultDbAdapter</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>

    
    <span class="sd">/**</span>
<span class="sd">     * Set the default database adapter for all database services</span>
<span class="sd">     * </span>
<span class="sd">     * @param DbAdapter $dbAdapter</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">setDefaultDbAdapter</span><span class="p">(</span><span class="nx">DbAdapter</span> <span class="nv">$dbAdapter</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nx">self</span><span class="o">::</span><span class="nv">$defaultDbAdapter</span> <span class="o">=</span> <span class="nv">$dbAdapter</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Get the default database adapter for all database services</span>
<span class="sd">     * </span>
<span class="sd">     * @return DbAdapter</span>
<span class="sd">     * @throws ConfigException If no default database adapter is set</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">getDefaultDbAdapter</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="nv">$defaultDbAdapter</span> <span class="o">===</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">ConfigException</span><span class="p">(</span><span class="s1">&#39;No default database adapter configured&#39;</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="nx">self</span><span class="o">::</span><span class="nv">$defaultDbAdapter</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Set the database adapter for this service</span>
<span class="sd">     * </span>
<span class="sd">     * @param  DbAdapter $dbAdapter</span>
<span class="sd">     * @return AbstractDbService *Fluent interface*</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">setDbAdapter</span><span class="p">(</span><span class="nx">DbAdapter</span> <span class="nv">$dbAdapter</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dbAdapter</span> <span class="o">=</span> <span class="nv">$dbAdapter</span><span class="p">;</span>
        
        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Get the database adapter for this service</span>
<span class="sd">     *</span>
<span class="sd">     * If no database adapter is set, set it to the default database adapter.</span>
<span class="sd">     *</span>
<span class="sd">     * @return DbAdapter</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getDbAdapter</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dbAdapter</span> <span class="o">===</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setDbAdapter</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">getDefaultDbAdapter</span><span class="p">());</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dbAdapter</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>Then, in your bootstrap, you would just need to set the default adapter:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Epixa\\Application\\Bootstrap</span> <span class="k">as</span> <span class="nx">BaseBootstrap</span><span class="p">,</span>
    <span class="nx">Epixa\\Service\\AbstractDbService</span> <span class="k">as</span> <span class="nx">DbService</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Bootstrap</span> <span class="k">extends</span> <span class="nx">BaseBootstrap</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * Set the default database adapter for database services</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">_initDbServices</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$db</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bootstrap</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getResource</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">);</span>
        <span class="nx">DbService</span><span class="o">::</span><span class="na">setDefaultDbAdapter</span><span class="p">(</span><span class="nv">$db</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>This code is adhering to Zend Framework&#39;s bootstrapping implementation, but the premise is universal: set up your database adapter, and set it as the default on the abstract service.  After that is done, any class that extends AbstractDbService will have access to the database adapter.  However, if they needed to have their own database adapter set (either for unit testing purposes or if they happened to need to access another database), you can do so on an individual basis.  In either case, the way you access the database adapter within your service remains unchanged.</p>

<p>And that&#39;s it!  Go ahead and mock your dependencies for unit testing or throw around different database adapters at your pleasure.</p>

<p>Ok, ok...  That isn&#39;t entirely it.</p>

<h2>There is One Large Caveat</h2>

<p>If your objects rely on a large [variable] number of dependencies, a single abstract class might not do the trick.  My services generally do not require more than an entity manager and an ACL object, and I imagine many developers will be in a similar boat.  That said, this is not the best solution out there for handling a lot of dependencies.  If this is not sufficient for your needs, consider a more robust system such as <a href="http://components.symfony-project.org/dependency-injection/">Symfony&#39;s dependency injection framework</a>.</p>

<h2>A Final Note</h2>

<p>With the addition of <a href="http://wiki.php.net/rfc/horizontalreuse">traits</a> in the PHP trunk, this method of setting defaults for dependencies will actually be that much more powerful.  Instead of having to deal with a single abstract class, each dependency can be managed by a single trait, and your objects will be able to pick and choose whichever traits they need.  Neat, eh?</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Forget Concatenation; Format your strings!</title>
    <link href="http://epixa.com/2010/09/forget-concatenation-format-your-strings.html"/>
    <id>http://epixa.com/?p=253</id>
    <updated>2010-09-16T00:16:34Z</updated>
    <content type="html"><![CDATA[<p>I do it, you do it, everyone does it!  We all concatenate.  If you&#39;re simply combining a few variables or constants together, concatenation is the way to go.  After all, it is quick and easy, and who can complain about that?  However, concatenation does have two serious drawbacks: any sort of string formatting must be done manually, and it is difficult to visualize the &quot;goal&quot; string when it is sufficiently complex.</p>

<p>Fortunately, the PHP core offers <a href="http://php.net/sprintf">sprintf()</a>/<a href="http://php.net/printf">printf()</a> which can greatly improve the readability of your code and even limit the amount of work you need to do to perform common formatting and type casting on your strings.</p>

<h2>Why is String Formatting so Great?</h2>

<p>This is a pretty silly question, I know.  Let&#39;s face it, whether or not you use sprintf, you format strings all the time.  You cast variables to certain types, you format float representations of currency, you put multiple values together, etc.  The key here is, sprintf makes all of that incredibly easy, and it does so while making your code easier to read.</p>

<p>Want to do any of the things I just mentioned?  Piece of cake:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$money</span> <span class="o">=</span> <span class="mf">29.5</span><span class="p">;</span>
<span class="nb">printf</span><span class="p">(</span><span class="s1">&#39;Approximately $%d.&#39;</span><span class="p">,</span> <span class="nv">$money</span><span class="p">);</span>
<span class="c1">// outputs: Approximately $29.</span>
<span class="nb">printf</span><span class="p">(</span><span class="s1">&#39;Exactly $%01.2f.&#39;</span><span class="p">,</span> <span class="nv">$money</span><span class="p">);</span>
<span class="c1">// outputs: Exactly $29.50.</span>

<span class="nv">$total</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">&quot;%d item%s total.&quot;</span><span class="p">,</span> <span class="nv">$total</span><span class="p">,</span> <span class="nv">$total</span> <span class="o">!=</span> <span class="mi">1</span> <span class="o">?</span> <span class="s1">&#39;s&#39;</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
<span class="c1">// outputs: 1 item total.</span>
<span class="nv">$total</span><span class="o">++</span><span class="p">;</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">&quot;%d item%s total.&quot;</span><span class="p">,</span> <span class="nv">$total</span><span class="p">,</span> <span class="nv">$total</span> <span class="o">!=</span> <span class="mi">1</span> <span class="o">?</span> <span class="s1">&#39;s&#39;</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
<span class="c1">// outputs: 2 items total.</span>
</code></pre></div>

<h2>Visualize the Goal</h2>

<p>We&#39;d like to avoid doing it, but as developers of dynamic applications, we are frequently forced to build complex strings on the fly.  If you handle this with concatenation, you are almost assuredly creating strings that are difficult to read without careful scrutiny.  Consequently, it is difficult to determine the intent of the completed string which can cause unexpected results or trigger errors.  The functionality offered by sprintf allows us to visualize the template of the string that we&#39;re ultimately trying to create, so it can greatly improve readability and save you some annoying debugging time.</p>

<p>Consider creating a fairly simple, dynamic email link in HTML:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$email</span> <span class="o">=</span> <span class="s1">&#39;dynamic@email.com&#39;</span><span class="p">;</span>

<span class="nb">printf</span><span class="p">(</span><span class="s1">&#39;&lt;a href=&quot;mailto:%1$s&quot;&gt;%1$s&lt;/a&gt;&#39;</span><span class="p">,</span> <span class="nb">htmlentities</span><span class="p">(</span><span class="nv">$email</span><span class="p">));</span>
<span class="k">echo</span> <span class="s1">&#39;&lt;a href=&quot;mailto:&#39;</span> <span class="o">.</span> <span class="nb">htmlentities</span><span class="p">(</span><span class="nv">$email</span><span class="p">)</span> <span class="o">.</span> <span class="s1">&#39;&gt;&#39;</span> 
    <span class="o">.</span> <span class="nb">htmlentities</span><span class="p">(</span><span class="nv">$email</span><span class="p">)</span> <span class="o">.</span> <span class="s1">&#39;&lt;/a&gt;&#39;</span><span class="p">;</span>
</code></pre></div>

<p>These are both designed to output the same thing, but since the first one separates the string formatting into two distinct parts: it first sets up the goal string and then escapes the variable input.  This separation makes it very clear what you are trying to accomplish and what has to be done to accomplish it, and it is easier to debug either step as a result.</p>

<p>The concatenation version is harder to read and all of your work is muddied throughout the process.  This makes it more difficult to quickly identify bugs.  Speaking of which, did you notice that the concatenation version is bugged in the example?  If not, look closer (if so, thanks for proof reading my code so thoroughly!).  This type of bug is especially heinous since some browsers may render it perfectly fine.</p>

<p>Now, take a look at a dynamic SQL query where I&#39;ll let the results speak for themselves.  There is not a bug (that I&#39;m aware of) in this code, so consider this simply from a readability standpoint:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$userId</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nv">$limit</span>  <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="nv">$offset</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span>

<span class="nv">$columns</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;b.id&#39;</span><span class="p">,</span> <span class="s1">&#39;b.title&#39;</span><span class="p">,</span> <span class="s1">&#39;b.date&#39;</span><span class="p">,</span> <span class="s1">&#39;b.content&#39;</span><span class="p">,</span> <span class="s1">&#39;u.name&#39;</span><span class="p">,</span> <span class="s1">&#39;u.email&#39;</span>
<span class="p">);</span>

<span class="nv">$where</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
    <span class="nv">$dbAdapter</span><span class="o">-&gt;</span><span class="na">quoteInto</span><span class="p">(</span><span class="s1">&#39;u.id = ?&#39;</span><span class="p">,</span> <span class="nv">$userId</span><span class="p">),</span>
    <span class="s1">&#39;b.date_published is not null&#39;</span>
<span class="p">);</span>

<span class="nv">$dbAdapter</span><span class="o">-&gt;</span><span class="na">query</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
    <span class="s1">&#39;SELECT %s </span>
<span class="s1">        FROM Blog b INNER JOIN User u ON u.id = b.user_id </span>
<span class="s1">        WHERE %s LIMIT %d OFFSET %d&#39;</span><span class="p">,</span>
    <span class="nb">implode</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">,</span> <span class="nv">$columns</span><span class="p">),</span> <span class="nb">implode</span><span class="p">(</span><span class="s1">&#39; AND &#39;</span><span class="p">,</span> <span class="nv">$where</span><span class="p">),</span> <span class="nv">$limit</span><span class="p">,</span> <span class="nv">$offset</span>
<span class="p">));</span>

<span class="nv">$dbAdapter</span><span class="o">-&gt;</span><span class="na">query</span><span class="p">(</span>
    <span class="s1">&#39;SELECT &#39;</span> <span class="o">.</span> <span class="nb">implode</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">,</span> <span class="nv">$columns</span><span class="p">)</span> 
        <span class="o">.</span> <span class="s1">&#39; FROM Blog b INNER JOIN User u ON u.id = b.user_id </span>
<span class="s1">            WHERE &#39;</span> <span class="o">.</span> <span class="nb">implode</span><span class="p">(</span><span class="s1">&#39; AND &#39;</span><span class="p">,</span> <span class="nv">$where</span><span class="p">)</span> 
        <span class="o">.</span> <span class="s1">&#39; LIMIT &#39;</span> <span class="o">.</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span><span class="nv">$limit</span> <span class="o">.</span> <span class="s1">&#39; OFFSET &#39;</span> <span class="o">.</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span><span class="nv">$offset</span>
<span class="p">);</span>
</code></pre></div>

<h2>Concluding Thoughts</h2>

<p>This is not a very complex concept; while you can do more with the PHP string formatting functions than what I&#39;ve shown here, they are not miracle gifts to your programming arsenal that will instantly make you god&#39;s gift to the web.  They can, however, make your code easier to read, and that translates to less animosity between you and the next sap that has to maintain your code, and they can even save you some time in identifying some common but frustrating mistakes.</p>

<p>Hint: Use sprintf when you&#39;re throwing exceptions.  You may find yourself making clearer messages that also include more useful information for the user:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">InvalidArgumentException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
    <span class="s1">&#39;Received value of type `%s` but expected value of type `integer`&#39;</span><span class="p">,</span>
    <span class="nb">gettype</span><span class="p">(</span><span class="nv">$param</span><span class="p">)</span>
<span class="p">));</span>
</code></pre></div>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Zend Framework Modules: Autoloading &amp; Namespaces</title>
    <link href="http://epixa.com/2010/07/zend-framework-modules-autoloading-namespaces.html"/>
    <id>http://epixa.com/?p=231</id>
    <updated>2010-07-06T11:45:19Z</updated>
    <content type="html"><![CDATA[<p>Modules are natively supported in Zend Framework, but their implementation is not conducive to flexible autoloading nor the use of namespaces in PHP 5.3.  There may be a few contributors out there that will defend the current implementation of module autoloading, but throughout the development lifecycle of the current Model-View-Controller implementation in the framework, poor design decisions have made working with modules less flexible and more frustrating.</p>

<h2>The First Problem</h2>

<p>The problem stems from the initial decisions about the naming conventions for directories and classes for controllers and views.  The convention that controllers would be stored in a directory called &quot;controllers&quot; and views would be stored in a directory called &quot;views&quot; throws any attempt at dynamic autoloading immediately out the window.  Instead, this single design decision served to ensure that all attempts to autoload consistently-named module-based PHP classes would require some sort of explicit configuration.  As a result, many developers decided to put their classes such as forms, models, and mappers into separate libraries -- not very modular, eh?</p>

<h2>The Official Solution: AKA The Second Problem</h2>

<p>Enter the current implementation of &quot;resource&quot; autoloading.  This greatly anticipated addition to Zend Framework was to solve our insatiable hunger for module-specific classes (hereto referred to as &quot;resources&quot;).  The immediate effect was our modules could finally autoload our most used module resources.  Unfortunately, every single type of resource has to be explicitly defined for each module!  To help make this configuration easier, a &quot;module&quot; autoloader was added to Zend_Application that pre-configures common resources such as models and forms.  But think of that for a second.  An entire class was added to the framework with no other purpose other than pre-configuring options.  If that doesn&#39;t scream red-flag, I don&#39;t know what does.</p>

<h2>Let&#39;s Talk Solutions</h2>

<p>I am extremely opinionated, and I could probably rant for hours about a topic like this, but I digress.  Instead, let&#39;s look at a proof of concept that I implemented:</p>

<p><a href="http://github.com/epixa/Epixa">http://github.com/epixa/Epixa</a></p>

<p>The premise is pretty simple: modules should be nothing less than near-independent libraries of code.  When modules are treated like libraries in their own right, they gain all of the flexibility and speed that we get from autoloading library files.  Better yet, the main autoloader in Zend Framework can handle the autoloading all on its own, which means your module resources can be namespaced.</p>

<p>With extensions in that library, you can achieve a directory structure like the following with little to no configuration: </p>

<p><img src="http://epixa.com/files/2010/06/epixa-app-directory-structure.png" alt="Screenshot of Epixa example directory structure" title="Epixa Example App Directory Structure"></p>

<h2>What We&#39;re Missing</h2>

<p>This is currently to serve only as a proof of concept, so there is still plenty that can be added.  For instance, while I updated the dispatcher so controllers are namspaced like &quot;Blog\Controller\Post&quot;, I did not remove the class loading logic from the dispatcher itself.  To separate concerns, the controller class loading <em>should</em> be passed off entirely to the autoloader.</p>

<p>The library also still leaves a lot to be desired when it comes to efficient module bootstrapping and plugin loading.  I&#39;ll post improvements in both of those regards along with module dependency loading in the near future.</p>

<p>In the meantime, I would love feedback about this approach.  If I can refine it a bit further, I plan to campaign for its inclusion as the standard module setup in Zend Framework 2.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Goodbye Modo Design Group, Hello echolibre</title>
    <link href="http://epixa.com/2010/06/goodbye-modo-design-group-hello-echolibre.html"/>
    <id>http://epixa.com/?p=222</id>
    <updated>2010-06-15T00:22:20Z</updated>
    <content type="html"><![CDATA[<p>After more than two years, I am both saddened and excited to say that I am leaving <a href="http://mododesigngroup.com">Modo Design Group</a>.</p>

<p>I&#39;m saddened because I loved working at Modo.  It was wonderful being a part of a rapidly growing company from very early on, and I was constantly challenged [in a good way] by the myriad of new and cutting edge technologies that we implemented in some of the most fantastic client projects I have come across to date.  Modo is comprised of some of the most talented and inspiring individuals I have ever had the privilege of working with, and I truly wish them the best of luck in everything they do.</p>

<p>I am excited because I will be joining the team at <a href="http://echolibre.com">echolibre</a> on June 29th.  They are an amazing bunch of guys with seemingly endless talent, and I cannot wait to start contributing to the team.  I am always looking to expand my current skillset and work with the best people in the industry, and I believe I will do just that with the fellas from abroad.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>PHP Integration with Salesforce CRM</title>
    <link href="http://epixa.com/2010/05/php-integration-with-salesforce-crm.html"/>
    <id>http://epixa.com/?p=156</id>
    <updated>2010-05-19T02:18:28Z</updated>
    <content type="html"><![CDATA[<p>If your primary clientele is small to medium business owners, as I imagine is the case for most professional developers these days, chances are you have developed custom applications that interact with Salesforce CRM.  For those of you that have not had the <em>delight</em> of integrating with Salesforce, let&#39;s walk through the most common integration techniques.</p>

<p>Integrating with Salesforce CRM begins with the Force.com Web Services API.  The API is SOAP based, so you can use PHP&#39;s built in soap extension to make calls to the service, but in this tutorial I&#39;ll be using the <a href="http://wiki.developerforce.com/index.php/PHP_Toolkit">PHP Toolkit</a> provided by Salesforce; you still need to have the php soap extension installed, but the toolkit provides convenient utility methods for all of the available api calls.</p>

<h2>Generate your WSDL</h2>

<p>The first thing you&#39;ll need to do to access your salesforce via the api is generate a WSDL.  The soap client requires the WSDL in order to, among other things, know what calls it can make to the server.</p>

<p>You have a few options when it comes to generating WSDLs in salesforce; I prefer to use the strongly typed Enterprise WSDL whenever possible.  Enter your salesforce &#39;setup&#39; section, traverse to Develop &gt; API, and click the &quot;Generate Enterprise WSDL&quot; link (see screenshot below).  On the following step, just leave all the versions at the defaults and click the &quot;Generate&quot; button.  Save the XML that is generated into a new file in your application.</p>

<p><img src="https://s3.amazonaws.com/epixa.com/images/2010-05-18-php-integration-with-salesforce-crm/salesforce-generate-wsdl.png" alt="Screenshot of salesforce setup for generating a wsdl" title="Salesforce: Generate WSDL"></p>

<h2>Get your Security Token</h2>

<p>To access the soap service, you will need to provide your username, password, and the security token that is generated for your account.  The security token is a random 25 character string of uppercase and lowercase letters and numbers.  If you are not sure what your security token is, you can generate a new one through the salesforce &#39;setup&#39; page (see screenshot below).  While you can reset your security token at any time, take heed of the notices that pepper the security-token section of the salesforce setup: if you change your security token, all existing api applications that rely on the token will break unless they are updated with the new token.</p>

<p><img src="https://s3.amazonaws.com/epixa.com/images/2010-05-18-php-integration-with-salesforce-crm/salesforce-reset-security-token.png" alt="Screenshot of salesforce setup for resetting login security token" title="Salesforce: Reset Security Token"></p>

<h2>Get your Code On</h2>

<p>Now that we have the boring salesforce groundwork out of the way, let&#39;s write some code!  First up, get connected:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$wsdl</span>  <span class="o">=</span> <span class="s1">&#39;enterprise-wsdl.xml&#39;</span><span class="p">;</span>
<span class="nv">$user</span>  <span class="o">=</span> <span class="s1">&#39;example@epixa.com&#39;</span><span class="p">;</span>
<span class="nv">$pass</span>  <span class="o">=</span> <span class="s1">&#39;supersecure&#39;</span><span class="p">;</span>
<span class="nv">$token</span> <span class="o">=</span> <span class="s1">&#39;fAjfS4FkxLsoqPxmsZujj0Szr&#39;</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SforceEnterpriseClient</span><span class="p">();</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createConnection</span><span class="p">(</span><span class="nv">$wsdl</span><span class="p">);</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">login</span><span class="p">(</span><span class="nv">$user</span><span class="p">,</span> <span class="nv">$pass</span> <span class="o">.</span> <span class="nv">$token</span><span class="p">);</span>
</code></pre></div>

<p>The five core method calls that you <em>must</em> know are upsert, retrieve, getUpdated, delete, getDeleted.  There are <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_list.htm">many more</a>, but knowing these powerful five is sufficient to do a large number of synchronization scripts.</p>

<h2>SforceEnterpriseClient::upsert()</h2>

<p>While the Salesforce API does offer create() and update() methods, you will probably find yourself using this nifty function to accomplish either task: <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_upsert.htm">upsert()</a> will attempt to insert a new record, and if an existing record that matches the field you specify already exists, it will update that record instead.  For those familiar with MySQL, this is basically the equivalent of INSERT ON DUPLICATE KEY UPDATE.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$first</span> <span class="o">=</span> <span class="k">new</span> <span class="k">stdClass</span><span class="p">();</span>
<span class="nv">$first</span><span class="o">-&gt;</span><span class="na">Name</span> <span class="o">=</span> <span class="s1">&#39;First Epixa Widget&#39;</span><span class="p">;</span>
<span class="nv">$first</span><span class="o">-&gt;</span><span class="na">Description</span> <span class="o">=</span> <span class="s1">&#39;This Epixa Widget is the best product of all time!&#39;</span><span class="p">;</span>

<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">upsert</span><span class="p">(</span><span class="s1">&#39;Name&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="nv">$first</span><span class="p">),</span> <span class="s1">&#39;Product2&#39;</span><span class="p">);</span>
<span class="c1">// result: a new product is created in salesforce</span>

<span class="nv">$second</span> <span class="o">=</span> <span class="k">new</span> <span class="k">stdClass</span><span class="p">();</span>
<span class="nv">$second</span><span class="o">-&gt;</span><span class="na">Name</span> <span class="o">=</span> <span class="s1">&#39;Second Epixa Widget&#39;</span><span class="p">;</span>
<span class="nv">$second</span><span class="o">-&gt;</span><span class="na">Description</span> <span class="o">=</span> <span class="s1">&#39;No, THIS Widget is the best product of all time!&#39;</span><span class="p">;</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">upsert</span><span class="p">(</span><span class="s1">&#39;Name&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="nv">$second</span><span class="p">),</span> <span class="s1">&#39;Product2&#39;</span><span class="p">);</span>
<span class="c1">// result: a new product is created in salesforce</span>

<span class="nv">$clonedFirst</span> <span class="o">=</span> <span class="k">clone</span> <span class="nv">$first</span><span class="p">;</span>
<span class="nv">$clonedFirst</span><span class="o">-&gt;</span><span class="na">Description</span> <span class="o">=</span> <span class="s1">&#39;FINE, Second Widget.  You can be the best product.&#39;</span><span class="p">;</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">upsert</span><span class="p">(</span><span class="s1">&#39;Name&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="nv">$clonedFirst</span><span class="p">),</span> <span class="s1">&#39;Product2&#39;</span><span class="p">);</span>
<span class="c1">// result: the first object&#39;s description is updated in salesforce</span>
</code></pre></div>

<h2>SforceEnterpriseClient::retrieve()</h2>

<p>The core method <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_retrieve.htm">retrieve()</a> allows you to query for one or more of a specified Salesforce object given a set of unique Ids:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$ids</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;01tA0000000YU4D&#39;</span><span class="p">,</span> <span class="s1">&#39;01tA0000000YU48&#39;</span><span class="p">);</span>

<span class="nv">$results</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">retrieve</span><span class="p">(</span><span class="s1">&#39;Id, Name, Description&#39;</span><span class="p">,</span> <span class="s1">&#39;Product2&#39;</span><span class="p">,</span> <span class="nv">$ids</span><span class="p">);</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$results</span><span class="p">);</span>
<span class="c1">// results:</span>
<span class="c1">// Array</span>
<span class="c1">// (</span>
<span class="c1">//     [0] =&gt; stdClass Object</span>
<span class="c1">//         (</span>
<span class="c1">//             [Id] =&gt; 01tA0000000YU48IAG</span>
<span class="c1">//             [Description] =&gt; FINE, Second Widget.  You can be the best product.</span>
<span class="c1">//             [Name] =&gt; First Epixa Widget</span>
<span class="c1">//         )</span>
<span class="c1">//     [1] =&gt; stdClass Object</span>
<span class="c1">//         (</span>
<span class="c1">//             [Id] =&gt; 01tA0000000YU4DIAW</span>
<span class="c1">//             [Description] =&gt; No, THIS Widget is the best product of all time!</span>
<span class="c1">//             [Name] =&gt; Second Epixa Widget</span>
<span class="c1">//         )</span>
<span class="c1">// )</span>
</code></pre></div>

<h2>SforceEnterpriseClient::getUpdated()</h2>

<p>Whenever you are polling for data from Salesforce, <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_getupdated.htm">getUpdated()</a> is probably the method you&#39;re going to use.  This will return an object that contains an array of all the unique Ids of objects that match the supplied type that were updated between the timestamps you pass it.  In addition to the array of Ids, the returned object also contains a timestamp in DATE_ATOM format of the last date covered in your getUpdated call that you can store and use for the start date in your next call to getUpdated().  Couple this with a call to retrieve(), and you can easily query for all objects updated since the last time your script ran.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$results</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getUpdated</span><span class="p">(</span><span class="s1">&#39;Product2&#39;</span><span class="p">,</span> <span class="nb">strtotime</span><span class="p">(</span><span class="s1">&#39;-7 days&#39;</span><span class="p">),</span> <span class="nb">time</span><span class="p">());</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$results</span><span class="p">);</span>
<span class="c1">// stdClass Object</span>
<span class="c1">// (</span>
<span class="c1">//     [ids] =&gt; Array</span>
<span class="c1">//         (</span>
<span class="c1">//             [0] =&gt; 01tA0000000YU48IAG</span>
<span class="c1">//             [1] =&gt; 01tA0000000YU4DIAW</span>
<span class="c1">//         )</span>
<span class="c1">//     [latestDateCovered] =&gt; 2010-05-19T00:29:00.000Z</span>
<span class="c1">// )</span>
</code></pre></div>

<h2>SforceEnterpriseClient::delete()</h2>

<p>This does not really require any explanation; however, it is worth noting that objects deleted through the <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_delete.htm">delete()</a> method are only logically deleted.  This will simply set the IsDeleted flag to true.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;01tA0000000YU4D&#39;</span><span class="p">,</span> <span class="s1">&#39;01tA0000000YU48&#39;</span><span class="p">));</span>
<span class="c1">// result: Two products with the passed Ids are marked as deleted in salesforce</span>
</code></pre></div>

<h2>SforceEnterpriseClient::getDeleted()</h2>

<p>The method <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_getdeleted.htm">getDeleted()</a> is very similar to getUpdated() -- it takes exactly the same parameters, but it returns a slightly different object.  The returned object still has the latestDateCovered property, but it also has an earliestDateAvailable property which is a DATE_ATOM formatted timestamp of the last physically deleted object.  Rather than having an array of Ids, the object returned by getDeleted() has an array of objects each with the Id of the deleted object and the timestamp of when that object was actually deleted.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$results</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getDeleted</span><span class="p">(</span><span class="s1">&#39;Product2&#39;</span><span class="p">,</span> <span class="nb">strtotime</span><span class="p">(</span><span class="s1">&#39;-7 days&#39;</span><span class="p">),</span> <span class="nb">time</span><span class="p">());</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$results</span><span class="p">);</span>
<span class="c1">// stdClass Object</span>
<span class="c1">// (</span>
<span class="c1">//     [deletedRecords] =&gt; Array</span>
<span class="c1">//         (</span>
<span class="c1">//             [0] =&gt; stdClass Object</span>
<span class="c1">//                 (</span>
<span class="c1">//                     [deletedDate] =&gt; 2010-05-19T02:38:31.000Z</span>
<span class="c1">//                     [id] =&gt; 01tA0000000YU48IAG</span>
<span class="c1">//                 )</span>
<span class="c1">//             [1] =&gt; stdClass Object</span>
<span class="c1">//                 (</span>
<span class="c1">//                     [deletedDate] =&gt; 2010-05-19T02:38:31.000Z</span>
<span class="c1">//                     [id] =&gt; 01tA0000000YU4DIAW</span>
<span class="c1">//                 )</span>
<span class="c1">//         )</span>
<span class="c1">//     [earliestDateAvailable] =&gt; 2010-03-12T01:13:00.000Z</span>
<span class="c1">//     [latestDateCovered] =&gt; 2010-05-19T00:29:00.000Z</span>
<span class="c1">// )</span>
</code></pre></div>

<h2>Hold up, there are some &#39;gotchas&#39;</h2>

<ol>
<li>Calls to retrieve() do not always return an array of objects!  If only one result is returned, only that object will be returned.  I cannot begin to imagine who made this bonehead-decision, but it can be frustrating if you&#39;re not expecting it.</li>
<li>The PHP Toolkit handles some errors by throwing exceptions.  This is immensely convenient.  However, not all errors are thrown!  For methods such as create(), make sure you check the returned value for the property &#39;errors&#39;.  In addition to signifying that an error has occurred, the &#39;errors&#39; object contains information that can be useful in debugging the issue.</li>
</ol>

<p>Integrating with Salesforce can be a frustrating experience, but it is hard to avoid if you work with any small to medium companies that take their CRM solutions seriously.  There are many more possibilities beyond what I outlined here, so I recommend that you familiarize yourself with the API documentation that I linked to throughout this article before beginning any Salesforce integration project.</p>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>The Best Models are Easy Models</title>
    <link href="http://epixa.com/2010/05/the-best-models-are-easy-models.html"/>
    <id>http://epixa.com/?p=112</id>
    <updated>2010-05-06T02:48:47Z</updated>
    <content type="html"><![CDATA[<p>Models are one of the most important building blocks to any well-formed application, but a few common misconceptions persist throughout the development community that can make working with models excruciating.  A properly constructed model should not only be powerful, but it should be extremely easy to work with.</p>

<p>While models do contain specific data, they are far more than simple data structures.  They should contain all logic possible to manage, manipulate, and validate the correctness of data as it is updated.  By treating your models as nothing more than a place to dump your data, you are doing yourself and your application a severe disservice; your business logic is going to be scattered throughout the rest of your application, and you will have a progressively more difficult time as you try to maintain and build upon your existing system.  Do not fall into the <a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html">anemic model</a> trap.</p>

<p>In addition, models should be independent of the data-access layer.  If I am modeling a blog article, the article should not know nor care to know whether it was created from a mysql database, an xml file, user input, or the divine spaghetti monster.  No matter how it was populated or where it was persisted, the blog article is a blog article, and that is all that is important.</p>

<p>To manage my data access, I am a huge proponent of <a href="http://www.doctrine-project.org">Doctrine 2</a>.  Of which, one of my favorite features is that my models are completely decoupled from Doctrine itself.  This means there is no base model class that defines a ton of functionality for interacting with your data abstraction, so you have near endless flexibility when it comes to creating your models.  However, just because you are not <em>required</em> to extend a base record class does not mean that working with many of your models cannot be improved with some simple, abstract implementations.  Utilizing a simple abstract model and a few best practices can ensure your models remain incredibly versatile while still preserving the strict integrity of your data.</p>

<p>Let&#39;s start with a simple blog article model:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Blog</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Epixa\AbstractModel</span><span class="p">;</span>

<span class="sd">/**</span>
<span class="sd"> * @Entity</span>
<span class="sd"> * @Table(name=&quot;blog_article&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">ArticleModel</span> <span class="k">extends</span> <span class="nx">AbstractModel</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * @Id @Column(type=&quot;integer&quot;)</span>
<span class="sd">     * @GeneratedValue</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     * @Column(type=&quot;string&quot;)</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$title</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     * @Column(type=&quot;date&quot;)</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$date</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     * @Column(type=&quot;text&quot;)</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$content</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     * For demonstration purposes only</span>
<span class="sd">     */</span>
    <span class="k">protected</span> <span class="nv">$_hiddenProperty</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<p>In our AbstractModel, we will utilize php&#39;s magic methods to provide access to our entity properties in both a convenient and secure way.  All calls to retrieve a property&#39;s value will map through an appropriate accessor if one exists, and all attempts to set an entity property will map through an appropriate mutator if one exists.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Blog</span><span class="p">;</span>

<span class="k">abstract</span> <span class="k">class</span> <span class="nc">AbstractModel</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * Map a call to get a property to its corresponding accessor if it exists.</span>
<span class="sd">     * Otherwise, get the property directly.</span>
<span class="sd">     *</span>
<span class="sd">     * Ignore any properties that begin with an underscore so not all of our</span>
<span class="sd">     * protected properties are exposed.</span>
<span class="sd">     *</span>
<span class="sd">     * @param  string $name</span>
<span class="sd">     * @return mixed</span>
<span class="sd">     * @throws \LogicException If no accessor/property exists by that name</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__get</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;_&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$accessor</span> <span class="o">=</span> <span class="s1">&#39;get&#39;</span><span class="o">.</span> <span class="nx">ucfirst</span><span class="p">(</span><span class="nv">$name</span><span class="p">);</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">method_exists</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$accessor</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$accessor</span><span class="p">();</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="nb">property_exists</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$name</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$name</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\LogicException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
            <span class="s1">&#39;No property named `%s` exists&#39;</span><span class="p">,</span>
            <span class="nv">$name</span>
        <span class="p">));</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Map a call to set a property to its corresponding mutator if it exists.</span>
<span class="sd">     * Otherwise, set the property directly.</span>
<span class="sd">     *</span>
<span class="sd">     * Ignore any properties that begin with an underscore so not all of our</span>
<span class="sd">     * protected properties are exposed.</span>
<span class="sd">     * </span>
<span class="sd">     * @param  string $name</span>
<span class="sd">     * @param  mixed  $value</span>
<span class="sd">     * @return void</span>
<span class="sd">     * @throws \LogicException If no mutator/property exists by that name</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__set</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;_&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$mutator</span> <span class="o">=</span> <span class="s1">&#39;set&#39;</span><span class="o">.</span> <span class="nx">ucfirst</span><span class="p">(</span><span class="nv">$name</span><span class="p">);</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">method_exists</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$mutator</span><span class="p">))</span> <span class="p">{</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$mutator</span><span class="p">(</span><span class="nv">$value</span><span class="p">);</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="nb">property_exists</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$name</span><span class="p">))</span> <span class="p">{</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$name</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\LogicException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
            <span class="s1">&#39;No property named `%s` exists&#39;</span><span class="p">,</span>
            <span class="nv">$name</span>
        <span class="p">));</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Map a call to a non-existent mutator or accessor directly to its</span>
<span class="sd">     * corresponding property</span>
<span class="sd">     *</span>
<span class="sd">     * @param  string $name</span>
<span class="sd">     * @param  array  $arguments</span>
<span class="sd">     * @return mixed</span>
<span class="sd">     * @throws \BadMethodCallException If no mutator/accessor can be found</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__call</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$arguments</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="s1">&#39;set&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$property</span> <span class="o">=</span> <span class="nb">lcfirst</span><span class="p">(</span><span class="nx">substr</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="mi">3</span><span class="p">));</span>

                <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$property</span> <span class="o">=</span> <span class="nb">array_shift</span><span class="p">(</span><span class="nv">$arguments</span><span class="p">);</span>
                <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">===</span> <span class="nb">strpos</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="s1">&#39;get&#39;</span><span class="p">))</span> <span class="p">{</span>
                <span class="nv">$property</span> <span class="o">=</span> <span class="nb">lcfirst</span><span class="p">(</span><span class="nx">substr</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="mi">3</span><span class="p">));</span>

                <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$property</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\BadMethodCallException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
            <span class="s1">&#39;No method named `%s` exists&#39;</span><span class="p">,</span>
            <span class="nv">$name</span>
        <span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>With these simple methods, our protected entity properties are accessible like public properties, but individual models can ensure that their access and modification is still bound by filtering/validation through mutators and accessors.  Let&#39;s implement some of these in our article model:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="k">class</span> <span class="nc">ArticleModel</span> <span class="k">extends</span> <span class="nx">AbstractModel</span>
<span class="p">{</span>
    <span class="c1">// ...</span>

    <span class="sd">/**</span>
<span class="sd">     * Constructor</span>
<span class="sd">     * </span>
<span class="sd">     * Set the date to right now</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setDate</span><span class="p">(</span><span class="s1">&#39;now&#39;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * @throws \BadMethodCallException Every time</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">setId</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\BadMethodCallException</span><span class="p">(</span><span class="s1">&#39;Cannot set article id directly&#39;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Set the article title</span>
<span class="sd">     * </span>
<span class="sd">     * @param  string $title</span>
<span class="sd">     * @return ArticleModel *Provides fluid interface*</span>
<span class="sd">     * @throws \InvalidArgumentException If title is less than 3 characters</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">setTitle</span><span class="p">(</span><span class="nv">$title</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$title</span> <span class="o">=</span> <span class="nx">trim</span><span class="p">(</span><span class="nv">$title</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$title</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">\InvalidArgumentException</span><span class="p">(</span><span class="s1">&#39;Title must be more than 3 chars&#39;</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">title</span> <span class="o">=</span> <span class="nv">$title</span><span class="p">;</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Set the article date</span>
<span class="sd">     * </span>
<span class="sd">     * @param  mixed $date</span>
<span class="sd">     * @return ArticleModel *Provides fluid interface*</span>
<span class="sd">     * @throws \InvalidArgumentException If invalid date is given</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">setDate</span><span class="p">(</span><span class="nv">$date</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">is_int</span><span class="p">(</span><span class="nv">$date</span><span class="p">))</span> <span class="p">{</span>
            <span class="nv">$date</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\DateTime</span><span class="p">(</span><span class="s2">&quot;@</span><span class="si">$date</span><span class="s2">&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">is_string</span><span class="p">(</span><span class="nv">$date</span><span class="p">))</span> <span class="p">{</span>
            <span class="nv">$date</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\DateTime</span><span class="p">(</span><span class="nv">$date</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$date</span> <span class="nx">instanceof</span> <span class="nx">\DateTime</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">\InvalidArgumentException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span>
                <span class="s1">&#39;Expecting string, int or DateTime but `%s` given&#39;</span><span class="p">,</span>
                <span class="nb">gettype</span><span class="p">(</span><span class="nv">$date</span><span class="p">)</span>
            <span class="p">));</span>
        <span class="p">}</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">date</span> <span class="o">=</span> <span class="nv">$date</span><span class="p">;</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Get the article date in a human readable format</span>
<span class="sd">     * </span>
<span class="sd">     * @return string</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getFormattedDate</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">date</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">&#39;F j, Y&#39;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>With that, our article model filters and validates incoming and outgoing data.  Our article date is set immediately upon instantiation, the title is always trimmed and its length validated, the date can be set by multiple different types of values but is always stored as a DateTime, and we can utilize a convenience accessor (even as a property) to get the date formatted as a string.</p>

<p>If you are the type of developer that insists on having 100% data integrity in your models at all times, you could take this filtering and validation one step further by passing all required fields as arguments in the constructor.  On the other hand, if you&#39;re like me you would abstract out the logic for handling data validation, so you could reuse the validation in forms that accept input from the user to populate your models and create a prePersist <a href="http://www.doctrine-project.org/documentation/manual/2_0/en/events#lifecycle-callbacks">lifecycle callback</a> (Doctrine only) that runs through the validation before a new model is persisted in the database.</p>

<p>To finish this up, here are some ad hoc examples of code using the ArticleModel:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$article</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Blog\ArticleModel</span><span class="p">();</span>

<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">title</span> <span class="o">=</span> <span class="s1">&#39;   My Article Title &#39;</span><span class="p">;</span>
<span class="k">echo</span> <span class="nv">$article</span><span class="o">-&gt;</span><span class="na">title</span><span class="p">;</span>
<span class="c1">// outputs: My Article Title</span>

<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">title</span> <span class="o">=</span> <span class="s1">&#39;My&#39;</span><span class="p">;</span>
<span class="c1">// throws exception: Title must be more than 3 chars</span>

<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">date</span> <span class="o">=</span> <span class="s1">&#39;yesterday&#39;</span><span class="p">;</span>
<span class="k">echo</span> <span class="nv">$article</span><span class="o">-&gt;</span><span class="na">formattedDate</span><span class="p">;</span>
<span class="c1">// outputs: May 5, 2010</span>

<span class="k">echo</span> <span class="nv">$article</span><span class="o">-&gt;</span><span class="na">setContent</span><span class="p">(</span><span class="s1">&#39;This is my content&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getContent</span><span class="p">();</span>
<span class="c1">// outputs: This is my content</span>

<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">_hiddenProperty</span><span class="p">;</span>
<span class="c1">// throws exception: No property named `_hiddenProperty` exists</span>
</code></pre></div>

<h2>Other Resources about Models</h2>

<ul>
<li><a href="http://weierophinney.net/matthew/archives/202-Model-Infrastructure.html">Model Infrastructure - Matthew Weier O&#39;Phinner</a></li>
<li><a href="http://matthewturland.com/2010/03/26/models-in-zend-framework/">Models in Zend Framework - Matthew Turland</a></li>
</ul>
]]></content>
  </entry>
  
  
  
  
    <entry>
    <title>Organize Your Project like a Pro with PHP Namespaces</title>
    <link href="http://epixa.com/2010/04/organize-your-project-like-a-pro-with-php-namespaces.html"/>
    <id>http://epixa.com/?p=29</id>
    <updated>2010-04-17T00:51:26Z</updated>
    <content type="html"><![CDATA[<p>PHP took a huge step forward in June 2009 with the release of version 5.3.  It wasn&#39;t quite as big of a change as version 5.0, but the release did introduce a number of new language features including <a href="http://php.net/namespace">namespaces</a> -- an addition that can dramatically improve the way you organize your PHP in an object oriented paradigm.</p>

<p>Anyone who&#39;s written code in Java, C++, or for any language in ASP.NET has had the pleasure of working with them, but we PHP developers have had to settle with emulating namespaces by defining long class prefixes.</p>

<p>Prefixes serve their primary purpose well: when used correctly, they will ensure that your class names do not have naming conflicts.  Unfortunately, they are long and pedantic, and provide no additional benefits.  Take, for example, the following class name: <em>Zend<em>Service</em>DeveloperGarden<em>Response</em>ConferenceCall_CreateConferenceResponseType</em> which can be found in <a href="http://framework.zend.com">Zend Framework</a>.  At 81 characters, the name of this class by itself breaks the <a href="http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html#coding-standard.php-file-formatting.max-line-length">recommended line length</a> in Zend&#39;s own coding standard, and it is not even the longest class name in the framework!</p>

<p>Namespaces provide other benefits than shorter class names, though.  Consider the following:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Epixa\\Service</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Epixa\\Model\\ArticleModel</span><span class="p">,</span>
    <span class="nx">Epixa\\Model\\AuthorModel</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">ArticleService</span> <span class="k">extends</span> <span class="nx">AbstractService</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * @param  string      $title</span>
<span class="sd">     * @param  AuthorModel $author</span>
<span class="sd">     * @return ArticleModel</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">create</span><span class="p">(</span><span class="nv">$title</span><span class="p">,</span> <span class="nx">AuthorModel</span> <span class="nv">$author</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$article</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ArticleModel</span><span class="p">();</span>
        <span class="nv">$article</span><span class="o">-&gt;</span><span class="na">title</span> <span class="o">=</span> <span class="nv">$title</span><span class="p">;</span>
        <span class="nv">$article</span><span class="o">-&gt;</span><span class="na">author</span> <span class="o">=</span> <span class="nv">$author</span><span class="p">;</span>
        <span class="k">return</span> <span class="nv">$article</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>The namespace declaration immediately gives you a clear indication of what type of class is being declared -- a service within the Epixa library.</p>

<p>Along with simply declaring a namespace, the file then uses other namespaces.  In this particular case, I chose to import the specific classes ArticleModel and AuthorModel.  I could have simply used the Epixa\Model namespace, and then I would be able to instantiate any models within the namespace, but importing the specific models that I plan to use is a clear way to define class dependencies.</p>

<p>At this point, we haven&#39;t even declared the class, yet we already know what type of class it will be and what dependencies it will have.  Throughout the rest of the class declaration and definition, the concise class names are used.  Long, ugly prefixes are left in the dust, and the code is cleaner and clearer as a result.</p>

<h2>But Court, it&#39;ll be <em>forever</em> until the community adopts PHP 5.3!</h2>

<p>While this sentiment might have been true for past releases of PHP, developers finally seem to be coming around to the notion that software drives the community forward.  When software increases its requirements, server administrators <em>will</em> follow suit.</p>

<p>In less than a year, industry-leading frameworks such as <a href="http://framework.zend.com/wiki/display/ZFDEV2/Zend+Framework+2.0+Roadmap">Zend Framework</a> and <a href="http://www.symfony-project.org/blog/2009/10/27/why-will-symfony-2-0-finally-use-php-5-3">Symfony</a> have decided to utilize these new features to such an extent that 5.3 will be a minimum requirement.  The Doctrine team is well into its development roadmap which includes a new <a href="http://www.doctrine-project.org/documentation/manual/2_0/en/introduction#requirements">minimum requirement of PHP 5.3</a>; they have already slated an <a href="http://www.doctrine-project.org/blog/doctrine-future-roadmap">end-of-life date</a> for their 1.x branch and are taking the release of PHP 5.3 not as a challenge but as an opportunity to radically improve their codebase.</p>

<p>Don&#39;t be left in the dust; the PHP community is moving forward with version 5.3, and an <a href="http://www.php.net/manual/en/migration53.incompatible.php">easy upgrade path</a> means you can start benefiting from incredible language features such as namespaces immediately.</p>
]]></content>
  </entry>
  
  
  

</feed>
