<?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>Weblog van Paul de Raaij</title>
	<atom:link href="http://www.paulderaaij.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.paulderaaij.nl</link>
	<description>Algemeen weblog van Paul de Raaij</description>
	<lastBuildDate>Fri, 03 Feb 2012 11:19:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Afgestudeerd!</title>
		<link>http://www.paulderaaij.nl/2012/02/03/afgestudeerd/</link>
		<comments>http://www.paulderaaij.nl/2012/02/03/afgestudeerd/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 11:17:10 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[LOI/Opleiding]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=243</guid>
		<description><![CDATA[Na 2,5 jaar bloed, zweet en tranen heb ik gisteravond de laatste horde genomen in mijn opleidingstraject. De laatste horde was het verdedigen van mijn scriptie en het geven van een presentatie over een gerelateerd technisch onderwerp. Als onderwerp had ik gekozen voor SOLID design. De slides heb ik beschikbaar gesteld op Slideshare voor nieuwsgierigen. [...]]]></description>
			<content:encoded><![CDATA[<p>Na 2,5 jaar bloed, zweet en tranen heb ik gisteravond de laatste horde genomen in mijn opleidingstraject. De laatste horde was het verdedigen van mijn scriptie en het geven van een presentatie over een gerelateerd technisch onderwerp. Als onderwerp had ik gekozen voor SOLID design. De slides heb ik beschikbaar gesteld op Slideshare voor nieuwsgierigen.</p>
<div style="width:425px" id="__ss_11401232"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/pderaaij/afstudeer-presentatie-solid-design" title="Afstudeer presentatie: Solid design" target="_blank">Afstudeer presentatie: Solid design</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/11401232" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/pderaaij" target="_blank">pderaaij</a> </div>
</p></div>
<div style="padding: 5px 0 12px;">Eindresultaat van het afstuderen? Een 8! Daar ben ik erg blij mee en daarmee heb ik voldoende punten gehaald voor het diploma. Vanaf vandaag ben ik dan ook Bachelor of ICT!</div>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2012%2F02%2F03%2Fafgestudeerd%2F&amp;title=Afgestudeerd%21"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2012/02/03/afgestudeerd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend_Pdf drawing multi-line text</title>
		<link>http://www.paulderaaij.nl/2011/10/31/zend_pdf-drawing-multi-line-text/</link>
		<comments>http://www.paulderaaij.nl/2011/10/31/zend_pdf-drawing-multi-line-text/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 12:12:04 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[magento]]></category>
		<category><![CDATA[multi-line text]]></category>
		<category><![CDATA[zend_pdf]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=238</guid>
		<description><![CDATA[Here is an easy trick to enter multi-line text with Zend_Pdf which I use in some Magento PDF creators $this-&#62;y = 150; $description = wordwrap(strip_tags($product-&#62;getDescription()), 110, &#34;&#60;br /&#62;&#34;); foreach (explode(&#34;&#60;br /&#62;&#34;, $description) as $i =&#62; $line) { $page-&#62;drawText($line, 65, $this-&#62;y - $i * 12, 'UTF-8'); }]]></description>
			<content:encoded><![CDATA[<p>Here is an easy trick to enter multi-line text with Zend_Pdf which I use in some Magento PDF creators</p>
<pre class="brush: php; title: ;">
$this-&gt;y = 150;
$description = wordwrap(strip_tags($product-&gt;getDescription()), 110, &quot;&lt;br /&gt;&quot;);
 foreach (explode(&quot;&lt;br /&gt;&quot;, $description) as $i =&gt; $line) {
     $page-&gt;drawText($line, 65, $this-&gt;y - $i * 12, 'UTF-8');
}
</pre>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2011%2F10%2F31%2Fzend_pdf-drawing-multi-line-text%2F&amp;title=Zend_Pdf%20drawing%20multi-line%20text"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2011/10/31/zend_pdf-drawing-multi-line-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I-7: Onderzoek Apple &amp; Geo-Informatie</title>
		<link>http://www.paulderaaij.nl/2011/07/23/i-7-onderzoek-apple-geo-informatie/</link>
		<comments>http://www.paulderaaij.nl/2011/07/23/i-7-onderzoek-apple-geo-informatie/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 14:22:58 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[LOI/Opleiding]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[geo informatie]]></category>
		<category><![CDATA[HHS]]></category>
		<category><![CDATA[onderzoek]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=233</guid>
		<description><![CDATA[Voor het laatste major blok op de HHS moesten we een onderzoek uitvoeren naar een onderwerp naar keuze. Samen met een studiegenoot besloten we om een onderzoek te doen naar de perikelen rond de opslag van geografische informatie op Apple devices. Dit onderzoek hebben we beoordeeld gekregen met een 8 en daar zijn we dan [...]]]></description>
			<content:encoded><![CDATA[<p>Voor het laatste major blok op de HHS moesten we een onderzoek uitvoeren naar een onderwerp naar keuze. Samen met een studiegenoot besloten we om een onderzoek te doen naar de perikelen rond de opslag van geografische informatie op Apple devices. </p>
<p>Dit onderzoek hebben we beoordeeld gekregen met een 8 en daar zijn we dan ook blij mee. We hebben ons best gedaan om zo nauwkeurig mogelijk te werk te gaan, maar kunnen niet garanderen dat het foutloos is. </p>
<p><a href="http://www.paulderaaij.nl/wp-content/uploads/Onderzoek-Apple-Geo-Informatie.pdf" target="_blank" >Lees hier het onderzoeksrapport</a></p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2011%2F07%2F23%2Fi-7-onderzoek-apple-geo-informatie%2F&amp;title=I-7%3A%20Onderzoek%20Apple%20%26%23038%3B%20Geo-Informatie"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2011/07/23/i-7-onderzoek-apple-geo-informatie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Valideren elfproef met jquery.validate</title>
		<link>http://www.paulderaaij.nl/2011/06/10/valideren-elfproef-met-jquery-validate/</link>
		<comments>http://www.paulderaaij.nl/2011/06/10/valideren-elfproef-met-jquery-validate/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 09:39:18 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[elfproef]]></category>
		<category><![CDATA[jquery.vlidate]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=230</guid>
		<description><![CDATA[Aangezien ik iedere keer weer een custom validatie op bankrekeningnummers moest schrijven, werd het maar eens tijd om het in het digitale archief te plaatsen. Wellicht heeft iemand er nog wat aan&#8230; jQuery.validator.addMethod("elfproef", function(value, element) { var sum=0; for (i=1; i]]></description>
			<content:encoded><![CDATA[<p>Aangezien ik iedere keer weer een custom validatie op bankrekeningnummers moest schrijven, werd het maar eens tijd om het in het digitale archief te plaatsen. Wellicht heeft iemand er nog wat aan&#8230;</p>
<p><code><br />
jQuery.validator.addMethod("elfproef", function(value, element) {<br />
	var sum=0;<br />
	for (i=1; i<10; i++) {<br />
		amount=value.charAt(i-1);<br />
		sum+=amount*(10-i);<br />
	} </p>
<p>	if (sum % 11==0 &#038;&#038; value.length==9) {<br />
		return true<br />
	} else {<br />
		return false<br />
	}<br />
}, "Vul hier een geldige bankrekeningnummer in.");<br />
</code></p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2011%2F06%2F10%2Fvalideren-elfproef-met-jquery-validate%2F&amp;title=Valideren%20elfproef%20met%20jquery.validate"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2011/06/10/valideren-elfproef-met-jquery-validate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Doctrine in Joomla</title>
		<link>http://www.paulderaaij.nl/2011/03/05/using-doctrine-in-joomla/</link>
		<comments>http://www.paulderaaij.nl/2011/03/05/using-doctrine-in-joomla/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 14:44:19 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[joomla]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=213</guid>
		<description><![CDATA[Joomla is a decent CMS with very nice features. It works great for the end user and has many components ready to use from the online world. What I don&#8217;t like personally, as a developer, is the model implementation in Joomla. For me the way &#8216; model and table&#8217; classes are implemented, just doesn&#8217;t feel [...]]]></description>
			<content:encoded><![CDATA[<p>Joomla is a decent CMS with very nice features. It works great for the end user and has many components ready to use from the online world. What I don&#8217;t like personally, as a developer, is the model implementation in Joomla. For me the way &#8216; model and table&#8217; classes are implemented, just doesn&#8217;t feel right to me. Also it is very difficult to get other models in a controller or an other model class.</p>
<p><span id="more-213"></span></p>
<p>With Symfony I have worked with Doctrine regularly and in this blog I&#8217;ll show you how to use Doctrine for your own component in Joomla. Doctrine is an Object Relational  Mapping framework and offers you a persistence library. This not the holy grail and you should determine  if you need the extra overhead and if you are comfortable with it.</p>
<h2>The first step</h2>
<p>I&#8217;ll start with an clean Joomla 1.6 install from the Joomla website. Also I installed <a href="http://www.doctrine-project.org/projects/orm/download">Doctrine ORM</a> from the Doctrine website. I unpacked the archive in  a new folder in the Joomla folder libraries.The structure in this new folder would be the same as the archive, so you get a Doctrine folder and a bin folder in the libraries/doctrine folder.</p>
<p>By the way, we live in 2011 and the current release of PHP is 5.3.5. Doctrine and the implementation I show you here assumes you use PHP 5.3. If you still use PHP 5.2 you seriously need to work on the upgrade of that projects.</p>
<h2>The example</h2>
<p>I&#8217;m going to provide you a very simple example. The most important thing I want to show you is how to implement Doctrine in your Joomla project, not how to use Doctrine. The documentation on the Doctrine website is of high quality and should give you enough information to get going.</p>
<p>We are writing a new component called Bugs end hold one entity called &#8216;Bug&#8217;. It has five attributes. ID, title, description, notificationDate and solvedDate. In the controller I&#8217;ll show you some examples how to use it.</p>
<h2>Setting up the defaults</h2>
<p>It is possible that you want to use Doctrine on multiple components you are going to write. This is the reason why I choose to add Doctrine to the libraries folder. In this folder we are going to add two files. One is an interface to provide a generic interface, the other is a bootstrapper to get Doctrine going. First the easy stuff, the interface.</p>
<p>The interface looks like this:</p>
<pre class="brush: php; title: ;">

&lt;?php

interface JoomlaDoctrineController {
public function setEntityManager(Doctrine\ORM\EntityManager $entityManager);
}

?&gt;
</pre>
<p>Nothing spectacular  here, lets move on.</p>
<p>Doctrine needs to have some basic configuration to get going. We need to tell Doctrine where it can find the entities and where it needs to place the generated proxies. Here is the implementation of JoomlaDoctrineBootstrapper:</p>
<pre class="brush: php; title: ;">
&lt;?php
/**
 * Configuration class to integrate Doctrine into Joomla.
 *
 * @author pderaaij &lt;paul@paulderaaij.nl&gt;
 */

use Doctrine\Common\ClassLoader,
    Doctrine\ORM\EntityManager,
    Doctrine\ORM\Configuration,
   Doctrine\Common\Cache\ArrayCache;

if( !class_exists('\Doctrine\Common\Classloader')) {
    require_once dirname(__FILE__) . '/../doctrine/Doctrine/Common/ClassLoader.php';
}

class JoomlaDoctrineBootstrapper {

    const APP_MODE_DEVELOPMENT = 1;
    const APP_MODE_PRODUCTION  = 2;

    private $applicationMode;
    private $cache;
    private $entityLibrary;
    private $proxyLibrary;
    private $proxyNamespace;
    private $entityManager;
    private $connectionOptions;

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

    public function getConnectionOptions() {
        return $this-&gt;connectionOptions;
    }

    public function setConnectionOptions($connectionOptions) {
        $this-&gt;connectionOptions = $connectionOptions;
    }

    public function getProxyLibrary() {
        return $this-&gt;proxyLibrary;
    }

    public function setProxyLibrary($proxyLibrary) {
        $this-&gt;proxyLibrary = $proxyLibrary;
    }

    public function getProxyNamespace() {
        return $this-&gt;proxyNamespace;
    }

    public function setProxyNamespace($proxyNamespace) {
        $this-&gt;proxyNamespace = $proxyNamespace;
    }

    public function getCache() {
        return $this-&gt;cache;
    }

    public function setCache($cache) {
        $this-&gt;cache = $cache;
    }

    public function getEntityLibrary() {
        return $this-&gt;entityLibrary;
    }

    public function setEntityLibrary($entityLibrary) {
        $this-&gt;entityLibrary = $entityLibrary;
    }

    public function getApplicationMode() {
        return $this-&gt;applicationMode;
    }

    public function setApplicationMode($applicationMode) {
        $this-&gt;applicationMode = $applicationMode;
    }

    public function getEntityManager() {
        return $this-&gt;entityManager;
    }

    public function setEntityManager($entityManager) {
        $this-&gt;entityManager = $entityManager;
    }

    /**
     * Bootstrap Doctrine, setting the libraries and namespaces and creating
     * the entitymanager
     */
    public function bootstrap() {
        $this-&gt;registerClassLoader();

        // Load cache
        if ($this-&gt;getApplicationMode() == self::APP_MODE_DEVELOPMENT) {
            $this-&gt;cache = new ArrayCache;
        } else {
            $this-&gt;cache = new ApcCache;
        }

        /** @var $config Doctrine\ORM\Configuration */
        $config = new Configuration;
        $config-&gt;setMetadataCacheImpl($this-&gt;cache);
        $driverImpl = $config-&gt;newDefaultAnnotationDriver($this-&gt;getEntityLibrary());

        $config-&gt;setMetadataDriverImpl($driverImpl);
        $config-&gt;setQueryCacheImpl($this-&gt;cache);
        $config-&gt;setProxyDir($this-&gt;getProxyLibrary());
        $config-&gt;setProxyNamespace($this-&gt;getProxyNamespace());

        if ($this-&gt;applicationMode == self::APP_MODE_DEVELOPMENT) {
            $config-&gt;setAutoGenerateProxyClasses(true);
        } else {
            $config-&gt;setAutoGenerateProxyClasses(false);
        }

        $this-&gt;entityManager = EntityManager::create($this-&gt;getConnectionOptions(), $config);
    }

    /**
     * Register the different classloaders for each type.
     */
    private function registerClassLoader() {
        // Autoloader for all the Doctrine library files
        $classLoader = new ClassLoader('Doctrine', dirname(__FILE__) . '/');
        $classLoader-&gt;register();

        // Autoloader for all Entities
        $modelLoader = new ClassLoader('Entities', $this-&gt;getEntityLibrary());
        $modelLoader-&gt;register();

        // Autoloader for all Proxies
        $proxiesClassLoader = new ClassLoader('Proxies', $this-&gt;getProxyLibrary());
        $proxiesClassLoader-&gt;register();
    }

}
?&gt;</pre>
<div>Okay, what&#8217;s going on here. As said earlier we are expecting an PHP 5.3 application, so we are making a lot of use of namespaces here. We are loading some base classes of Doctrine so we can bootstrap it.</div>
<div>You see two constants in this class. These constants are flags you can use to set the environment the application is in. Is the application is used in a production environment it will make use of the APC cache. In development it will use a simple ArrayCache which is volatile.</div>
<div>If we skip the getters and setters we see two interesting functions. The first one is registerClassLoader. Here we register three classloaders. The first one is used to auto load all Doctrine classes. The second one we use for the entities we created. The proxies are auto loaded by the third class loader. The argument the last two classloaders receive are just absolute paths to the folder containing the belonging files.</div>
<div>In the bootstrap function we define the configuration for Doctrine. We define the cache it needs to use, the AnnotationDriver and the folders where Doctrine can find proxies and entities. To learn more about this configuration you should read the Doctrine manual. What we do here is a standard configuration, setting the right locations.</div>
<h2>Creating the component</h2>
<p>Now we can start with setting up our component. Create a com_bugs folder in components with a models folder in it. In the models folder you should create an Entities folder (mind the capital, it&#8217;s important!).</p>
<p>Create the &#8216;Bug&#8217; entity next. Copy the text below and place it in Bug.php in the models/Entities folder. Do not forget to set the namespace it is essential. If you forget it the entity can&#8217;t be found by the classloader. This is also the reason why the capitalization is so important.</p>
<pre class="brush: php; title: ;">

&lt;?php

namespace Entities;

/**

* @Entity @Table(name=&quot;bugs&quot;)

*/

class Bug {

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

private $id;

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

private $title;

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

private $description;

/** @Column(type=&quot;datetime&quot;) */

private $notificationDate;

/** @Column(type=&quot;datetime&quot;) */

private $solvedDate;

public function getId() {

return $this-&gt;id;

}

public function setId($id) {

$this-&gt;id = $id;

}

public function getTitle() {

return $this-&gt;title;

}

public function setTitle($title) {

$this-&gt;title = $title;

}

public function getDescription() {

return $this-&gt;description;

}

public function setDescription($description) {

$this-&gt;description = $description;

}

public function getNotificationDate() {

return $this-&gt;notificationDate;

}

public function setNotificationDate($notificationDate) {

$this-&gt;notificationDate = $notificationDate;

}

public function getSolvedDate() {

return $this-&gt;solvedDate;

}

public function setSolvedDate($solvedDate) {

$this-&gt;solvedDate = $solvedDate;

}

}

?&gt;
</pre>
<p>There is our entity! Now we need a way to get that entity definition in our database. Doctrine has command-line tools for us to do that, but they need the same configuration as we give to our controller in the front-end. So, lets set-up that configuration and use it on the command line.</p>
<h2>The configuration</h2>
<p>In order to use Doctrine within our controllers we have to create the configuration and use our created bootstrapper to get Doctrine going. At the moment I chose the component initialization file for our initialization work on Doctrine. I&#8217;m looking for a way to extract this initialization in to a nicer place, but the options I&#8217;ve tried didn&#8217;t made me happy at all.</p>
<p>What do we need to do? Well, we need to tell where our entities are stored on the file system and where we want to store our proxy files. also we need to pass our database parameters to Doctrine so it has authorization to the database. Here is my init file (bugs.php) of the component:</p>
<pre class="brush: php; title: ;">
&lt;?php
// no direct access
defined('_JEXEC') or die;

// Include dependancies
jimport('joomla.application.component.controller');

require_once(JPATH_LIBRARIES . '/doctrine/bootstrap.php');

$controller = JController::getInstance('Bugs');
// configure Doctrine thru the bootstrapper
$controller-&gt;setEntityManager(bootstrapDoctrine());
$controller-&gt;execute(JRequest::getCmd('task', 'index'));
$controller-&gt;redirect();

/**
 * Initialize doctrine by setting the entities and proxies locaties. Also define
 * a default namespace for the proxies.
 */
function bootstrapDoctrine() {
    $doctrineProxy = new JoomlaDoctrineBootstrapper( JoomlaDoctrineBootstrapper::APP_MODE_DEVELOPMENT );
    $doctrineProxy-&gt;setEntityLibrary(dirname(__FILE__) . '/models');
    $doctrineProxy-&gt;setProxyLibrary(dirname(__FILE__) . '/proxies');
    $doctrineProxy-&gt;setProxyNamespace('Joomla\Proxies');
    $doctrineProxy-&gt;setConnectionOptions(getConfigurationOptions());
    $doctrineProxy-&gt;bootstrap();

    return $doctrineProxy-&gt;getEntityManager();
}

function getConfigurationOptions() {
     // Define database configuration options
    $joomlaConfig = JFactory::getConfig();
    return array(
        'driver' =&gt; 'pdo_mysql',
        'path' =&gt; 'database.mysql',
        'dbname' =&gt; $joomlaConfig-&gt;get('db'),
        'user' =&gt;  $joomlaConfig-&gt;get('user'),
        'password' =&gt;  $joomlaConfig-&gt;get('password')
    );
}
</pre>
<p>What do we do here. We retrieve an instance of our controller and our going to inject an EntityManager to this controller. In order to this we are going to call the JoomlaDoctrineBootstrapper, set the configuration parameters and it will return us the EntityManager. To make the configuration and use a little easier we are using the database credentials from the Joomla configuration.</p>
<p>That&#8217;s nice for the front-end, but how about that command line tool? Well Doctrine will search for a file called &#8216;cli-config.php&#8217; on the location you call the doctrine command line tool. The file &#8216;cli-config.php&#8217; will return an EntityManager using the configuration we set from our bootstrap file.</p>
<p>Before we start sorting out this file, a little notice. This file is somewhat strange. We have to perform a number of tricks so we can make use of the Joomla framework on the command line. The way we do use led to the fact we need a separate configuration file containing the database credentials and other configuration options. I&#8217;m sure that a number of trick I use here aren&#8217;t necessary, but I just can&#8217;t find a better way to do this. If you know the trick, please let me know. I, for sure, don&#8217;t like the way this file has been built up and would love to improve it.</p>
<p>Now with that out, I&#8217;ll show you the file.</p>
<pre class="brush: php; title: ;">
&lt;?php
// We are a valid Joomla entry point.
define('_JEXEC', 1);

// Setup the path related constants.
define('DS', DIRECTORY_SEPARATOR);
define('JPATH_BASE', __DIR__ . '/../../');
define('JPATH_ROOT', JPATH_BASE);
define('JPATH_CONFIGURATION', JPATH_BASE);
define('JPATH_LIBRARIES', JPATH_BASE.DS.'libraries');
define('JPATH_METHODS', JPATH_ROOT.DS.'methods');

// Load the library importer.
require_once (JPATH_LIBRARIES.'/joomla/import.php');
require_once (JPATH_CONFIGURATION.'/configuration.php');

// Import library dependencies.
jimport('joomla.application.application');
jimport('joomla.utilities.utility');
jimport('joomla.language.language');
jimport('joomla.utilities.string');
jimport('joomla.factory');

require_once __DIR__ . '/../../libraries/doctrine/bootstrap.php';

/**
 * Initialize doctrine by setting the entities and proxies locaties. Also define
 * a default namespace for the proxies.
 */
function bootstrapDoctrine() {
    $doctrineProxy = new JoomlaDoctrineBootstrapper( JoomlaDoctrineBootstrapper::APP_MODE_DEVELOPMENT );
    $doctrineProxy-&gt;setEntityLibrary(dirname(__FILE__) . '/models');
    $doctrineProxy-&gt;setProxyLibrary(dirname(__FILE__) . '/proxies');
    $doctrineProxy-&gt;setProxyNamespace('Joomla\Proxies');
    $doctrineProxy-&gt;setConnectionOptions(getConfigurationOptions());
    $doctrineProxy-&gt;bootstrap();

    return $doctrineProxy-&gt;getEntityManager();
}

function getConfigurationOptions() {
     // Define database configuration options
    $joomlaConfig = JFactory::getConfig(JPATH_BASE . '/cli-configuration.php');
    return array(
        'driver' =&gt; 'pdo_mysql',
        'path' =&gt; 'database.mysql',
        'dbname' =&gt; $joomlaConfig-&gt;get('db'),
        'user' =&gt;  $joomlaConfig-&gt;get('user'),
        'password' =&gt;  $joomlaConfig-&gt;get('password')
    );
}

$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'em' =&gt; new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper(bootstrapDoctrine())
));
</pre>
<p>The first part of the file is just bootstrapping of the Joomla framework. We determine the location of some core folders, we import core classes and all that will bootstrap the Joomla Framework. Then two function follow that we have seen before. The only difference is that we can&#8217;t use the default configuration, which will give us an blank configuration class, but an alternative file. Why not the default file? Well the default file is of the type JConfig and the factory expects an JFrameworkConfig to import.</p>
<p>The bottom three lines are the default code of Doctrine to get the command line tools going. You see, the only thing we do here is setting the EntityManager. More information about this file can be found on the Doctrine website.</p>
<h2>The last mile</h2>
<p>It has been a long way already, but we are getting there.The last thing I&#8217;m going to show you is how to make use of the Doctrine. If you remember we have created an interface earlier in this blog. Just implement this on your controller and implement the setEntityManager() method as required by the interface.</p>
<p>If you look back in the init file of the component we are using this method to set the EntityManager on the controller. We use the interface to make sure we use an generic method on all the controllers. In the example below you see how I created a simple example which makes use of Doctrine and outputs some basic information.</p>
<pre class="brush: php; title: ;">
&lt;?php

// No direct access
defined('_JEXEC') or die;

jimport('joomla.application.component.controller');
require_once(JPATH_LIBRARIES . '/doctrine/JoomlaDoctrineController.php');

/**
 * Description of BugsController
 *
 * @author pderaaij
 */
class BugsController extends JController implements JoomlaDoctrineController {

    /**
     *
     * @var Doctrine\ORM\EntityManager
     */
    private $em;

    public function setEntityManager(Doctrine\ORM\EntityManager $entityManager) {
        $this-&gt;em = $entityManager;
    }

    public function index() {
        // add a default bug every refresh
        $newBug = new Entities\Bug();
        $newBug-&gt;setTitle('Doctrine Test');
        $newBug-&gt;setDescription('test');
        $newBug-&gt;setNotificationDate(new DateTime());
        $newBug-&gt;setSolvedDate(new DateTime());
        $this-&gt;em-&gt;persist($newBug);
        $this-&gt;em-&gt;flush();

        $dql = &quot;SELECT b FROM Entities\Bug b&quot;;
        $query = $this-&gt;em-&gt;createQuery($dql);
        $query-&gt;setMaxResults(30);
        $bugs = $query-&gt;getResult();

        echo '&lt;h1&gt;Bug overview&lt;/h1&gt;';
        echo '&lt;table width=&quot;100%&quot;&gt;';
        echo '&lt;tr&gt;';
            echo '&lt;th&gt;#&lt;/th&gt;';
            echo '&lt;th&gt;Title&lt;/th&gt;';
            echo '&lt;th&gt;Notification date&lt;/th&gt;';
            echo '&lt;th&gt;Date solved&lt;/th&gt;';
        echo '&lt;/tr&gt;';

        foreach( $bugs as $bug ) {
            /* @var $bug Bug */
            echo '&lt;tr&gt;';
                echo '&lt;td&gt;' . $bug-&gt;getId() . '&lt;/td&gt;';
                echo '&lt;td&gt;' . $bug-&gt;getTitle() . '&lt;/td&gt;';
                echo '&lt;td&gt;' . $bug-&gt;getNotificationDate()-&gt;format(&quot;Y-m-d H:i:s&quot;) . '&lt;/td&gt;';
                echo '&lt;td&gt;' . $bug-&gt;getSolvedDate()-&gt;format(&quot;Y-m-d H:i:s&quot;) . '&lt;/td&gt;';
            echo '&lt;/tr&gt;';
        }

        echo '&lt;/table&gt;';

        echo '&lt;h1&gt;Bug #1&lt;/h1&gt;';
        $bug = $this-&gt;em-&gt;find(&quot;Entities\Bug&quot;, 1);
        echo '&lt;pre&gt;';
            var_dump($bug);
        echo '&lt;/pre&gt;';
    }

}
?&gt;
</pre>
<h2>It&#8217;s a wrap</h2>
<p>That&#8217;s it, now you can make use of Doctrine within your component. It was a long blog post, but I hope I&#8217;ve shown you an easy way to get going with Doctrine within Joomla.</p>
<p>I hope you liked this article. You can leave your feedback behind on this blog, since I&#8217;m always interested in new insights which I can use to learn and grow as an developer.</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2011%2F03%2F05%2Fusing-doctrine-in-joomla%2F&amp;title=Using%20Doctrine%20in%20Joomla"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2011/03/05/using-doctrine-in-joomla/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>RTL gemist bekijken op Ubuntu 10.10</title>
		<link>http://www.paulderaaij.nl/2011/02/12/rtl-gemist-bekijken-op-ubuntu-10-10/</link>
		<comments>http://www.paulderaaij.nl/2011/02/12/rtl-gemist-bekijken-op-ubuntu-10-10/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 08:59:11 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[Algemeen]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=211</guid>
		<description><![CDATA[Als groot liefhebber van Voetbal International vond ik het vrij frustrerend dat ik dit programma niet terug kon kijken via mijn Ubuntu omgeving. Door het hele DRM gebeuren wat Moonlight niet ondersteund was het niet te doen om via rtlgemist.nl de afleveringen te bekijken. Via forums een fix gevonden om toch rtl gemist afleveringen bekijken. [...]]]></description>
			<content:encoded><![CDATA[<p>Als groot liefhebber van Voetbal International vond ik het vrij frustrerend dat ik dit programma niet terug kon kijken via mijn Ubuntu omgeving. Door het hele DRM gebeuren wat Moonlight niet ondersteund was het niet te doen om via rtlgemist.nl de afleveringen te bekijken.</p>
<p><span id="more-211"></span></p>
<p>Via forums een fix gevonden om toch rtl gemist afleveringen bekijken. What to do:</p>
<p>Download de User Agent Switcher add-on voor Firefox: http://chrispederick.com/work/user-agent-switcher/. Voeg via het menu de volgende user agent toe:</p>
<p>Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10</p>
<p>Switch naar die user agent. Voor websites toe ben je nu een iPad waardoor je naar deze pagina kan surfen: http://www.rtl.nl/service/gemist/device/ipad/feed/index.xml</p>
<p>Hier kun je alle afleveringen terugkijken aangezien je nu direct toegang tot de mp4&#8242;s krijgt. De snelheid is hier wel beduidend lager, de laatste paar weken had ik met de iPad ook al veel buffer problemen en keek alleen maar naar haperende afleveringen. Hopelijk word dat nog gefixed.</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2011%2F02%2F12%2Frtl-gemist-bekijken-op-ubuntu-10-10%2F&amp;title=RTL%20gemist%20bekijken%20op%20Ubuntu%2010.10"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2011/02/12/rtl-gemist-bekijken-op-ubuntu-10-10/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A way to implement unit testing in Joomla!</title>
		<link>http://www.paulderaaij.nl/2010/07/31/a-way-to-implement-unit-testing-in-joomla/</link>
		<comments>http://www.paulderaaij.nl/2010/07/31/a-way-to-implement-unit-testing-in-joomla/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 12:21:28 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[joomla]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=203</guid>
		<description><![CDATA[Since a couple of months I&#8217;m not anymore self-employed and am I working for a company who develops for ActiveCollab, Magento and Joomla!. While developing I&#8217;m trying to work according the TDD paradigm. So you write your tests first and then you develop the business logic to succeed the failing test. I&#8217;d have to admit that Joomla! [...]]]></description>
			<content:encoded><![CDATA[<p>Since a couple of months I&#8217;m not anymore self-employed and am I working for a company who develops for ActiveCollab, Magento and Joomla!. While developing I&#8217;m trying to work according the TDD paradigm. So you write your tests first and then you develop the business logic to succeed the failing test. I&#8217;d have to admit that Joomla! never will be my first choice to develop on, but it isn&#8217;t as bad some are preaching.</p>
<p><span id="more-203"></span></p>
<p>While getting my way around the Joomla! framework I have a big problem getting the checked in unit tests to run. If you do a checkout of the unit tests from the svn you&#8217;ll see there are about 960 tests and about 600 fails straight out of the box. Pretty annoying and unusable to write your own tests against.</p>
<p>So I&#8217;ve been working on a test runner of my own. The test runner tries to use the most of the Joomla! framework, but some things it just have to do itself. It consists of 2 files. One file is the testloader which is setup as an autoloader using the JLoad class. The second class sets some configuration files and kickstarts the Joomla! framework.</p>
<p><strong>Here&#8217;s the code for the testloader</strong></p>
<pre class="brush: php; title: ;">

&lt;?php

/**

* Testloader class

*

* This class strips the requested class and passes it thru

* to the Joomla autoload function

*

* @author Paul de Raaij &lt;paul@paulderaaij.nl&gt;

*/

// Preload the model so we can add paths to the inlude path of JLoader

jimport( 'joomla.application.component.model' );

class TestLoader {

/**

* Strip the given class and pass it to the

* Joomla autoloader.

*

* If it's a component add the path to the

* include path of the loader

*

* @param String $classname

* @return bool Has the inclusion succeeded

*/

static public function load( $classname ) {

$explodedPath = self::explodeClassname( $classname );

if( $explodedPath == null ) {

return self::loadJoomlaClass( $classname );

}

// Add the folder to the loader include path

JModel::addIncludePath('../components/com_' . $explodedPath['component'] . '/' . $explodedPath['type'] . 's');

return self::loadJoomlaClass( $classname );

}

/**

* Explode the classname and strip component name,

* type and type name

*

* @param string $classname

* @return mixed Returns null when it's a core file. Returns an array with data if it's a component data

*/

static protected function explodeClassname( $classname ) {

$types = array('model', 'controller', 'helper', 'view');

$classname = strtolower($classname);

if( $classname == 'jmodel' ) {

return null;

}

$fileInfo = array();

foreach( $types as $type ) {

if( false !== strpos($classname, $type) ) {

$fileInfo['type']       = $type;

}

}

if( isset( $fileInfo['type'] ) ) {

$fileInfo['component']  = substr($classname, 0, strpos($classname, $fileInfo['type'] ) );

$fileInfo['name']       = substr($classname, ( strpos($classname, $fileInfo['type'] ) + strlen($fileInfo['type']) ) );

return $fileInfo;

}

return null;

}

/**

* Simple pass thru function to the Joomla autoloader

*

* @param string $class

* @return bool Has inclusion succeeded?

*/

static public function loadJoomlaClass( $class ) {

return JLoader::load( $class );

}

}

?&gt;
</pre>
<p>And this is the TestCase class which is required by each unit test file:</p>
<pre class="brush: php; title: ;">

&lt;?php

require_once 'PHPUnit/Framework.php';

// We are a valid Joomla entry point.

define('_JEXEC', 1);

// Setup the path related constants.

define('DS', DIRECTORY_SEPARATOR);

define('JPATH_BASE', dirname( __FILE__ ) . '\..');

define('JPATH_ROOT', JPATH_BASE);

define('JPATH_CONFIGURATION', JPATH_BASE);

define('JPATH_LIBRARIES', JPATH_BASE.DS.'libraries');

define('JPATH_METHODS', JPATH_ROOT.DS.'methods');

// Load the library importer, datbase class and configuration

require_once (JPATH_LIBRARIES.'/joomla/import.php');

require_once (JPATH_LIBRARIES.'/joomla/database/database.php');

// Load the TestLoader

require_once dirname(__FILE__) . '\lib\TestLoader.php';

// register specific test autloader

if( !defined('LOADED_AUTOLOADER') ) {

spl_autoload_register( array('TestLoader', 'load') );

define('LOADED_AUTOLOADER', true);

}

// Define configuration

jimport( 'joomla.registry.registry' );

require_once( JPATH_CONFIGURATION.'/configuration.php' );

// Create the JConfig object

$config = new JConfig();

// Get the global configuration object

$registry =&amp; JFactory::getConfig();

// Load the configuration values into the registry

$registry-&gt;loadObject($config);

$options = array ('driver' =&gt; $config-&gt;driver,

'host' =&gt; $config-&gt;host,

'user' =&gt; $config-&gt;user,

'password' =&gt; $config-&gt;password,

'database' =&gt; $config-&gt;database,

'prefix' =&gt; $config-&gt;prefix );

// Preload database with configuration

$db = JDatabase::getInstance( $options );

?&gt;
</pre>
<p>An example unit test looks like this:</p>
<pre class="brush: php; title: ;">

&lt;?php

require_once dirname(__FILE__) . '\..\..\..\TestCase.php';

class Model_Test_Base extends PHPUnit_Framework_TestCase {

protected $model = null;

public function setUp() {

$this-&gt;model = JModel::getInstance('&lt;modelname&gt;', '&lt;componentname&gt;Model');

}

public function testSimpleAssertion() {

$this-&gt;assertTrue( $this-&gt;model-&gt;test() );

}

}

?&gt;
</pre>
<p>Perhaps this isn&#8217;t the best way to use unit testing in Joomla! But at the moment this is the only thing I got working. If you&#8217;ve got some suggestions your glad to leave it behind as a reaction!</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2010%2F07%2F31%2Fa-way-to-implement-unit-testing-in-joomla%2F&amp;title=A%20way%20to%20implement%20unit%20testing%20in%20Joomla%21"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2010/07/31/a-way-to-implement-unit-testing-in-joomla/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>het eerste schooljaar zit er op</title>
		<link>http://www.paulderaaij.nl/2010/07/24/het-eerste-schooljaar-zit-er-op/</link>
		<comments>http://www.paulderaaij.nl/2010/07/24/het-eerste-schooljaar-zit-er-op/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 09:17:30 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[LOI/Opleiding]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=199</guid>
		<description><![CDATA[Vorig jaar rond deze tijd besloot ik dat het echt niet verder kon met de LOI. Als ik namelijk door zou gaan met de HBO opleiding informatica bij hun, dan zou ik mijn diploma eens in 2020 op kunnen halen. Iets wat niet mijn bedoeling was. Na een korte oriëntatie besloot ik om mijn gelukt [...]]]></description>
			<content:encoded><![CDATA[<p>Vorig jaar rond deze tijd besloot ik dat het echt niet verder kon met de LOI. Als ik namelijk door zou gaan met de HBO opleiding informatica bij hun, dan zou ik mijn diploma eens in 2020 op kunnen halen. Iets wat niet mijn bedoeling was. Na een korte oriëntatie besloot ik om mijn gelukt te gaan beproeven bij de Haagse Hogeschool.</p>
<p>Het afgelopen jaar heb ik op dit blog al geregeld gepost hoe de opleiding mij verging. Over het algemeen ben ik best tevreden met de HHS, natuurlijk zijn er behoorlijk wat rare situaties, maar inmiddels begrijp ik ook wel dat je die overal wel tegenkomt.</p>
<p>Het laatste blok moesten we van een zeer oud en slecht geschreven programma het beheer op ons nemen en daar nieuwe functionaliteiten inbakken en dat volgens nette beheer methodes. Met weer een deels nieuw project groepje ging het ons aardig af. Voor de praktijk opdracht kregen we een 7 en voor de theoretische toets had ik een 7,3. Prima voor elkaar dus!</p>
<p>Eindresultaat van het eerste jaar is dan ook dat ik met de diverse vrijstellingen in het eerste jaar al 105 studiepunten heb gehaald, de propedeuse binnen is en dat ik lekker op schema lig om over 1,5 jaar het diploma op te halen.</p>
<p>Kortom&#8230; doe mij nog maar zo&#8217;n schooljaar!</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2010%2F07%2F24%2Fhet-eerste-schooljaar-zit-er-op%2F&amp;title=het%20eerste%20schooljaar%20zit%20er%20op"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2010/07/24/het-eerste-schooljaar-zit-er-op/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ik stop met ondernemen!</title>
		<link>http://www.paulderaaij.nl/2010/04/24/ik-stop-met-ondernemen/</link>
		<comments>http://www.paulderaaij.nl/2010/04/24/ik-stop-met-ondernemen/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 08:41:48 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[Algemeen]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=190</guid>
		<description><![CDATA[Deze week kon het dan eindelijk bekend worden. Ik heb besloten om te stoppen als ondernemer. Een beslissing die niet bepaald makkelijk genomen is, maar wel heel goed voelt. Zes jaar lang ben ik aan de gang gegaan met Mediactief en heb ik geprobeerd mijn droom te realiseren. De laatste maanden kwam ik er echter [...]]]></description>
			<content:encoded><![CDATA[<p>Deze week kon het dan eindelijk bekend worden. Ik heb besloten om te stoppen als ondernemer. Een beslissing die niet bepaald makkelijk genomen is, maar wel heel goed voelt.</p>
<p>Zes jaar lang ben ik aan de gang gegaan met Mediactief en heb ik geprobeerd mijn droom te realiseren. De laatste maanden kwam ik er echter steeds meer achter dat ik het niet zo gevormd kreeg zoals ik het graag zou willen hebben. Helaas, had ik ook niet het vertrouwen dat ik dit wel voor elkaar kreeg zoals ik zou willen. Als je daarbij optelt dat ik daardoor ook steeds meer het plezier kwijtraakte, dan is er maar een juiste beslissing.</p>
<p>En om eerlijk te zijn voel ik me er heel goed bij. Het is de juiste beslissing geweest en zeker ook geen schande. Ik voel dan ook geen schaamte en zie het ook niet als falen. Ik heb het geprobeerd en op tijd ingezien dat het mooi is geweest.</p>
<p>Het bedrijf is verkocht aan Eleven in Maasdijk. Zij nemen mijn klanten over en ook ik zal mij bij hun team voegen als webdeveloper. Daar kan ik gaan doen wat ik echt wil doen en dat is het ontwikkelen van (web)applicaties. Lekker in de code duiken zonder te denken aan de BTW aanslag die nog moet gebeuren en dat soort zaken.</p>
<p>Zes jaar lang heb ik me vol overgave gegeven voor mijn bedrijf en mijn klanten. Ik wil hun dan nogmaals ontzettend bedanken voor hun vertrouwen in mij en mijn team. Ik waardeer het zeer en weet zeker dat we samen met Eleven nog betere service en kwaliteit kunnen verlenen.</p>
<p>Ik heb er de volste vertrouwen in!</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2010%2F04%2F24%2Fik-stop-met-ondernemen%2F&amp;title=Ik%20stop%20met%20ondernemen%21"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2010/04/24/ik-stop-met-ondernemen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Custom symfony filters to filter model relations</title>
		<link>http://www.paulderaaij.nl/2010/04/21/custom-symfony-filters-to-filter-model-relations/</link>
		<comments>http://www.paulderaaij.nl/2010/04/21/custom-symfony-filters-to-filter-model-relations/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 10:17:21 +0000</pubDate>
		<dc:creator>Paul de Raaij</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.paulderaaij.nl/?p=186</guid>
		<description><![CDATA[For an application I was looking for a way to add filters in the generated admin application. We&#8217;de like to filter clients based on the articles or orders they have.  Lets take a look at the (simplified) schema: Account: columns: id:             { type: integer, primary: true, autoincrement: true, notnull: [...]]]></description>
			<content:encoded><![CDATA[<p>For an application I was looking for a way to add filters in the generated admin application. We&#8217;de like to filter clients based on the articles or orders they have.  Lets take a look at the (simplified) schema:</p>
<p><span id="more-186"></span></p>
<pre class="brush: php; title: ;">

Account:
columns:
id:             { type: integer, primary: true, autoincrement: true, notnull: true }
accountNumber:  { type: integer, notnull: true }
accountName:    { type: string(255), notnull: true }

Order:
columns:
id:             { type: integer, primary: true, autoincrement: true, notnull: true }
internID:       { type: string(20) }
accountID:      { type: integer, notnull: true }
locationID:    { type: integer }
orderDate:      { type: timestamp }
orderedBy:      { type: integer, notnull: true }
remarks:        { type: string(3000) }
orderDelivered: { type: boolean }
placedOrder:    { type: boolean }
relations:
Account:        { onDelete: CASCADE, local: accountID, foreign: id, foreignAlias: accountOrders }

Article:

columns:

id:            { type: integer, primary: true, autoincrement: true, notnull: true }
accountID:     { type: integer, notnull: true }

articleNumber: { type: string(15) }

description:   { type: string(255) }

currentStock:  { type: integer }

minimumStock:  { type: integer }

packageAmount: { type: integer }

previewFile:   { type: string( 255 ) }

remarks:       { type: string( 3000 ) }

internRemarks: { type: string( 5000 ) }

image:         { type: string( 255 ) }

relations:

Account:       { onDelete: CASCADE, local: accountID, foreign: id, foreignAlias: articleAccount }
</pre>
<p>In short. We have an account and each account has it own articles. The can order these articles and this is stored in the Order model ( and a bunch of others, which aren&#8217;t relevant for this post).</p>
<p>What we want to achieve is that we can filter the client list based on a article number or order id.</p>
<p>To do this I extended the generator.yml to add the two new fields.</p>
<pre class="brush: php; title: ;">
config:

fields:
articleNumber:     {label: Artikel nummer, type: string }
orderNumber:     {label: Order nummer, type: string }
</pre>
<p>Next thing to do is to modify the filter form of the account model. Here we&#8217;re going to add the two new fields to the filter form and give them a simple validator.</p>
<pre class="brush: php; title: ;">

public function configure()

{

parent::configure();

$this-&gt;widgetSchema['articleNumber'] = new sfWidgetFormInputText();

$this-&gt;validatorSchema['articleNumber'] = new sfValidatorPass(array('required'=&gt;'false'));

$this-&gt;widgetSchema['orderNumber'] = new sfWidgetFormInputText();

$this-&gt;validatorSchema['orderNumber'] = new sfValidatorPass(array('required'=&gt;'false'));

}
</pre>
<p>Now we want to add the filter values to the query so that the list actually gets filtered by the given values. Therefore were going to add a function for each of the filter fields. The function has one purpose and that is to add a where to the doctrine query.</p>
<pre class="brush: php; title: ;">

protected function addArticleNumberColumnQuery( Doctrine_Query $query, $field, $values) {

$rootAlias = $query-&gt;getRootAlias();

$fieldName = 'articleNumber';

$query-&gt;addWhere( sprintf('%s.articleAccount.%s = ?', $rootAlias, $fieldName), $values );

}

protected function addOrderNumberColumnQuery( Doctrine_Query $query, $field, $values) {

$rootAlias = $query-&gt;getRootAlias();

$fieldName = 'id';

$query-&gt;addWhere( sprintf('%s.accountOrders.%s = ?', $rootAlias, $fieldName), $values );

}
</pre>
<p>The name of the function is specific and has to match the format add%fieldname%ColumnQuery. The code in the functions are pretty self-explanatory. Somethings are hard coded and could be a  nicer. For example you could name the field accountOrders instead of orderNumber so that you can use the value of $field.</p>
<p>This is the simplest solution I could find for filtering a model based on its relations. If someone knows a better way I&#8217;d love to hear about it.</p>
<!-- PHP 5.x --><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.paulderaaij.nl%2F2010%2F04%2F21%2Fcustom-symfony-filters-to-filter-model-relations%2F&amp;title=Custom%20symfony%20filters%20to%20filter%20model%20relations"><img src="http://www.paulderaaij.nl/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.paulderaaij.nl/2010/04/21/custom-symfony-filters-to-filter-model-relations/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
