<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TBNL &#187; articles</title>
	<atom:link href="http://www.tibobeijen.nl/blog/category/articles/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tibobeijen.nl</link>
	<description>...another view on the web and how it's built</description>
	<lastBuildDate>Wed, 06 Jul 2011 19:28:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>DDD using Doctrine 2: A case study</title>
		<link>http://www.tibobeijen.nl/blog/2011/06/27/ddd-using-doctrine-2-a-case-study/</link>
		<comments>http://www.tibobeijen.nl/blog/2011/06/27/ddd-using-doctrine-2-a-case-study/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 13:06:57 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Doctrine 2]]></category>
		<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=704</guid>
		<description><![CDATA[Nowadays developing web applications usually requires a flexible process due to changing business logic, shifting priorities or new insights. Besides choosing the right methodology this also requires designing the application in such a way that this flexibility can be achieved. Domain Driven Design fits this process as it isolates business logic in the Domain layer [...]]]></description>
			<content:encoded><![CDATA[<p>Nowadays developing web applications usually requires a flexible process due to changing  business logic, shifting priorities or new insights. Besides choosing the right methodology this also requires designing the application in such a way that this flexibility can be achieved. </p>
<p><a href="http://domaindrivendesign.org/">Domain Driven Design</a> fits this process as it isolates business logic in the Domain layer and separates it from infrastructure and presentation layers. Questions like where or how to store data or what to build (website, mobile app, API) can be addressed separately. </p>
<p><a href="http://www.doctrine-project.org/projects/orm/2.0/docs/en">Doctrine 2</a> provides PHP developers with a powerful tool to create a Domain layer that contains business logic that is easy to unit test and therefore easy to expand upon in iterations.</p>
<p>In this article I will show how to implement a specific case using Doctrine 2. Full code accompanying this article can be <a href="https://github.com/TBeijen/DDD-HRM/tree/v001">found on GitHub</a>.<br />
<span id="more-704"></span></p>
<h3>In this article</h3>
<ul>
<li><a href="#caseOutline">Case outline</a></li>
<li><a href="#descriptionOfEntities">Description of Entities</a>
<ul>
<li><a href="#entUser">User</a></li>
<li><a href="#entTimeSheet">TimeSheet</a></li>
<li><a href="#entTimeSheetStatusChange">TimeSheetStatusChange</a></li>
<li><a href="#entNotIncluded">What&#8217;s not included</a></li>
</ul>
</li>
<li><a href="#implementing">Implementing requirements using Doctrine 2</a>
<ul>
<li><a href="#req1">User should have an e-mail address that is unique</a></li>
<li><a href="#req2">A TimeSheet should always belong to a user which, once specified, cannot be changed</a></li>
<li><a href="#req3">A new TimeSheet by default should have a status ‘open’</a></li>
<li><a href="#req4">Status changes should only be allowed in specific order</a></li>
<li><a href="#req5">A new TimeSheetStatusChange should have a dateApplied that is equal or more recent than the most recent TimeSheetStatusChange</a></li>
<li><a href="#req6">TimeSheetStatusChanges must have reference to a TimeSheet but at the same time must be valid.</a></li>
</ul>
</li>
<li><a href="#beyondDatabase">Where the domain model goes beyond the database model</a></li>
<li><a href="#concluding">Concluding</a></li>
</ul>
<h3 id="caseOutline">Case outline</h3>
<p>The application developed is a time registration tool that allows users to enter per-day time sheets and submit them for approval. A manager will approve or disapprove the time sheet. The business requirement this iteration focuses on is the tracking of time sheet status history and only allowing specific status changes. In subsequent iterations features like registrations, tasks, projects and permissions will be implemented.</p>
<h3 id="descriptionOfEntities">Description of entities</h3>
<p><a href="http://www.tibobeijen.nl/blog/wp-content/uploads/2011/06/yuml-ddd-hrm-001.21.png"><img src="http://www.tibobeijen.nl/blog/wp-content/uploads/2011/06/yuml-ddd-hrm-001.21-500x46.png" alt="" title="User, TimeSheet and TimeSheetStatusChange entities" width="500" height="46" class="aligncenter size-medium wp-image-723" /></a></p>
<h4 id="entUser">User</h4>
<p>A User can login, has attributes and &#8211; interesting for this case &#8211; can have timesheets. A user’s email address can be changed at any time but should be unique as it serves as the login name.</p>
<h4 id="entTimeSheet">TimeSheet</h4>
<p>A TimeSheet holds registrations of a single user, the registrant. Those registrations will be reviewed by a manager who will approve or disapprove them on a per-timesheet basis. The timesheet therefore can have the following statuses:</p>
<ul>
<li>Open &#8211; The default status of every new timesheet</li>
<li>Submitted &#8211; The timesheet has been submitted for approval</li>
<li>Approved &#8211; The manager has approved the timesheet</li>
<li>Disapproved &#8211; The manager has disapproved the timesheet</li>
<li>Final &#8211; The timesheet’s registrations have been processed and therefore can never be changed. Examples of processing are periodic business reports or salary payment.</li>
</ul>
<p>Status changes will be stored to allow a history of status changes to be shown. The most recent status change reflects the timesheet’s ‘current’ status.</p>
<p>Status changes are only allowed to be added in a specific order.</p>
<h4 id="entTimeSheetStatusChange">TimeSheetStatusChange</h4>
<p>Each subsequent status of a timesheet is represented by a TimeSheetStatusChange. Properties of a status change are the status and the date the new status has been applied. Once stored, the status and date properties of a status change are not allowed to change to prevent ‘breaking’ the history of status changes a timesheet went through.</p>
<h4 id="entNotIncluded">What is not included</h4>
<p>As mentioned in the case outline, some obvious entities or properties are out of scope, such as the registrations themselves and the date the timesheet applies to. For the business requirements described previously they are not relevant so, in true Agile fashion, they will be implemented in subsequent iterations.</p>
<h3 id="implementing">Implementing requirements using Doctrine 2</h3>
<h4 id="req1">User should have an e-mail address that is unique</h4>
<p>This is achieved by requiring an e-mail address in the constructor and by setting the column definition of the property to be unique.</p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/User.php">Domain/Entity/User.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> User
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @Column(type=&quot;string&quot;, length=128, unique=true)
     * @var string
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$email</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<h4 id="req2">A TimeSheet should always belong to a user which, once specified, cannot be changed</h4>
<p>This is enforced by requiring a User entity to be supplied in the constructor. As there’s no point in changing the registrant of an existing TimeSheet, the registrant can only be specified on creation. Therefore there is no setter for the registrant property.</p>
<p>(See next code example)</p>
<h4 id="req3">A new TimeSheet by default should have a status ‘open’</h4>
<p>In the TimeSheet constructor, a new TimeSheetStatusChange is created and added to the status changes. </p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheet.php">Domain/Entity/TimeSheet.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheet
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Constructor requiring a registrant user instance
     * 
     * @param User $registrant
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>User <span style="color: #000088;">$registrant</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registrant</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$registrant</span><span style="color: #339933;">;</span>
&nbsp;
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusChanges</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ArrayCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addStatusChange</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> TimeSheetStatusChange<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'open'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// no setRegistrant()</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<div class="sidenote">
<p>One might think that adding a default status change to a new instance would result in a duplicate first status change when the persisted status changes are loaded while fetching the TimeSheet from the database. This is not the case as Doctrine 2 does not instantiate the constructor of entities. Read more on: <a href="http://www.doctrine-project.org/blog/doctrine-2-give-me-my-constructor-back">Doctrine 2: Give me my constructor back</a></p>
</div>
<h4 id="req4">Status changes should only be allowed in specific order</h4>
<p>This is achieved by validating each TimeSheetStatusChange that is added via the addStatusChange method. Only specific transitions are allowed.</p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheet.php">Domain/Entity/TimeSheet.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheet
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Performs status change validation logic
     * 
     * @param string $statusChange
     * @return boolean
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> _validateNextStatus<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nextStatus</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
    	<span style="color: #666666; font-style: italic;">// make exception for initial adding of open status</span>
    	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$nextStatus</span> <span style="color: #339933;">===</span> <span style="color: #0000ff;">'open'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusChanges</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #666666; font-style: italic;">// validate status changes map</span>
    	<span style="color: #000088;">$allowedChangeMap</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    		<span style="color: #0000ff;">'open'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'submitted'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    		<span style="color: #0000ff;">'submitted'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'approved'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'disapproved'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    		<span style="color: #0000ff;">'approved'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'final'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'disapproved'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    		<span style="color: #0000ff;">'disapproved'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'submitted'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'approved'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    		<span style="color: #0000ff;">'final'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    	<span style="color: #000088;">$currentStatus</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nextStatus</span><span style="color: #339933;">,</span> <span style="color: #000088;">$allowedChangeMap</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$currentStatus</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4 id="req5">A new TimeSheetStatusChange should have a dateApplied that is equal or more recent than the most recent TimeSheetStatusChange</h4>
<p>The dateApplied property is settable because it can’t be assumed that the time at which the change is entered into the application reflects the actual time of the change (An example would be paper forms that are collected and entered once a week). Therefore the dateApplied property is validated at the same time the status is validated. Furthermore, once added, the dateApplied property cannot be changed so there is no setter. When loading a TimeSheet, the TimeSheetStatusChanges are fetched in order by specifying the <a href="http://www.doctrine-project.org/docs/orm/2.0/en/reference/annotations-reference.html#orderby">orderBy</a> attribute in the association.</p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheet.php">Domain/Entity/TimeSheet.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheet
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @OneToMany(targetEntity=&quot;Domain\Entity\TimeSheetStatusChange&quot;, mappedBy=&quot;timeSheet&quot;, cascade={&quot;persist&quot;}, orphanRemoval=true)
     * @OrderBy({&quot;dateApplied&quot; = &quot;ASC&quot;, &quot;id&quot; = &quot;ASC&quot;})
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$statusChanges</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Validates if the date of the statusChange given is later than the date
     * of the last statusChange present
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> _validateNextStatusChangeDate<span style="color: #009900;">&#40;</span>TimeSheetStatusChange <span style="color: #000088;">$statusChange</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
    	<span style="color: #666666; font-style: italic;">// if no statusChanges present yet any date is valid</span>
    	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusChanges</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #000088;">$currentDate</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLastStatusChange</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDateApplied</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$nextDate</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$statusChange</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDateApplied</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    	<span style="color: #666666; font-style: italic;">// enable once tests finish</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$nextDate</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$currentDate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4 id="req6">TimeSheetStatusChanges must have reference to a TimeSheet but at the same time must be valid.</h4>
<p>It can be prevented to store a TimeSheetStatusChange without reference to a TimeSheet by explictly specifying the joinColumn and setting the nullable attribute to false.</p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheetStatusChange.php">Domain/Entity/TimeSheetStatusChange.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheetStatusChange
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @ManyToOne(targetEntity=&quot;Domain\Entity\TimeSheet&quot;, inversedBy=&quot;statusChanges&quot;)
     * @JoinColumn(name=&quot;timesheet_id&quot;, referencedColumnName=&quot;id&quot;, nullable=false)
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$timeSheet</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This still leaves the possibility to set ‘any’ TimeSheet and thereby skipping validation that would normally be done in TimeSheet::addStatusChange(). To prevent this, TimeSheetStatusChange::setTimeSheet() verifies if the TimeSheet’s last status is the current TimeSheetStatusChange instance. </p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheet.php">Domain/Entity/TimeSheet.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheetStatusChange
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Sets the timeSheet.
     * 
     * Purpose is to have the reference to the timeSheet set when adding a 
     * new TimeSheetStatusChange to a TimeSheet. Therefore this method validates
     * if the timeSheet has the this instance as the last statusChange.
     * 
     * @param TimeSheet $timeSheet
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setTimeSheet<span style="color: #009900;">&#40;</span>TimeSheet <span style="color: #000088;">$timeSheet</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
    	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$timeSheet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLastStatusChange</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> \InvalidArgumentException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Cannot set TimeSheet if not having current instance as lastStatusChange'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">timeSheet</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$timeSheet</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The result is that the only way to create a persistable TimeSheetStatusChange is by adding it to the TimeSheet which will:</p>
<ol>
<li>Validate if the status change is allowed</li>
<li>Adds it to the list of status changes, making it the ‘last’ status change</li>
<li>In turn set the timeSheet reference on the TimeSheetStatusChange</li>
</ol>
<p>Persisting a TimeSheet is propagated to the status changes by setting the cascade attribute in the association definition</p>
<p><em><a href="https://github.com/TBeijen/DDD-HRM/blob/v001/Domain/Entity/TimeSheet.php">Domain/Entity/TimeSheet.php</a></em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TimeSheetStatusChange
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @OneToMany(targetEntity=&quot;Domain\Entity\TimeSheetStatusChange&quot;, mappedBy=&quot;timeSheet&quot;, cascade={&quot;persist&quot;}, orphanRemoval=true)
     * @OrderBy({&quot;dateApplied&quot; = &quot;ASC&quot;, &quot;id&quot; = &quot;ASC&quot;})
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$statusChanges</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3 id="beyondDatabase">Where the domain model goes beyond the database model</h3>
<p>One might be tempted to see an ORM as merely a convenient way to access and manipulate data contained in a database. While Doctrine 2 fits such a scenario (Entities can be modeled to reflect an already existing database) the real power shines when entities are modeled with business logic in mind instead of just being a collection of setters and getters matching the database fields.</p>
<p>Features displayed in these examples that can not be expressed in a database model include:</p>
<ul>
<li>Forcing each timesheet to start with a status ‘open’</li>
<li>Only allowing specific timesheet status changes:
<ul>
<li>By preventing ‘floating’ timesheetsStatusChanges to be created.</li>
<li>By preventing change of dateApplied and status properties, once created</li>
</ul>
</li>
<li>Make values, once persisted immutable. (the registrant property of a timesheet, the status and dateApplied properties of a timesheetStatusChange)</li>
</ul>
<h3 id="concluding">Concluding</h3>
<p>As the previous example shows, a Domain model is more than a database model: It should be modeled to comply with business logic required. As a result, for the code in this article I have used <a href="http://www.doctrine-project.org/docs/orm/2.0/en/reference/tools.html">Doctrine tools</a> only for creating entity proxies, <a href="http://www.doctrine-project.org/docs/orm/2.0/en/reference/tools.html#entity-generation">not the entities themselves</a></p>
<p>Furthermore, the fact that business logic is only contained in the Domain layer is illustrated by the facts that in this setup:</p>
<ul>
<li>There is no front-end</li>
<li>There is no framework (Zend Framework, Symfony, Cake, Yii, Solar, all possibilities are open)</li>
<li>There is no specific database. For the tests an in-memory SQLite database is used. In production this will obviously not be the case.</li>
</ul>
<p>Because of this isolation from other layers, domain logic is easily testable as can be seen from <a href="https://github.com/TBeijen/DDD-HRM/tree/v001/Test/Domain/Entity">the test cases</a>.</p>
<p>Credits for the test setup used here go to the example found on Giorgio Sironi&#8217;s <a href="https://github.com/giorgiosironi/ddd-talk">ddd-talk GitHub page</a>.</p>
<p>In future articles I intend to expand on this case, showing how Domain Driven Design can be used in an Agile development process.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2011/06/27/ddd-using-doctrine-2-a-case-study/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Usability: Autofocus and not breaking the backspace-button</title>
		<link>http://www.tibobeijen.nl/blog/2011/03/14/usability-autofocus-and-not-breaking-the-backspace-button/</link>
		<comments>http://www.tibobeijen.nl/blog/2011/03/14/usability-autofocus-and-not-breaking-the-backspace-button/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 11:32:39 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery plugin]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=672</guid>
		<description><![CDATA[A while ago during a project we were asked to implement autofocus on the generic search field that every page in the application has. At a first glance a pretty straightforward task, from a technical perspective that is. Not from a user perspective, as indicated by a colleague mentioning his dislike of such autofocus fields [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago during a project we were asked to implement autofocus on the generic search field that every page in the application has. At a first glance a pretty straightforward task, from a technical perspective that is. Not from a user perspective, as indicated by a colleague mentioning his dislike of such autofocus fields &#8220;because they prevent backspace going to the previous page&#8221;. In this post I will outline some usability considerations and conclude with a jQuery plugin that will take away some of the possible hindrance of autofocusing a field.</p>
<h3>Usability considerations</h3>
<p>There are some things to consider to determine if such automatic focusing of a search field is actually helpful to the user navigating to the page. Who is <em>the</em> user?</p>
<p>As I was discussing this case with <a href="http://www.architecto.nl">an interaction designer friend</a> (dutch) of mine, he brought up the idea of mimicking the browser&#8217;s backspace behaviour, and discussing it further we concluded that this might be useful in some cases but is definitely not a &#8216;one size fits all&#8217; solution.</p>
<h4>Different goals</h4>
<p>Different users will probably have different goals when navigating to a page. On the google page or a login screen the majority of the users&#8217; goal is to type something in the first input field. On a lot of other pages this won&#8217;t be so obvious. Question then is: Will focusing a search field, if not help, instead <em>hinder</em> the user? For example: A user might have navigated to a page by accident. In that case not being able to go to the previous page by pressing &#8216;backspace&#8217; might indeed hinder the user.</p>
<h4>Different expectations</h4>
<p>Not every user navigates to the previous page by using &#8216;backspace&#8217;, some might not even be aware of that possibility. Not every user expects text entered to automatically appear in an input field. Some users might have enabled the option to directly find text in a page when typing text and find this functionality suddenly broken.</p>
<p><a href="http://diveintohtml5.org/detect.html#input-autofocus">Dive into HTML5</a> has some other nice examples of how autofocus might <em>not</em> be helpful.</p>
<h3>What size fits all?</h3>
<p>As mentioned before, there is no &#8216;one size fits all&#8217; solution. Questions that need to be asked include:</p>
<ul>
<li>How many users might be helped by adding autofocus to a common search field?</li>
<li>How many users might instead be hindered by autofocus?</li>
<li>Are there pages where autofocus on more specific fields (like the main form) is needed which will break consistency throughout the site?</li>
</ul>
<p>This means studying your site, the target audience, their goals and expectations and based on that finding a balance.</p>
<h3>Restoring the backspace: jQuery autofocusBackspace plugin</h3>
<p>If the conclusion of aforementioned considerations is that autofocus indeed <em>is</em> helpful, there is more than one way to achieve this: The first is using the HTML5 autofocus attribute. Another is using javascript to focus the field.</p>
<p>As not all browsers support the autofocus attribute yet, and we wanted to preserve the browser&#8217;s backspace functionality, I created a jQuery plugin that does just that:</p>
<ul>
<li>It focuses the first matching element
<li>It responds to &#8216;backspace&#8217; by navigating to the previous page.
<ul>
<li>Only until a user has entered text
<li>Only until the element loses focus</ul>
</ul>
<p>Refer to GitHub for the <a href="https://github.com/TBeijen/jQuery-plugin-autofocusBackspace">jQuery plugin autospaceBackspace</a>. </p>
<p>Feel free to report problems or ideas for improvement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2011/03/14/usability-autofocus-and-not-breaking-the-backspace-button/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Zend_Form without Zend Framework MVC</title>
		<link>http://www.tibobeijen.nl/blog/2009/12/07/using-zend_form-without-zend-framework-mvc/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/12/07/using-zend_form-without-zend-framework-mvc/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 10:13:13 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_form]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=568</guid>
		<description><![CDATA[Most components of Zend Framework can be used without using the entire framework and Zend_Form is no exception. It&#8217;s a versatile component that can be customized to great extent. The payoff is that seemingly easy tasks can seem quite complex to complete and involve concepts like Decorators and View Helpers. Complexity is increased by the [...]]]></description>
			<content:encoded><![CDATA[<p>Most components of <a href="http://framework.zend.com/">Zend Framework</a> can be used without using the entire framework and <a href="http://framework.zend.com/manual/en/zend.form.html">Zend_Form</a> is no exception. It&#8217;s a versatile component that can be customized to great extent. The payoff is that seemingly easy tasks can seem quite complex to complete and involve concepts like Decorators and View Helpers. Complexity is increased by the fact that most tasks can be achieved in multiple ways.</p>
<p>Forms in general are elements where a lot of parts of an application &#8216;meet&#8217;: Frontend code (HTML/CSS), behavior (JS) and backend processing (validation, filtering and storage). In this post I&#8217;ll show how one can:</p>
<ul>
<li>Use Zend_Form outside the Zend Framework MVC (most likely an existing project)</li>
<li>Separate Form rendering from it&#8217;s structure</li>
<li>Use custom validators and decorators</li>
</ul>
<p>The Form used in this tutorial can be <a href="/static/zend_form_without_mvc/">viewed here</a>. The code can be browsed or downloaded <a href="http://github.com/TBeijen/Zend_Form_Without_MVC">on GitHub</a>.</p>
<h3>Zend_Form components at a glance</h3>
<p>Let&#8217;s start with a quick look at how Zend_Form&#8217;s different components are tied together:</p>
<ul>
<li>A Zend_Form consists of elements, descendants of Zend_Form_Element</li>
<li>Elements can be supplied with Validators and Filters</li>
<li>Both the form and it&#8217;s elements depend on Decorators to generate HTML. Decorators form a &#8216;chain&#8217; where each decorator adds HTML to the result of the previous decorators.</li>
<li>The standard decorators provided by Zend_Form delegate the rendering of the actual HTML to <a href="http://framework.zend.com/manual/en/zend.view.helpers.html">View Helpers</a></li>
</ul>
<h3>Using Zend_Form without the MVC</h3>
<p>As the last point above shows, Zend_Form, through Decorators, makes extensive use of Zend_View helpers. In a Zend_Framework project Zend_Form is able to retrieve the View itself. In other projects (if one wants to use any of Zend_Form&#8217;s default decorators) a View instance has to be supplied to Zend_Form:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$view</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_View<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">doctype</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'XHTML1_TRANSITIONAL'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Form<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setView</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_View<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In this example the doctype is specified in the view. This controls if input elements are rendered with XHTML self-closing tags.</p>
<h3>Separate structure and rendering</h3>
<p>In this tutorial I create a form for an admin interface where basic user-details can be edited. Let&#8217;s assume an ACL implementation dictates that some people can actually <em>edit </em>the details while others are only allowed to <em>view </em>them. I&#8217;ve decided to keep the form definition (the &#8216;model&#8217; side of a form) to a bare minimum and let different renderers (the &#8216;view&#8217; side) control the output. </p>
<p>For re-usability and keeping controller code clean one can best create form objects by creating an instance of a subclass of Zend_Form:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> My_Form_User <span style="color: #000000; font-weight: bold;">extends</span> Zend_Form
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// username</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'username'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'validators'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #666666; font-style: italic;">// arguments: type, breakchain, validator constructor options</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Alnum'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'StringLength'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// email</span>
        <span style="color: #000088;">$EmailValidate</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_Validator_Email<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'email'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'validators'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'EmailAddress'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$EmailValidate</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(As can be seen I create an instance of My_Validate_Email and add that to the email element. We&#8217;ll look into that later. First, let&#8217;s continue with the form definition.)</p>
<p>The init() method is designed for this type of form definition, thereby avoiding the need to duplicate the constructor and it&#8217;s parameter scheme. As can be seen, I only define the form elements and validators. Labels and such I defer to the renderer (more on that later). As this is about integrating Zend_Form into existing projects that are not based on Zend Framework, I assume there is some sort of language-aware component. In this example I use a language pack that returns language-specific results based on tags. Adding a set of checkboxes then looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> My_Form_User <span style="color: #000000; font-weight: bold;">extends</span> Zend_Form
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
        <span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_LanguagePack<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$groupIds</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$groupOptions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$groupIds</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$groupOptions</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'group.label.'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$elmGroup</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Form_Element_MultiCheckbox<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'group'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$elmGroup</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMultiOptions</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$groupOptions</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$elmGroup</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setRequired</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElement</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$elmGroup</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now I create two renderer classes for both the &#8216;edit&#8217; and &#8216;view&#8217; display mode. Both accepting a Zend_Form instance in the constructor. Code below shows how the form is displayed using either rendering class:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$Form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_Form_User<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$RendererEdit</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_Form_Renderer_Edit<span style="color: #009900;">&#40;</span><span style="color: #000088;">$Form</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user_edit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$RendererEdit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$RendererView</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_Form_Renderer_View<span style="color: #009900;">&#40;</span><span style="color: #000088;">$Form</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user_view'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$RendererView</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>But before moving onto the renderers, let&#8217;s look into the aforementioned My_Email_Validator class.</p>
<h3>Adding a custom validator</h3>
<p>When specifying validators by string, as is done with &#8216;EmailAddress&#8217;, Zend_Form adds one of the types of <a href="http://framework.zend.com/manual/en/zend.validate.html">Zend_Validate</a>. For validation not covered by the standard validators one can create a custom validator by extending Zend_Validate_Abstract or implementing Zend_Validator_Interface. For email addresses, a typical scenario would be a custom validator that connects to a database and checks if the given email address is allready used by another user. For this demo I skip the database part, resulting in:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> My_Validator_Email <span style="color: #000000; font-weight: bold;">extends</span> Zend_Validate_Abstract
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$isValid</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> isValid<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span> <span style="color: #339933;">=</span> <span style="color: #339933;">!</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'duplicate@test.com'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getMessages<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'duplicateEmail'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'This email address is allready used'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getErrors<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessages</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now let&#8217;s continue with the two renderer classes:</p>
<h3>Rendering the edit mode</h3>
<p>The basics of the My_Form_Renderer_Edit class constructor are shown below:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> My_Form_Renderer_Edit
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$form</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>Zend_Form <span style="color: #000088;">$form</span><span style="color: #339933;">,</span> <span style="color: #000088;">$form_id</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$view</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_View<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">doctype</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'XHTML1_TRANSITIONAL'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$form</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setView</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_View<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAttrib</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'form_edit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$form_id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAttrib</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$form_id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> My_LanguagePack<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As can be seen this is where I setup the view (as mentioned before) and set id and classname that can be used in CSS. I want the HTML to look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;username-label&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;required&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>* Username<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;element&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;span</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;description&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>(Min 6, max 16 char.)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/span<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>When the render() method is called on the renderer class I do four things:</p>
<ul>
<li>Add a submit element</li>
<li>Setup element properties that are common for all elements</li>
<li>Setup properties on a per-element basis</li>
<li>Setup properties of the form element</li>
</ul>
<p>I&#8217;ll briefly run through those steps. <a href="http://github.com/TBeijen/Zend_Form_Without_MVC/blob/master/htdocs/My_Form_Renderer_Edit.php">Complete code for My_Form_Renderer_Edit</a> can be seen on Github.</p>
<h4>Add a submit element</h4>
<p>As long as the submit value doesn&#8217;t play a role in the processing of entered data I consider this part of the view layer. For example, interaction design might dictate that on long forms submit buttons are placed both above and below the form.</p>
<h4>Setup common properties</h4>
<p>By using the method setElementDecorators() of Zend_Form, all default decorators are replaced by the ones specified. The decorators that fit my needs are ViewHelper (renders the element itself) and Description, resulting in:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> setupElementsCommon<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setElementDecorators</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'ViewHelper'</span><span style="color: #339933;">,</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Description'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'placement'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'append'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'tag'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'span'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'class'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'description'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
         <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<h4>Setup per-element properties</h4>
<p>Here I add additional decorators. First I setup the element&#8217;s label and description properties by using the language pack, then I add the appropriate decorators. Furthermore I add some additional classnames to elements. If the element has an error I not only want to display the errors (using a custom decorator, more on that later). I also want to give the HTML element wrapped around all of the parts an &#8216;error&#8217; classname.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">        <span style="color: #000088;">$elmHasError</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$elm</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessages</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$liClass</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$elmHasError</span> ? <span style="color: #0000ff;">'error'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$elm</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDecorator</span><span style="color: #009900;">&#40;</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'outerLi'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'HtmlTag'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tag'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'li'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'class'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$liClass</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h4>Setup the form object</h4>
<p>Finally the Form is configured. After removing all existing decorators, three decorators are added. The only difference with the default set of decorators is the UL element used in the HtmlTag decorator:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> setupForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clearDecorators</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDecorator</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FormElements'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDecorator</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HtmlTag'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tag'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ul'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDecorator</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Form'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Adding a custom decorator</h3>
<p>The complete code shows that instead of the default &#8216;Errors&#8217; decorator I provide my own. This way I can retrieve the error messages provided by the form element and then replace them with messages retrieved from the languagePack. A custom decorator needs to extend Zend_Form_Decorator_Abstract or implement Zend_Form_Decorator_Interface. Excerpts from <a href="http://github.com/TBeijen/Zend_Form_Without_MVC/blob/master/htdocs/My_Decorator_Errors.php">My_Decorator_Errors</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000088;">$element</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$errorMessages</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessages</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$errorMessages</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$content</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// iterate over errorMessages, replace or use default</span>
        <span style="color: #000088;">$errorLinesHtml</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$errorMessages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$errorCode</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$errorMsg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// make an exception for isEmpty and array representing elements</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$errorCode</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'isEmpty'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$msgLangPack</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'form.error.array.'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$errorCode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$msgLangPack</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'form.error.'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$errorCode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000088;">$errorMsg</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$msgLangPack</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$msgLangPack</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$errorMsg</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$errorLinesHtml</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;li&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$errorMsg</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/li&gt;'</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #666666; font-style: italic;">// combine</span>
        <span style="color: #000088;">$errorHtml</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;ul class=&quot;errors&quot;&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$errorLinesHtml</span> <span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/ul&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p>Errormessages are fetched by an element&#8217;s getMessages() method that returns an associative array. The error-codes (keys) can be used to translate the message. As can be seen I treat elements representing an array differently when fetching the &#8216;isEmpty&#8217; error message.</p>
<div class="sidenote">
<p>Why using a custom errors decorator and not setting the messages on the element?</p>
<p>setErrors() can be used to set own errors on Zend_Form_Element. Those errors are stored in property _errorMessages which is indeed cleared first. This doesn&#8217;t remove the messages received from the validators though as they are stored in _messages. Upon adding an error by setErrors() both arrays are merged into _messages (this happens in markAsError()) and that&#8217;s the one returned by getMessages(). So trying to replace the existing isEmpty error by &#8216;setting&#8217; a custom error effectively adds an error instead of replacing it. getErrorMessages() does return just the new errors but&#8230; the viewHelper formErrors (which is invoked by the default &#8216;Errors&#8217; decorator) uses getMessages()&#8230;</p>
</div>
<h3>Rendering the view mode</h3>
<p>The view renderer is a simplified version of the edit renderer. Main differences are:</p>
<ul>
<li>The form doesn&#8217;t have a Form decorator and thereby no form tag. (I&#8217;ll keep calling the no-form a form though ;)).</li>
<li>All elements have only one decorator common for all elements: My_Decorator_View_Element</li>
<li>As the only element decorator doesn&#8217;t use Zend_View, the form has no need for a View element.</li>
</ul>
<h4>My_Decorator_View_Element</h4>
<p>This decorator retrieves value and label from the element and creates. It then creates HTML making exceptions for:</p>
<ul>
<li>Submit elements (which are ignored)</li>
<li>Array representing elements (where more than one value needs to be displayed)</li>
</ul>
<h3>Concluding</h3>
<p>Above examples give an impression of how Zend_Form can be suited to virtually anyone&#8217;s needs. One can argue that separating the rendering from the basic definition adds unnecessary complexity. It does however pull HTML specifics (which during a project life-cycle often are subject to change) out of the &#8216;model&#8217; layer. Both the stripped down forms and renderers are easy to reuse: The renderer can be applied to a number of forms and the forms themselves can be used in projects requiring different HTML.</p>
<p>Even without considering the rendering part, Zend_Form is a valuable platform offering a lot of ways to customize it. As the view renderer example shows it can also operate without Zend_View, provided one doesn&#8217;t use any of the built in decorators. Being able to provide self-built elements, validators and decorators makes it possible to use Zend_Form in virtually any project.</p>
<p>Further reading:</p>
<ul>
<li><a href="http://framework.zend.com/apidoc/core/">Zend Framework API documentation</a></li>
<li><a href="http://devzone.zend.com/article/3450">Decorators with Zend_Form</a></li>
<li><a href="http://weierophinney.net/matthew/archives/215-Rendering-Zend_Form-decorators-individually.html">Rendering Zend Form decorators individually</a></li>
<li><a href="http://giorgiosironi.blogspot.com/2009/10/advanced-zendform-usage.html">Advanced Zend_Form usage</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/12/07/using-zend_form-without-zend-framework-mvc/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Catching PHP Exceptions: Except the unexpected</title>
		<link>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 11:57:20 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=527</guid>
		<description><![CDATA[PHP Exceptions can greatly assist in implementing various error scenario&#8217;s into an application. Before PHP5 one had to resort to specific return values or drastic measures like trigger_error(). Planning exceptions, I found out, is just as important as class design. At any point where a developer needs to handle the possibility of an exception being [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://us.php.net/manual/en/language.exceptions.php">PHP Exceptions</a> can greatly assist in implementing various error scenario&#8217;s into an application. Before PHP5 one had to resort to specific return values or drastic measures like <a href="http://us.php.net/manual/en/function.trigger-error.php">trigger_error()</a>. Planning exceptions, I found out, is just as important as class design. At any point where a developer needs to handle the possibility of an exception being thrown he needs to know: </p>
<ul>
<li>What Exceptions can I expect?</li>
<li>What Exceptions do I plan to catch?</li>
</ul>
<p>In this post I&#8217;ll show some important aspects to consider when planning exceptions.<br />
<span id="more-527"></span></p>
<h3>The Basic Exception</h3>
<p>Let&#8217;s assume a Soap-based web-service client class used to submit order-data to a supplier&#8217;s web-service. The web-service client throws an exception if required configuration parameters are missing. The actual SoapClient object will be initialized when the first webservice method is called.</p>
<p>Web-service client class:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$config</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$soapClient</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$config</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initSoapClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toSoapParam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Configuration error'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Application code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// We need to act on this asap...</span>
    <span style="color: #000088;">$AppError</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">register_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Redirect to application error page</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In case of a configuration error a redirect is performed to an application-error page. And (just an example) some mechanism is triggered that starts to bug a (or all) developers that there&#8217;s a problem that needs immediate attention. </p>
<h3>Knowing what to catch</h3>
<p>There are of course errors that are less disastrous. Web-services can be down so we need to cope with that, resulting in the modifications below:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClientException <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClientConfigurationException <span style="color: #000000; font-weight: bold;">extends</span> WsSoapClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClientConnectionException <span style="color: #000000; font-weight: bold;">extends</span> WsSoapClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClientConfigurationException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Configuration error'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        try <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #339933;">,</span> 
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exceptions'</span><span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>SoapFault <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClientConnectionException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Cannot load WSDL: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsSoapClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// store the order in a queue to be processed later</span>
    <span style="color: #000088;">$Order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">queue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Page</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'OrderQueued'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Catch everything, also WsSoapClientConfigurationException</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// We need to act on this asap...</span>
    <span style="color: #000088;">$AppError</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">register_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Redirect to application error page</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Two things have changed:</p>
<h4>Extending exception types</h4>
<p>Exception classes have been defined for specific errors. They both extend an Exception class that is specific for the WsSoapClient class. This allows us to catch specific exceptions, like is done with WsSoapClientConnectionException. We could also catch all exceptions directly thrown by WsSoapClient by catching WsSoapClientException. When defining exception types one might take <a href="http://us.php.net/manual/en/spl.exceptions.php">SPL Exceptions</a> as a starting point.</p>
<h4>Rethrowing exceptions</h4>
<p>A SoapFault exception is caught and a WsSoapClientConnectionException is thrown instead. Now one might wonder: Why? Couldn&#8217;t I just as well catch SoapFault in the application code? That brings us to the next section.</p>
<h3>Knowing what to expect</h3>
<p>In the previous example we simply used one WsSoapClient class to handle all web-service related communications. Now imagine that we have different suppliers that (inevitably) offer different types of web-services for us to use. Besides a client that handles Soap we now also need a client that handles XML-RPC.</p>
<p>After reading up a bit on <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29">Design Patterns</a> we decide to introduce a <a href="http://www.ibm.com/developerworks/library/os-php-designptrns/#N10076">Factory</a> that returns the proper web-service client for the order, which we supply in the method call.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsClientFactory
<span style="color: #009900;">&#123;</span>
    static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getWsClient<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplier</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'supplierA'</span><span style="color: #339933;">:</span>
                <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span>
                    Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soap</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplierA</span>
                <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'supplierB'</span><span style="color: #339933;">:</span>
                <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WsXmlRpcClient<span style="color: #009900;">&#40;</span>
                    Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlrpc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplierB</span>
                <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Briefly put: The point of a factory is to avoid the &#8216;new&#8217; keyword by allowing it to return various class instances. To know what callable methods to expect on the returned object, the possible object types need to implement a common interface or extend a common (abstract) class. We define an interface WsClient and let the two client types implement it:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// submitting order to soap webservice</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsXmlRpcClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// submitting order to xml-rpc webservice</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now if we take a look at our original application code it becomes obvious that we are not finished yet.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> WsClientFactory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsSoapClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Now what if there's a XML-RPC client throwing other exceptions?</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We could catch WsXmlRpcClientConnectException as well but that&#8217;s not the way to go for two obvious reasons:</p>
<ol>
<li>We would be duplicating the code in the catch blocks</li>
<li>If later we need to add a WsEmailClient class, we would need to update both the factory and all the try-catch blocks in the application.</li>
</ol>
<h4>Abstracting exceptions</h4>
<p>As the client types implement a common interface we can also define a set of exceptions that are thrown by all classes implementing that interface:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsClientException <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsClientConfigurationException <span style="color: #000000; font-weight: bold;">extends</span> WsClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsClientConnectionException <span style="color: #000000; font-weight: bold;">extends</span> WsClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span> WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The classes implementing WsClient:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initSoapClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConfigurationException</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConnectionException</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsXmlRpcClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initXmlRpcClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initXmlRpcClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConfigurationException</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConnectionException</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The application code retrieving an object from the factory now knows what exception types to expect:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> WsClientFactory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Now we know what to expect</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Wrapping it up</h3>
<p>What the above shows is that:</p>
<ul>
<li>Throwing a default &#8216;Exception&#8217; is bad practice if you ever want to act on that specific error scenario. Without extending the Exception class you can only catch all or none.</li>
<li>New exceptions can be thrown in catch blocks. That way it&#8217;s possible to prevent unexpected exception types to cross certain application design boundaries.</li>
<li>Once class design involves abstract classes or interfaces it is wise to design exception structures as well and organize them in similar layers of abstraction.</li>
</ul>
<p>Using above &#8216;rules of thumb&#8217; will hopefully help in using exceptions to maximum effect. The above mainly covers the structure of exceptions and not so much functionally that can be added to an exception subclass. Ideas to consider:</p>
<ul>
<li>Adding listeners to an Exception that might write exceptions to a log. Beware though: There&#8217;s probably no need to log &#8216;expected exceptions&#8217; and every disk-write is a small hit on performance.</li>
<li>Adding the caught exception to the new exception that is being re-thrown.</li>
</ul>
<p>Do you think I&#8217;ve left out important parts or are you using (entirely) different exception strategies? Feel free to comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Usability: What does this button do?</title>
		<link>http://www.tibobeijen.nl/blog/2009/10/09/usability-what-does-this-button-do/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/10/09/usability-what-does-this-button-do/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 14:01:48 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[graphic design]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=484</guid>
		<description><![CDATA[In software development projects, paying proper attention to usability aspects, can greatly help &#8216;getting the message functionality across&#8217;. Usability is a field of expertise on its own and involves techniques like wireframes, prototyping and card sorting. Not every project is the same and (sadly) lack of time or budget can prevent specialized interaction designers to [...]]]></description>
			<content:encoded><![CDATA[<p>In software development projects, paying proper attention to usability aspects, can greatly help &#8216;getting the <del datetime="2009-09-20T10:22:43+00:00">message </del>functionality across&#8217;. <a href="http://en.wikipedia.org/wiki/Usability">Usability</a> is a field of expertise on its own and involves techniques like <a href="http://www.usabilityfirst.com/glossary/term_645.txl">wireframes</a>, <a href="http://www.usabilitynet.org/tools/prototyping.htm">prototyping</a> and <a href="http://en.wikipedia.org/wiki/Card_sorting">card sorting</a>. Not every project is the same and (sadly) lack of time or budget can prevent specialized interaction designers to be involved in the project. This means that making the application &#8216;usable&#8217; becomes the responsibility of graphic designers or developers (or it is neglected altogether). Not an easy combination of tasks&#8230;<br />
<span id="more-484"></span><br />
When developing or visually designing an application one goes into much detail which makes it hard to step back and look at the application from an end user&#8217;s perspective. To help measure and improve usability there are numerous <a href="http://www.usereffect.com/topic/25-point-website-usability-checklist">usability checklists</a> out there, some of them focusing on <a href="http://www.alistapart.com/articles/sensibleforms">specific subjects like forms</a>. Such lists can be very complete (and thereby very long) and because of that difficult to continuously use during development. They tend to be more useful as an evaluation tool than as a development tool.</p>
<p>To help during development (or design) it helps to keep in mind that a user using an application is all about interaction and exchanging information. At any given moment while using an application, a user might wonder things like:</p>
<ul>
<li>What did that button do?</li>
<li>What will this button do?</li>
<li>What does this label mean?</li>
<li>How can I find the page I&#8217;m looking for?</li>
</ul>
<p>Summarized: action and information, past and future as illustrated below:<br />
<div id="attachment_501" class="wp-caption aligncenter" style="width: 510px"><img src="http://www.tibobeijen.nl/blog/wp-content/uploads/2009/09/usability_application_state_diagram_01.gif" alt="Usability: Application State Diagram" title="Usability: Application State Diagram" width="500" height="350" class="size-full wp-image-501" /><p class="wp-caption-text">Usability: Application State Diagram</p></div></p>
<h3>Four quadrants</h3>
<h4>I. Past actions</h4>
<p>This translates to &#8216;feedback&#8217;. Is it at any point clear to the user what the application is doing or has done, following the user&#8217;s commands? Is the feedback form sent? Are modifications done through the CMS visible online? Is the application really still busy or is something going wrong?</p>
<h4>II. Future actions</h4>
<p>Feed forward. For a user to &#8216;trust&#8217; an application he needs to be able to predict what will happen when he performs certain actions. Take for instance a webshop: After clicking &#8216;place order&#8217;, will there be a screen to review and possibly cancel the order process? Or, after saving a page in a CMS, will it be possible to preview a page before it&#8217;s visible on the live site?</p>
<h4>III. Past information</h4>
<p>This focuses mainly on how information is displayed at a given point. Is important information clearly recognizable? Is it clear what is displayed? For example a product page on a webshop: Can editorials and user comments be clearly distinguished?</p>
<h4>IV. Future information</h4>
<p>This covers navigation and thereby how all the information and possible interaction of an application is structured. To efficiently use an application a user needs to be able to predict where to find information and how to get there. This involves structuring navigation and perhaps also tailoring navigation to accommodate for common usage scenarios.</p>
<h3>What this diagram does not</h3>
<p>The above diagram focuses on the state of an application at a given point and therefore doesn&#8217;t look at the bigger picture. This means it doesn&#8217;t:</p>
<ul>
<li>Cover consistency throughout the application.</li>
<li>Prioritize functionality.</li>
<li>Match functionality with user goals.</li>
<li>Look into characteristics of the targetted users (like experience with similar applications) or the environment the application is used in.</li>
</ul>
<h3>What this diagram can do</h3>
<p>Taking back a step once in a while <em>during</em> development and applying this diagram on the application that is being created, can help to quickly point out certain usability flaws. This is especially true when there is no dedicated usability expert in the team. Having a certain amount of knowledge of the more elaborate checklists mentioned earlier will help. Besides being used as a quick evaluation tool this diagram can also be used to structure usability-related thoughts and ideas and predict their effectiveness. Hopefully that will help creating a better user experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/10/09/usability-what-does-this-button-do/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Controlled initialization of domain objects</title>
		<link>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 07:09:44 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[domain model]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=385</guid>
		<description><![CDATA[In a recent project I&#8217;ve been working on, we have used the &#8216;Domain Model&#8216; to describe and design our application. Doing so we decouple persistency logic from the objects that are being passed around and modified throughout our application: The Domain objects. So what in MVC is often referred to as &#8216;model&#8217; is actually a [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent project I&#8217;ve been working on, we have used the &#8216;<a href="http://en.wikipedia.org/wiki/Domain_model">Domain Model</a>&#8216; to describe and design our application. Doing so we decouple persistency logic from the objects that are being passed around and modified throughout our application: The Domain objects. So what in MVC is often referred to as &#8216;model&#8217; is actually a combination of a persistency layer, a service layer and a Domain layer. The persistency and service layer are also referred to as Data Access Objects: DAO. (As for the why and how of this architecture I recommend the article <a href="http://www.angryobjects.com/2009/03/30/writing-robust-php-backends-with-zend-framework/">Writing robust backends with Zend Framework</a>. For a good description of the DAO concept <a href="http://www.sitecrafting.com/blog/php-patterns-part-ii/">look here</a>). </p>
<p>One of the challenges we were facing was that on one hand we wanted to implement business rules in our Domain objects. In plainish english: On setting or changing properties of the object (like changing a status) we want to validate if that action is allowed. On the other hand we want to be able to initialize an object to whatever state corresponds with the data fetched from the persistency layer. Doing so we found that the business rules got in the way during initialization when fetching it from the persistency layer. So what we were looking for was a way to allow the service layer to construct a Domain object using methods that are hidden from the rest of the code. We found two ways:</p>
<ol>
<li>Reflection (as of PHP 5.3)</li>
<li>A design pattern where the Domain object initializes itself using the provided Service object.</li>
</ol>
<p><span id="more-385"></span></p>
<h3>Das Model: DAO, Domain, Service and Persistency layer</h3>
<p>First lets look at how such a Domain object might look like. See simplified example below of an &#8216;order&#8217;:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$orderDate</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$articles</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$customer</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$invoices</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$statusHistory</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getArticles<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setStatus<span style="color: #009900;">&#40;</span>OrderStatus <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// other getters and setters</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The order has properties like it&#8217;s id, a list of articles, the customer that placed the order and the invoice(s) sent. Besides that it has a status history that actually is a stack of subsequent statuses that correspond to the business processes involved. Possible statuses could be:</p>
<ul>
<li>initiated</li>
<li>confirmed</li>
<li>payment_confirmed</li>
<li>articles_deliverable</li>
<li>shipped</li>
<li>onhold_system_error</li>
<li>resolved_system_error</li>
<li>onhold_helpdesk</li>
<li>resolved_helpdesk</li>
<li>cancelled_helpdesk</li>
<li>completed</li>
</ul>
<p>Domain objects are fetched, stored and updated by using methods on Service objects. Those service objects implement the aforementioned &#8216;persistency layer&#8217; (could be PDO, webservices, memory, files, etc.). Services are retrieved from a DAO instance that is fetched from a DAO registry. I&#8217;ll cover that more thoroughly in a later post so I&#8217;ll keep it brief:</p>
<p>Bootstrap:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// bootstrap. setup DAO registry  with </span>
<span style="color: #666666; font-style: italic;">// DAO instance that provides service objects</span>
DAO_Factory<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setInstance</span><span style="color: #009900;">&#40;</span>
	<span style="color: #000000; font-weight: bold;">new</span> DAO_PDO<span style="color: #009900;">&#40;</span><span style="color: #000088;">$initialisedPdo</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Fetching an order by id:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// returns concrete DAO, in this case using PDO for persistency</span>
<span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> DAO_Registry<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
	<span style="color: #666666; font-style: italic;">// the DAO instance returns an 'order' service instance</span>
	<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getServiceOrder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #666666; font-style: italic;">// the service instance provides methods for CRUD type operations</span>
	<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getById</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reqOrderId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Implementing logic</h3>
<p>Now let&#8217;s illustrate the concept of putting business rules in the Domain object: If a customer contacts the helpdesk with a difficult question, the helpdesk can put the order on hold to prevent shipping. The status &#8216;onhold_helpdesk&#8217; is added to the status history. But (in our imaginary shop) this can&#8217;t be done if the order is already shipped. So the setStatus() method will validate if the status given is actually allowed and only then perform the action.</p>
<p>The setStatus() method in the order class now looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... properties and other methods</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setStatus<span style="color: #009900;">&#40;</span>OrderStatus <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// determine if new status is allowed business-wise</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$newStatusAllowed</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #990000;">array_push</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusHistory</span><span style="color: #339933;">,</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Domain_Order_InvalidStatus_Exception<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ... other methods</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Calling the setStatus() method should handle the possible exception:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setStatus</span><span style="color: #009900;">&#40;</span>
		<span style="color: #000000; font-weight: bold;">new</span> OrderStatus<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'onhold_helpdesk'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Domain_Order_InvalidStatus_Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//  properly handle exception</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>No public access allowed</h3>
<p>To continue the example: If an order is already shipped it can&#8217;t be put on hold. But (at least in this imaginary shop) the other way round goes too: If an order is &#8216;on hold&#8217; the status &#8216;shipped&#8217; can&#8217;t be added. The issue has to be resolved first. From a given state this behaviour is good: invalid actions are prevented. The problem is that the public setters like setStatus() are not suitable for bringing a newly created domain object into it&#8217;s &#8216;persisted&#8217; state. A possible solution might be to add methods that bypass the business logic, but as these methods are used by the service object they need to be public. This is not desired as it allows developers to cut corners that shouldn&#8217;t be cut.</p>
<p>So, back to the start of this post: How to set properties bypassing business-logic?</p>
<h3>1 . ReflectionProperty (PHP 5.3)</h3>
<p>As of PHP 5.3 the <a href="http://www.php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionproperty">ReflectionProperty</a> class of the <a href="http://www.php.net/manual/en/language.oop5.reflection.php">reflection API</a> has a method setAccessible() that allows access to protected and protected properties. Accessing the protected id property of the Order class would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Service
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getById<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// based on the id from the persistency layer </span>
        <span style="color: #666666; font-style: italic;">// data is retreived. In this demo the data is a hash. </span>
        <span style="color: #666666; font-style: italic;">// Now it needs to be put into the newly created </span>
        <span style="color: #666666; font-style: italic;">// Order that is returned.</span>
        <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Order<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$refId</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span>  ReflectionProperty<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Order'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$refId</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$refId</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$persistedData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ... set other properties</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The major drawback of using this technique is that the Service class needs to be aware of the internals of the Order class. So, updating the Order class involves needing to update the Service class as well. This breaks basic concepts of OOP. (For a more useful example of reflectionProperty see <a href="http://sebastian-bergmann.de/archives/831-Freezing-and-Thawing-PHP-Objects.html">this object freezer example</a> by Sebastian Bergmann.</p>
<h3>2. Protected Link Pattern?</h3>
<p>Another way to bypass business-logic on creation without exposing that possibility is to create what could be called a &#8216;protected link&#8217; between the Service and the Order object. See code below:</p>
<p>Service:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Service_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getById<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> Order<span style="color: #339933;">::</span>_init<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> _getInitData<span style="color: #009900;">&#40;</span>Domain_Order <span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// will return 'raw' data (hash/object) as</span>
        <span style="color: #666666; font-style: italic;">// retrieved from the persistency layer</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Domain:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... </span>
    <span style="color: #000000; font-weight: bold;">private</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// no, no, go to the Service</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> _init<span style="color: #009900;">&#40;</span>Service_Order <span style="color: #000088;">$service</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// create brand new instance</span>
        <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Domain_Order<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// fetch persisted data</span>
        <span style="color: #000088;">$initData</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$service</span><span style="color: #339933;">-&gt;</span>_getInitData<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">,</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// bring order in it's initial state</span>
        <span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$initData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">orderDate</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$initData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'orderDate'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// etc...</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
    <span style="color: #666666; font-style: italic;">// ... </span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A static _init() method, that <em>has</em> access to the Order&#8217;s protected properties, is provided with a Service instance and the id of the Order to be initialized. The static Order method then in turn <em>fetches</em> the data from the Service. The new Order instance is then put into the persisted state by directly setting attributes otherwise not accessible. The initialized instance is then returned to the Service which in turn returns it to the requesting code.</p>
<p>On a first glance this might look more complicated than needed: Instead of using a _getInitData() from the Order class we could also have provided the _init() method with a data object that implements a certain interface. But this leaves open the option to initialize an Order object with manipulated data that is not directly derived from the persistency layer.</p>
<p>What this <em>does </em>achieve is that it is now impossible to manipulate a Domain object bypassing methods that apply business logic. Yet at the same time that business logic doesn&#8217;t get in the way when initializing a Domain object from the Service layer. A benefit compared to the reflection solution is that the Service object doesn&#8217;t need to be aware of the Order&#8217;s internals. The existence of the Domain layer&#8217;s _init() and the Service layer&#8217;s _getInitData() methods are enforced by their respective interfaces or the abstract classes they extend. The design of the transported data (in these examples a hash) can of course also be limited to a certain object type.</p>
<p>A drawback is that there is now a public method _getInitData on the Service layer. In this example the impact thereof is reduced by requiring an instance of Domain_Order but that&#8217;s just sugar (or vinegar so you like): It&#8217;s just an indication for developers that they are on the wrong track when they are directly calling _getInitData().</p>
<p>As said, in later posts I plan to elaborate more on the Service and Persistency layers that are briefly shown here. If anyone knows of other ways to address the issue of &#8216;controlled initialization&#8217; I&#8217;m of course very interested. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Explicit PHP6?</title>
		<link>http://www.tibobeijen.nl/blog/2009/06/11/explicit-php6/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/06/11/explicit-php6/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 07:47:06 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php6]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=396</guid>
		<description><![CDATA[Some days ago I read Fabien Potencier&#8217;s post &#8216;What for PHP 6&#8242; pointing me to some features that might be implemented in PHP6. Two of those would have been nice in a project I&#8217;m currently working on where I&#8217;ve been experimenting with &#8216;domain objects&#8217; having &#8216;scalar&#8217; or &#8216;value&#8217; objects as properties (more on that later). [...]]]></description>
			<content:encoded><![CDATA[<p>Some days ago I read Fabien Potencier&#8217;s post <a href="http://fabien.potencier.org/article/18/what-for-php6">&#8216;What for PHP 6&#8242;</a> pointing me to some features that might be implemented in PHP6. Two of those would have been nice in a project I&#8217;m currently working on where I&#8217;ve been experimenting with &#8216;domain objects&#8217; having &#8216;scalar&#8217; or &#8216;value&#8217; objects as properties (more on that later). The first is scalar type hinting and hinted return values. The other is a __cast() method that replaces (or complements __toString()). Now that sounds quite java-ish and one of PHP merits is it&#8217;s flexibility but having the <em>option</em> to be more strict in my opinion is a good thing: If I feed my application with garbage I don&#8217;t blame it for being equally blunt.<br />
<span id="more-396"></span><br />
Consider a User object that has the properties userid, email and admin.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> User
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$userId</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$email</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$admin</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setUserId<span style="color: #009900;">&#40;</span>UserId <span style="color: #000088;">$userId</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setEmail<span style="color: #009900;">&#40;</span>Email <span style="color: #000088;">$email</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// this should only accept a boolean</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setAdmin<span style="color: #009900;">&#40;</span><span style="color: #000088;">$isAdmin</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_bool</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$isAdmin</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ValueTypeException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Wrong parameter for '</span> <span style="color: #339933;">.</span> <span style="color: #009900; font-weight: bold;">__METHOD__</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$isAdmin</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Here being able to enforce the boolean parameter would be nice and more consequent with the other methods.</p>
<p>The Email value object has it&#8217;s own validation and could look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Email
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^.+\@.+\..+$/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ScalarValueException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Invalid value for type Email'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now let&#8217;s look at how a PHP6 UserId object <em>might</em> look like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> UserId
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$isValid</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_int</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span>
            <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span>
            <span style="color: #000088;">$value</span> <span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">0</span>
        <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ScalarValueException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Invalid value for type UserId'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Warning: uses PHP6 proposed features</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __cast<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'int'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// return integer value</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'boolean'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// return true as UserId can only </span>
            <span style="color: #666666; font-style: italic;">// exist with a valid value</span>
            <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> SkalarInvalidCastException<span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'Object of type UserId cannot be cast to '</span><span style="color: #339933;">.</span><span style="color: #000088;">$type</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> exists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// method that checks if a user with given id exists</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As can be seen the __cast() method assumably (it&#8217;s just a proposed feature) accepts a $type parameter. That raises the question if it wouldn&#8217;t be better to add __toInteger(), __toFloat() and __toBoolean() methods instead. That seems more consequent with the __toString() method that&#8217;s allready widely used.</p>
<p>The C#-style properties with getters and setters might be nice too, although imho it doesn&#8217;t really add much to the allready existing __set() and __get() methods. I would prefer to see &#8216;strongly typed&#8217; properties instead:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> User
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// PHP6 wishlist: strong typed properties</span>
    <span style="color: #000000; font-weight: bold;">protected</span> UserId <span style="color: #000088;">$userId</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> Email <span style="color: #000088;">$email</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> boolean <span style="color: #000088;">$admin</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// etc...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I&#8217;m really looking forward to these kind of additions, especially if such type hinting is kept optional. Then the flexibility of PHP is preserved but it allows for a more robust approach in large projects.</p>
<p>Be explicit. Type strong.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/06/11/explicit-php6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Browser Zoom: Design consequences</title>
		<link>http://www.tibobeijen.nl/blog/2009/03/07/web-browser-zoom-design-consequences/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/03/07/web-browser-zoom-design-consequences/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 18:57:19 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[accessibility]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.yunademo.nl/preview/tibobeijen.nl/?p=42</guid>
		<description><![CDATA[Over the years the display size of the average computer screen has increased. As a consequence nowadays more and more websites are designed with a 1024 width screen in mind. For example: BBC, Adobe and The New York Times. With at least 78% of the users using a 1024 or higher resolution screen the time [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years the display size of the average computer screen has increased. As a consequence nowadays more and more websites are designed with a 1024 width screen in mind. For example: <a href="http://www.bbc.co.uk/">BBC</a>, <a href="http://www.adobe.com/">Adobe</a> and <a href="http://www.times.com/">The New York Times</a>. With at least 78% of the users using a 1024 or higher resolution screen the time seems right to move away from the 800px designs. But what about accessibility? And usability? And is full page zooming really better than text scaling?<br />
<span id="more-42"></span></p>
<h3>Screen resolution</h3>
<p>Take <a href="http://www.thecounter.com/stats/2009/February/res.php">the february 2009 stats of thecounter.com</a>. Based on those stats a target resolution of 1024 seems reasonable: At least 78% of the people view websites at that resolution or higher. </p>
<p>Of course the need for the increased width depends on the specific elements that have to be displayed. When left- and right columns are narrow, a width of 1024 might lead to very long lines which are hard to read.</p>
<h3>Accessibility guideline: text size</h3>
<p>Accessibility guidelines (<a href="http://www.w3.org/TR/WCAG10/#gl-structure-presentation">W3C WCAG 1.0 point 3.4</a>) state that relative units are to be used when specifying text size. That way, users can easily adjust the size of text. For some time, browsers (except *sigh* IE6) allowed users to adjust the displayed text size by using key combinations or ctrl+scrollwheel. This posed a challenge to CSS coding as it wasn&#8217;t always easy to keep everything in place when text size was increased. Or, probably worse, text would flow out of the box and become unreadable. See below image of a <a href="http://www.eurogamer.net/articles/bioshock-2-set-seven-years-later">page on eurogamer.net</a>. In the left-column navigation and bottom parts of the page elements will overlap when text size is increased.</p>
<div id="attachment_182" class="wp-caption aligncenter" style="width: 505px"><img src="http://www.tibobeijen.nl/blog/wp-content/uploads/2009/03/eurogamer_textsize_example.png" alt="Eurogamer text size example" title="Eurogamer text size example" width="495" height="271" class="size-full wp-image-182" /><p class="wp-caption-text">Eurogamer text size example</p></div>
<p>Nowadays quite some web browsers have replaced text scaling with page zooming. This definitely makes life easier for CSS coders. It will also help user experience when increasing text size because relative placement of elements is preserved, as opposed to situations where some columns are stretched in different amounts. But there is a side-effect.</p>
<h3>The misinterpretation of statistics and its disastrous consequences</h3>
<p>When a website already fills the entire viewport in it&#8217;s original size, as soon as display size is increased, horizontal scroll bars will appear and the rightmost content will move out of view. So now let&#8217;s turn the <a href="http://www.thecounter.com/stats/2009/February/res.php">aforementioned stats around</a>. At least 51% of the visitors have a screen resolution of 1024 or <em>less</em>. So basically this means that when a page is designed to have a minimum width of, say, 1000px, half of the visitors will have problems increasing the displayed size.</p>
<p>Although official accessibility standards don&#8217;t seem to mention horizontal scrolling, it&#8217;s safe to say that having to scroll horizontally doesn&#8217;t <em>help</em> accessibility. And from a usability perspective it&#8217;s <a href="http://www.useit.com/alertbox/20050711.html">most certainly bad practice</a>.</p>
<p class="remark">Regarding accessibility standards not mentioning horizontal scrolling: I searched <a href="http://www.drempelvrij.nl/webrichtlijnen">the standards document of the dutch government</a> which includes all WCAG guidelines (and more). I searched for the words screen (dutch: scherm), horizontal (dutch: horiz) and scroll. Nothing. A downside of these kind of checklists: technology moves on continuously while standards only get update once every x years. But that&#8217;s a different subject&#8230;</p>
<h3>Browser overview: Text scaling or Full page zooming?</h3>
<p>Acknowledging this side-effect it&#8217;s good to know exactly how today&#8217;s browsers perform zooming. See the table below.</p>
<table id="browser_widths" cellspacing="0">
<thead>
<tr>
<th class="c1"></th>
<th class="c2">IE7</th>
<th class="c3">FF3</th>
<th class="c4">Opera 9</th>
<th class="c5">Safari</th>
<th class="c6">Chrome</th>
</tr>
<tr>
<th>Default scaling</th>
<td>zoom</td>
<td>zoom</td>
<td>zoom</td>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td colspan="6" class="subheading">Zoom options</td>
</tr>
<tr>
<th>All content</th>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<th>Text only</th>
<td>menu</td>
<td>menu</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td colspan="6" class="subheading">Zoom percentages</td>
</tr>
<tr>
<th>Step 1</th>
<td>110</td>
<td>111</td>
<td>110</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 2</th>
<td>120</td>
<td>123</td>
<td>120</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 3</th>
<td>130</td>
<td>131</td>
<td>130</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 4</th>
<td>140</td>
<td>143</td>
<td>140</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 5</th>
<td>150</td>
<td>154</td>
<td>150</td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="6" class="subheading">Widths (original is 800px)</td>
</tr>
<tr>
<th>Step 1</th>
<td>880</td>
<td>888</td>
<td>880</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 2</th>
<td>960</td>
<td>980</td>
<td>960</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 3</th>
<td>1040</td>
<td>1044</td>
<td>1040</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 4</th>
<td>1120</td>
<td>1142</td>
<td>1120</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Step 5</th>
<td>1200</td>
<td>1230</td>
<td>1200</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p class="caption">Browser zoom characteristics</p>
<h3>Conclusion</h3>
<p>Although stats suggest 1024 is a solid choice, it&#8217;s obvious that there are considerations to be taken into account. If liquid design with a minimum of 800px is not an option and one chooses to design for a (minimum) resolution of 1024px the least one can do is try to avoid putting essential navigation or use cues in the rightmost part of the site.</p>
<p>See image below of <a href="http://www.play.com/">Play.com</a>: The top part with the currency selectors and link to the visitor&#8217;s account-page <em>do</em> sticks to the right size of the screen. </p>
<p class="remark">In this case I think it&#8217;s a coincidence as the cart button does extend beyond the visible area. The selectors are positioned absolutely from the right size of a container that doesn&#8217;t have it&#8217;s css attribute position set to &#8216;relative&#8217;. So positioning is done with respect to the BODY element. Although that has a min-width of 990px it somehow works out this way.</p>
<div id="attachment_198" class="wp-caption aligncenter" style="width: 499px"><img src="http://www.tibobeijen.nl/blog/wp-content/uploads/2009/03/playcom_header_example.png" alt="Play.com header example" title="Play.com header example" width="489" height="156" class="size-full wp-image-198" /><p class="wp-caption-text">Play.com header example</p></div>
<p>One last tip: IE7 keeps a centered column centered when zooming in, as opposed to Firefox and Opera. So when in IE7 horizontal scroll bars appear, bits are falling of the left side of the screen as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/03/07/web-browser-zoom-design-consequences/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thousands of modules can&#8217;t be wrong, right?</title>
		<link>http://www.tibobeijen.nl/blog/2009/02/20/thousands-of-modules-cant-be-wrong-right/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/02/20/thousands-of-modules-cant-be-wrong-right/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 17:48:58 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[customization]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[joomla!]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=158</guid>
		<description><![CDATA[Yesterday I attended a presentation showcasing Drupal. Like Joomla! and WordPress an easy install routine presents the user with a lot of functionality right out of the box. By adding modules as needed one can achieve whatever he wants. So it seems&#8230; After the showcase part, the session continued into a case study. The case [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I attended a presentation showcasing <a href="http://drupal.org/">Drupal</a>. Like Joomla! and WordPress an easy install routine presents the user with a lot of functionality right out of the box. By adding modules as needed one can achieve whatever he wants. So it seems&#8230; After the showcase part, the session continued into a case study. The case at hand was a project were all sorts of specific functionality (think: facebook, digg, etc. web 2.0 you know) was required. And it didn&#8217;t go as smooth and quick as expected. How come?<br />
<span id="more-158"></span><br />
No two projects are the same and within this scope it&#8217;s important to distinguish two types of project:</p>
<ol>
<li>There&#8217;s the ones that fit well into &#8216;the CMS mold&#8217;: Content is aggregated, put in the right drawer (=stored), perhaps sorted a bit and finally displayed. There are of course requirements but there&#8217;s usually a certain flexibility to them. Take for example images: It&#8217;s nice if the CMS will resize uploaded images as needed but if not then that is usually not a show-stopper.</li>
<li>The one&#8217;s where requirements are specific, out of the ordinary, and probably detailed. Some functionality might be provided by a traditional CMS, but there&#8217;s a lot more. Future requirements are undetermined but might be very diverse.</li>
</ol>
<p>Confection clothing vs. tailor made suits really. The project discussed clearly matched the second description.</p>
<h3>Thousands of Drupal modules must be right. Wrong!</h3>
<p>For the first type of project it is obvious that applications like Drupal, Joomla! and WordPress are unbeatable. If that does the job well enough there&#8217;s no point in coding yourself. Besides that, the community will provide you with free upgrades and enhanced functionallity as updates are released!</p>
<p>The second type of project is different though. What I believe went wrong in the case discussed, was that right at the start of the project the assumption was made that &#8216;the needed modules were sure somewhere out there&#8217;. Even if they <em>are</em> it may be hard to find them. Some simplified math: 2332 modules (<a href="http://en.wikipedia.org/wiki/Drupal#Contributed_modules">wikipedia</a>). 1 minute to quickly scan a module and take note if interested. 40 working hours a week equaling 2400 minutes. So it takes about a week to make a first inventory. Not entirely true of course but the time you win, you lose again by comparing the nitty gritty details between similar modules.</p>
<h3>Module creep</h3>
<p>Once the needed modules are found a situation like illustrated below might occur:<br />
<div id="attachment_171" class="wp-caption aligncenter" style="width: 510px"><img src="http://www.tibobeijen.nl/blog/wp-content/uploads/2009/02/module_creep.png" alt="Module Creep" title="Module Creep" width="500" height="394" class="size-full wp-image-171" /><p class="wp-caption-text">Module Creep</p></div></p>
<p>The modules found provide most of the functionallity neccessary. And more. Enough to pass whatever requirements check you want to perform. But take for example module E. That&#8217;s just there to cover for that little bit of &#8216;must have&#8217; requirements. And modules B and D provide functionality that&#8217;s totally irrelevant. Depending on implementation details, for visitors or editors the user experience will be less focused. More is not always better. Maintenance and implementation might be harder than planned too.</p>
<h3>Customization</h3>
<p>So the second type of project might lead to the conclusion that customization is required. And that conclusion by itself poses all kinds of new questions, like:</p>
<ul>
<li><em>Does</em> the application architecture allow for customization?</li>
<li>Can enhancements and original software be kept separate? In other words: what is the quality of the application&#8217;s architecture?</li>
<li>Are the resources (time/money/knowledge/management support) to build custom enhancements available?</li>
<li>What are the risks of core- or module upgrades causing the custom enhancements to fail?</li>
<li>What are considerations with respect to licensing?</li>
<li>How well can risks involved be estimated?</li>
</ul>
<p>These are questions that should be addressed very early in the project. Finally some aspects to take into consideration when trying to answer these questions: </p>
<ul>
<li>Besides looking from a functional point of view, technical details have to be addressed. That expertise has to be (made) available.</li>
<li>Experience from previous projects or case studies greatly helps answering these questions. That experience is not always there.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/02/20/thousands-of-modules-cant-be-wrong-right/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Zend_Config strategies</title>
		<link>http://www.tibobeijen.nl/blog/2008/11/30/zend_config-strategies/</link>
		<comments>http://www.tibobeijen.nl/blog/2008/11/30/zend_config-strategies/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 18:24:30 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.yunademo.nl/preview/tibobeijen.nl/?p=44</guid>
		<description><![CDATA[As applications often need to run on different setups (think: develop, test, production), configuration settings can usually be divided in a static &#8216;application&#8217; part and a more dynamic &#8216;environment&#8217; part. Zend Framework offers a very flexible set of classes that help reading and organizing configuration data and making it available throughout the entire application. But, [...]]]></description>
			<content:encoded><![CDATA[<p>As applications often need to run on different setups (think: develop, test, production), configuration settings can usually be divided in a static &#8216;application&#8217; part and a more dynamic &#8216;environment&#8217; part. Zend Framework offers a very flexible set of classes that help reading and organizing configuration data and making it available throughout the entire application. But, as very often, there is no &#8216;only way&#8217;.
</p>
<p><span id="more-44"></span></p>
<h3>Loading configuration data</h3>
<p>Basically there are three ways of loading configuration data:
</p>
<ul>
<li>1.Using Zend_Config and passing a PHP array as parameter</li>
<li>2.Using Zend_Config_Ini to load an ini configuration file</li>
<li>3.Using Zend_Config_Xml to load an xml configuration file</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$configData</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'somecategory'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'somesetting'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'somevalue'</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// 1. Load array</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config<span style="color: #009900;">&#40;</span><span style="color: #000088;">$configData</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// 2. Load ini file</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config_Ini<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/path/to/config.ini'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// 3. Load xml file</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config_Xml<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/path/to/config.xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Alternatively, you can specify a file containing an array as require() returns the return value of a PHP script being included:
</p>
<p>config.php</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$CONFIG</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'somecategory'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'somesetting'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'somevalue'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$CONFIG</span><span style="color: #339933;">;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// 1b Load array</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config<span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'path/to/config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Using configuration data</h3>
<p>Zend_Config creates a hierachy of Zend_Config instances. So a specific part of the total configuration data can be extracted and passed to a specific component. All subparts behave the same. If the component requires configuration to be passed as an array the toArray() method can be used. Instead of accessing values as properties one can also use the get() method. The advantage of get() is that a default value can be supplied to be used when the requested variable isn&#8217;t available.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// configure an instance using a specific part of the config</span>
<span style="color: #000088;">$modelComponent</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ModelComponent<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">components</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">componentName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// Or, if the component requires an array</span>
<span style="color: #000088;">$modelComponent</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ModelComponent<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">components</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">componentName</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// Get an optional config setting, supplying a default value</span>
<span style="color: #000088;">$someValue</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">common</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'someValue'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'myDefaultValue'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The data contained in Zend_Config is read-only which is normally a good thing. In case the configuration data has to be changed this can be overridden by supplying an additional parameter in the constructor. Then after making the neccessary changes the config object can be &#8216;sealed&#8217; by calling setReadOnly().</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// read config with $allowModifications set to true</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config<span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'path/to/config.php'</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// perhaps change some bits here and there</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fullMoonMadness</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">site</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">theme</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'silver'</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">blog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allowComments</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// and prevent accidental modification</span>
<span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReadOnly</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>To make the loaded configuration available throughout the entire application, Zend_Registry is probably the tool of choice.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config<span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'path/to/config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// and store in registry</span>
Zend_Registry<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Organizing configuration data</h3>
<p>When using ini or xml configuration files, sections can be declared. On loading the file the section to be  used can be specified. A section can extend other sections thereby allowing configuration data to have a certain hierarchy.</p>
<p>Ini-file example:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>production<span style="">&#93;</span></span>
<span style="color: #000099;">www_root</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www.mysite.com</span>
site.title <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;My Website - &quot;</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>test : production<span style="">&#93;</span></span>
<span style="color: #000099;">www_root</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> test.mysite.com</span></pre></div></div>

<p>The root node of XML files can be named arbitrarily. If you want to use sections the first level in the XML has to correspond to the section requested. There are two reserved attributes: value and extends. Other attributes can hold values that otherwise would be childnodes. See example that holds the same data as the Ini file above:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;production<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;www_root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>www.mysite.com<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/www_root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;site</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;My Website - &quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/production<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;test</span> <span style="color: #000066;">extends</span>=<span style="color: #ff0000;">&quot;production&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;www_root</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;test.mysite.com&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/test<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Now the section-specific configuration can be loaded by specifying a second parameter in the constructor:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config_Xml<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/path/to/config.xml'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'test'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Ini, XML or Array?</h3>
<p>As mentioned at the top of this article: There is no &#8216;only&#8217; way and there is no &#8216;right&#8217; or &#8216;wrong&#8217; way. Of course there are aspects that can make you favor one approach over the other, the most notable being:</p>
<ul>
<li>Only Ini and XML provide sections, allowing you to use hierarchic configuration data</li>
<li>Ini and especially XML are better suited for tooling: Software other than PHP can read or modify configuration data.</li>
<li>When using ini files it is not possible to use quotes in a value.
<li>PHP arrays have the benefit that you can put program logic <em>in</em> them. For example, you can construct variables based on defaults that are set initially. See example below</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CONFIG</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'defaults'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fs_root'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/var/www/mysite_com/'</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #000088;">$CONFIG</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'locations'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'libraries'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'zf'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$CONFIG</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'defaults'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fs_root'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'lib/zf/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$CONFIG</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>2009-05-15: added example of loading specific section by passing section parameter to constructor</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2008/11/30/zend_config-strategies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

