<?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>cobbweb &#187; Zend Framework</title>
	<atom:link href="http://cobbweb.me/category/php/zend-framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://cobbweb.me</link>
	<description>Zend Framework Developer</description>
	<lastBuildDate>Thu, 09 Jun 2011 23:46:42 +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>How to integrate Doctrine 2 with your Zend Framework application</title>
		<link>http://cobbweb.me/2010/11/integrate-doctrine-2-zend-framework-application/</link>
		<comments>http://cobbweb.me/2010/11/integrate-doctrine-2-zend-framework-application/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 02:53:53 +0000</pubDate>
		<dc:creator>cobby</dc:creator>
				<category><![CDATA[Doctrine 2]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://www.cobbweb.me/?p=29</guid>
		<description><![CDATA[Before we get started When I first started using Doctrine 2 with Zend Framework, I of course Googled around for information about integrating the two. The process is pretty simple and I actually ended up just writing my own Application Resource. However, this is as far as blog posts got and they never got into [...]]]></description>
			<content:encoded><![CDATA[<h2>Before we get started</h2>
<p>When I first started using Doctrine 2 with Zend Framework, I of course Googled around for information about integrating the two. The process is pretty simple and I actually ended up just writing my own Application Resource. However, this is as far as blog posts got and they never got into detail on how to use Doctrine 2 in a practical context, or they promote using the EntityManager directly from the controller, which IMHO is really bad. So I&#8217;ll assume you already have the CLI setup and a working EntityManager stored in the Zend_Registry. Another side note, I prefer and recommend the annotations driver over the YAML or XML counterparts.</p>
<h2>Time to change your thinking</h2>
<p>Initially, it would be easy to misunderstand what an Entity is. At first, I was still viewing them as a class that defined the table structure but this is very wrong, you need to think of them as a persistable class. The other thing we need to sort out is how we use the Doctrine from a Controller. As I previously mentioned, I see a lot of examples that promote this:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Manages articles
 */
class ArticleController extends Zend_Controller_Action
{

    /**
     * @var Doctrine\ORM\EntityManager
     */
    protected $_em;

    /**
     * Get the EntityManager
     */
    public function init()
    {
        // Reg = Bad; use an action helper as a DI container to store/retrieve the EM and pass it to your services
        $this-&gt;_em = \Zend_Registry::get('Doctrine/ORM/EntityManager');
    }

    /**
     * Get a list of Articles
     */
    public function listAction()
    {
        $this-&gt;view-&gt;articles = $this-&gt;_em-&gt;getRepository('Article\Domain\Entities\Article')-&gt;findAll();
    }

    /**
     * Update an Article from POST params
     */
    public function updateAction()
    {
        $article = $this-&gt;_em-&gt;getRepository('Article\Domain\Entities\Article')-&gt;find($this-&gt;_getParam('id'));
        $article-&gt;setTitle($this-&gt;getRequest()-&gt;getPost('title'));
        // ... etc (and you would refactor all POST data into a local variable as well)

        $this-&gt;_em-&gt;persist($article);
        $this-&gt;_em-&gt;flush();
    }

}
</pre>
<p>There are three major problems with this:</p>
<ol>
<li>Your controllers will quickly evolve into a fat mess of persistence logic</li>
<li>If you want to change from Doctrine to something else (like <a href="http://www.redbeanphp.com">RedBeanPHP</a>), then your screwed</li>
<li>You will likely be duplicating a lot of code when handling persistence.</li>
</ol>
<p>To eliminate the two above problems, we need to completely decouple our Doctrine code from our controller code and we will do this by adding our own layer between the two frameworks.</p>
<h2>Interfacing the problem</h2>
<p>The idea is to write plain PHP classes that will serve as our middle man. The key factor is Separation of Concerns, in any situation: your application controllers shouldn&#8217;t be directly dealing with your data persistence or in this case the EntityManager. Furthermore, we can now test our domain layer without having to cycle up our entire MVC framework.</p>
<p>I think it&#8217;s best to learn by example, so we will create a very basic eCommerce system. We will use the following entities:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace MyApp\Domain\Entity;

// I define a custom Repository class for most entities
/**
 * @Entity(repositoryClass=&quot;MyApp\Domain\Repository\ProductRepository&quot;)
 */
class Product
{

   /**
    * @Column(type=&quot;integer&quot;)
    * @Id @GeneratedValue
    */
   private $id;

   /**
    * @Column(type=&quot;string&quot;)
    */
   private $name;

   /**
    * @Column(type=&quot;integer&quot;)
    */
   private $price;

   // getters and setters

}
</pre>
<p>An now a basic service:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace MyApp\Domain\Service;

use Doctrine\ORM\EntityManager;

class ProductService
{

    private $dm;

    public function __construct(EntityManager $dm)
    {
        $this-&gt;dm = $dm;
    }

    public function updateProduct(array $data, $id)
    {
        $product = $this-&gt;dm-&gt;getRepository('MyApp\Domain\Entity\Product')-&gt;find($id);

        if(!$product){
            throw new ProductNotFoundException();
        }

        $product-&gt;setName($data['name']);
        $product-&gt;setPrice($data['price']);

        $this-&gt;dm-&gt;flush();
    }

}
</pre>
<p>A fairly basic implementation of updating a product, don&#8217;t forget your life could be easier by using Doctrine&#8217;s ClassMetadata classes &#8211; though use it wisely. One thing to watch out for is your naming consistency with methods, (i.e. create v. add, delete v. remove, etc), I like to follow CRUD so I can always remember. Now working with your domain and persistence layer is much more hassle free from your controllers:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace MyApp\Admin\Catalog;

use MyApp\Library\Controllers\BackEndController

public function ProductController extends BackEndController
{

	public function updateAction()
	{
		$product = $this-&gt;getRequest()-&gt;getPost();

		// insert form validation and get filtered values (into $filteredProduct)

		$productService = new \MyApp\Domain\ProductService($this-&gt;resources()-&gt;entityManager);
		$productService-&gt;updateProduct($filteredProduct, $filteredProduct['id']);
	}

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cobbweb.me/2010/11/integrate-doctrine-2-zend-framework-application/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Global errors for your Zend_Forms</title>
		<link>http://cobbweb.me/2010/10/global-errors-for-your-zend_forms/</link>
		<comments>http://cobbweb.me/2010/10/global-errors-for-your-zend_forms/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 13:32:34 +0000</pubDate>
		<dc:creator>cobby</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cobbweb.me/?p=26</guid>
		<description><![CDATA[Zend_Form is definitely a great component of the Zend Framework library, but it really takes a lot to get the hang of the Element and Decorator system. Despite having a half decent knowledge of how it all fits together myself, I have been unable to figure out a way to attached generic errors to a [...]]]></description>
			<content:encoded><![CDATA[<p>Zend_Form is definitely a great component of the Zend Framework library, but it really takes a lot to get the hang of the Element and Decorator system. Despite having a half decent knowledge of how it all fits together myself, I have been unable to figure out a way to attached generic errors to a form, that is: errors that aren&#8217;t specific to certain form element. (E.g. A typical &#8216;Login Failed&#8217; for a login form).</p>
<p>So for my latest application I&#8217;ve decided I whip up a custom Form class and a GenericError decorator.</p>
<p>To start off, our custom Form class will need somewhere to store errors and getters/setters:</p>
<pre class="brush: php; title: ; notranslate">

/**
 * Custom Form Class
 */
class Cob_Form extends Zend_Form
{

	/**
	 * Stores generic errors
	 */
    protected $_genericErrors = array();

	/**
	 * Add a single generic error
	 *
	 * @param string $error Generic error message
	 * @return Cob_Form
	 */
    public function addGenericError($error)
    {
        $this-&gt;_genericErrors[] = $error;
        return $this;
    }

	/**
	 * Append an array of generic errors
	 *
	 * @param array $errors Generic error messages
	 * @return Cob_Form
	 */
    public function addGenericErrors(array $errors)
    {
        $this-&gt;_genericErrors = array_merge($this-&gt;_genericErrors, $errors);
        return $this;
    }

	/**
	 * Set the generic errors
	 *
	 * @param array $errors Generic error messages
	 * @return Cob_Form
	 */
    public function setGenericErrors(array $errors)
    {
        $this-&gt;_genericErrors = $errors;
        return $this;
    }

	/**
	 * Set generic error
	 *
	 * @param array $errors Generic error message
	 * @return Cob_Form
	 */
    public function setGenericError($error)
    {
        $this-&gt;_genericErrors = array($error);
        return $this;
    }

    /**
 	 * Retrieve all generic error messages
 	 *
	 * @return array
	 */
    public function getGenericErrors()
    {
        return $this-&gt;_genericErrors;
    }

	/**
	 * Returns true is any errors messages have been added
	 *
	 * @return bool
	 */
    public function hasGenericErrors()
    {
        return count($this-&gt;_genericErrors) &gt; 0;
    }

}
</pre>
<p>The above is nothing special, but I&#8217;ve added method chaining with the setters to maintain consistent API.</p>
<p>The next step is to write our decorator so the form will automatically render the errors if any are set.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Zend_Form decorator to render generic errors
 *
 * @author Andrew Cobby
 */
class Cob_Form_Decorator_GenericErrors extends Zend_Form_Decorator_Abstract
{

	/**
	 * Render generic errors
	 *
	 * @param string $content
	 * @return string
	 */
	public function render($content = '')
	{
		$form = $this-&gt;getElement();
        $view    = $form-&gt;getView();

		if(!($form instanceof Cob_Form)){
			throw Zend_Form_Exception(&quot;You can only use the GenericErrors decorator with forms that subclass Cob_Form&quot;);
		}

        if (null === $view) {
            return $content;
        }

        $errors = $form-&gt;getGenericErrors();
        if (empty($errors)) {
            return $content;
        }

        $separator = $this-&gt;getSeparator();
        $placement = $this-&gt;getPlacement();
        $errors    = $view-&gt;formErrors($errors, $this-&gt;getOptions());

        switch ($placement) {
            case self::APPEND:
                return $content . $separator . $errors;
            case self::PREPEND:
                return $errors . $separator . $content;
        }
	}

}
</pre>
<p>The above decorator is almost an exact copy of the existing Errors decorator, but I had to tweak it a bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://cobbweb.me/2010/10/global-errors-for-your-zend_forms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Framework Action Helpers and Namespaces</title>
		<link>http://cobbweb.me/2010/05/zend-action-helpers-and-namespaces/</link>
		<comments>http://cobbweb.me/2010/05/zend-action-helpers-and-namespaces/#comments</comments>
		<pubDate>Sat, 22 May 2010 00:09:50 +0000</pubDate>
		<dc:creator>cobby</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[namespaces]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.cobbweb.me/?p=3</guid>
		<description><![CDATA[In my current Zend Framework project, I am using PHP 5.3&#8242;s namespaces for all my library code (It makes sense considering I&#8217;m using Doctrine 2 and will attempt to upgrade to ZF 2 when it&#8217;s released). I have come across a few compatibility issues when trying to use namespaces, mostly with Zend&#8217;s PluginLoader and Phing. [...]]]></description>
			<content:encoded><![CDATA[<p>In my current <a href="http://www.zendframework.com">Zend Framework</a> project, I am using PHP 5.3&#8242;s namespaces for all my library code (It makes sense considering I&#8217;m using <a href="http://www.doctrine-project.org">Doctrine 2</a> and will attempt to upgrade to ZF 2 when it&#8217;s released). I have come across a few compatibility issues when trying to use namespaces, mostly with Zend&#8217;s PluginLoader and <a href="http://www.phing.info">Phing</a>. Below is how I have my action helpers setup:</p>
<pre>
site/
  library/
    Cob/
      Controller/
        Action/
          HelperBroker.php
          Helper/
            Myhelper.php
            HelperAbstract.php
</pre>
<p><strong>HelperBroker.php</strong></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Cob\Controller\Action;

use \Zend_Controller_Action_HelperBroker;

/**
 * Custom implementation of the HelperBroker to provide namespace support
 *
 * @author Andrew Cobby
 */

class HelperBroker extends Zend_Controller_Action_HelperBroker {

    /**
     * Add a namespace prefix (works the same as Zend_Helper_BrokerBroker::addPrefix()
     *
     * @param string $prefix Namespace prefix
     */
    static public function addNamespacePrefix($prefix)
    {
        $prefix = rtrim($prefix, '\\') . '\\';
        $path = str_replace('\\', DIRECTORY_SEPARATOR, $prefix);
        $path = rtrim($path, '/');
        self::getPluginLoader()-&gt;addPrefixPath($prefix, $path);
    }

    /**
     * Adds an array of helpers
     *
     * @param array $helpers Helpers
     */
    static public function addHelpers(array $helpers)
    {
        foreach($helpers as $helper){
            parent::addHelper($helper);
        }
    }

}
</pre>
<p><strong>HelperAbstract.php</strong></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Cob\Controller\Action\Helper;

use \Zend_Controller_Action_Helper_Abstract;

/**
 * Abstract helper for namespaced action helpers
 *
 * @author Andrew Cobby
 */

class HelperAbstract extends Zend_Controller_Action_Helper_Abstract
{

    /**
     * Fix to get the correct helper name (Overrides Zend_Controller_Action_HelperAbstract::getName)
     *
     * @return string
     */
    public function getName()
    {
        $className = get_class($this);
        if(strpos($className, '\\') !== false){
            $helperName = strrchr($className, '\\');
            return ltrim($helperName, '\\');
        }elseif(strpos($className, '_') !== false){
            $helperName = strrchr($className, '_');
            return ltrim($className, '_');
        }else{
            return $className;
        }
    }

}
</pre>
<p><strong>Myhelper.php</strong></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Cob\Controller\Action\Helper;

/**
 * Example helper that uses namespaces
 *
 * @author Andrew Cobby
 */

class Myhelper extends HelperAbstract
{

    public function direct()
    {
        return 'Namespaces are cool!!';
    }

}
</pre>
<p>Before you starting using this, you will need to add your namespace prefix in our new HelperBroker:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Cob\Controller;

use \Zend_Controller_Action;
use \Cob\Controller\Action\HelperBroker;

class Action extends Zend_Controller_Action
{

    public function preDispatch()
    {
        HelperBroker::addNamespacePrefix('Cob\Controller\Action\Helper\\'); // remember 2 trailing slashes to fix the escaping
        $coolio = $this-&gt;_helper-&gt;Myhelper(); // calling a helper is still the same
    }
}
</pre>
<p>As you can see, the only real part of the compatibility issue is overriding HelperAbstract::getName(), the methods in HelperBroker are more just for convenience.<br />
Hope this helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://cobbweb.me/2010/05/zend-action-helpers-and-namespaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

