<?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>coudenysj</title>
	<atom:link href="http://blog.jachim.be/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jachim.be</link>
	<description>Jachim on &#039;web development&#039;</description>
	<lastBuildDate>Wed, 25 Apr 2012 09:47:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Installing PEAR</title>
		<link>http://blog.jachim.be/2012/04/installing-pear/</link>
		<comments>http://blog.jachim.be/2012/04/installing-pear/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 09:47:08 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[phar]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=175</guid>
		<description><![CDATA[This post is just a quick notice/warning for everyone wanting to install PEAR (especially on Windows): always download the latest go-pear.phar from http://pear.php.net/go-pear.phar. Before running the famous php -d phar.require_hash=0 go-pear.phar command, make sure the timestamp of the phar file is somewhere this year. For some reason PHP (and in my case Zend Server CE) always [...]]]></description>
			<content:encoded><![CDATA[<p>This post is just a quick notice/warning for everyone wanting to install <a href="http://pear.php.net">PEAR</a> (especially on Windows): <strong>always download the latest <em>go-pear.phar</em></strong> from <a title="Download the latest go-pear.phar file" href="http://pear.php.net/go-pear.phar">http://pear.php.net/go-pear.phar</a>.</p>
<p>Before running the famous <code>php -d phar.require_hash=0 go-pear.phar</code> command, make sure the timestamp of the <a href="http://php.net/manual/en/book.phar.php">phar file</a> is somewhere this year. For some reason PHP (and in my case Zend Server CE) always ships with the phar file from 2008&#8230;</p>
<p>It will save you a lot of time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2012/04/installing-pear/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>make test every PHP version and send feedback</title>
		<link>http://blog.jachim.be/2012/02/make-test-every-php-version-and-send-feedback/</link>
		<comments>http://blog.jachim.be/2012/02/make-test-every-php-version-and-send-feedback/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 06:00:26 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[make test]]></category>
		<category><![CDATA[QA]]></category>
		<category><![CDATA[RC]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=170</guid>
		<description><![CDATA[Since David Coallier&#8217;s talk during PHPBenelux, I realized the importance of running make test on all PHP releases and send feedback to PHP. It is so easy, that I will run it from now on every time a new release is announced. If you&#8217;re running on Mac, you might want to install Xcode, so you can [...]]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://onemoredigit.com/">David Coallier&#8217;s</a> talk during <a href="http://conference.phpbenelux.eu/2012">PHPBenelux</a>, I realized the importance of running <strong><code>make test</code></strong> on all PHP releases and send feedback to PHP.</p>
<p>It is so easy, that I will run it from now on every time a new release is <a href="http://qa.php.net/">announced</a>.</p>
<p>If you&#8217;re running on Mac, you might want to install Xcode, so you can run &#8220;make&#8221; on command line. If you&#8217;re on Linux, you&#8217;re all set to go.</p>
<p>How to do it:</p>
<ul>
<li>Open a shell</li>
<li>Create a directory (e.g. <code>mkdir ~/src/php</code>)</li>
<li>Download the latest version into the directory (e.g. <code>wget http://downloads.php.net/stas/php-5.4.0RC6.tar.gz</code>)</li>
<li>Untar the file (e.g. <code>tar -xzf php-5.4.0RC6.tar.gz</code>)</li>
<li>Go into the directory and run <strong><code>./configure</code></strong>, you should get output like:<br />
<code>checking for grep that handles long lines and -e... /usr/bin/grep<br />
checking for egrep... /usr/bin/grep -E<br />
checking for a sed that does not truncate output... /usr/bin/sed<br />
checking build system type... i386-apple-darwin11.2.0<br />
checking host system type... i386-apple-darwin11.2.0<br />
checking target system type... i386-apple-darwin11.2.0<br />
...<br />
Thank you for using PHP. </code></li>
<li>After that, you can run <strong><code>make</code></strong> and should get a lot of output ending in:<br />
<code>Build complete.<br />
Don't forget to run 'make test'.</code></li>
<li>After that, you should do as the previous command suggests and run <strong><code>make test</code></strong>. You should see all tests passing by.</li>
<li>After all tests are run, you will get a summary. In my case, I get the message: &#8220;You may have found a problem in PHP.&#8221;<br />
<code>Bug #55509 (segfault on x86_64 using more than 2G memory) [Zend/tests/bug55509.phpt]<br />
Sort with SORT_LOCALE_STRING [ext/standard/tests/array/locale_sort.phpt]</code></li>
<li>Whether you get an error or not, you should always send the report back to PHP. You can do that by just answering Y to the question: &#8220;Do you want to send this report now?&#8221;</li>
<li>Enter your email address and PHP will thank you.</li>
</ul>
<p>How hard was that?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2012/02/make-test-every-php-version-and-send-feedback/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOAP-ERROR: Parsing WSDL</title>
		<link>http://blog.jachim.be/2010/11/soap-error-parsing-wsdl/</link>
		<comments>http://blog.jachim.be/2010/11/soap-error-parsing-wsdl/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 14:03:12 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[soap]]></category>
		<category><![CDATA[web service]]></category>
		<category><![CDATA[webserice]]></category>
		<category><![CDATA[wsdl]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=149</guid>
		<description><![CDATA[If you&#8217;re writing or consuming webservices with PHP SOAP, it&#8217;s possible you run into the SOAP-ERROR: Parsing WSDL problem once. The complete error string is: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://host/service?wsdl' : &#60;specific error&#62; If you copy and paste the url (including the ?wsdl parameter) in the browser and you see the WSDL file, [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re writing or consuming webservices with <a href="http://php.net/manual/en/book.soap.php">PHP SOAP</a>, it&#8217;s possible you run into the <strong>SOAP-ERROR: Parsing WSDL</strong> problem once.</p>
<p>The complete error string is:<br />
<code>SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://host/service?wsdl' : &lt;specific error&gt;</code></p>
<p>If you copy and paste the url (including the <code>?wsdl</code> parameter) in the browser and you see the <a title="Web Services Description Language on w3.org" href="http://www.w3.org/TR/wsdl">WSDL</a> file, the problem lies in the fact that the PHP cannot reach the host.</p>
<p>When you connect to <em>http://host/service</em>, PHP fetches the XML from the WSDL page via fopen(&#8216;<em>http://host/service?wsdl</em>&#8216;) so it can use it to handle the request. In some cases, that request is not routed correct, resulting in the SOAP-ERROR.</p>
<p>Some solutions:</p>
<ul>
<li>Add the hostname in the hostfile of the server (<code>127.0.0.1 hostname</code>).</li>
<li>Add the hostname or IP address in the correct VirtualHost (<code>ServerAlias hostname</code>).</li>
</ul>
<p>You can test the code by adding a file on the server:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php
echo htmlentities(file_get_contents('http://host/service?wdsl'));</pre>
<p>That way, you know if the server can reach and read the XML file.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/11/soap-error-parsing-wsdl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disallow changes in Subversion tags</title>
		<link>http://blog.jachim.be/2010/08/disallow-changes-in-subversion-tags/</link>
		<comments>http://blog.jachim.be/2010/08/disallow-changes-in-subversion-tags/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 05:12:52 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Servers]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[pre-commit]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[tags]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=142</guid>
		<description><![CDATA[Because Subversion does not have explicit tags, and everything in the repository is just another folder or file (and thus editable), we sometimes have the need to secure or force our repository layout. Creating a tag is just making a copy of the trunk (or any branch) so you have a snapshot of how the [...]]]></description>
			<content:encoded><![CDATA[<p>Because Subversion does not have explicit tags, and everything in the repository is just another folder or file (and thus editable), we sometimes have the need to secure or force our <a href="http://blogs.open.collab.net/svn/2007/04/subversion_repo.html">repository layout</a>.</p>
<p>Creating a tag is just making a copy of the trunk (or any branch) so you have a snapshot of how the trunk looked at that given time. If you make changes in it, it is not just a snapshot anymore.</p>
<p>The solution for this problem lies in a <a href="http://svnbook.red-bean.com/en/1.5/svn.ref.reposhooks.pre-commit.html"><code>pre-commit</code> hook</a>, which uses the <code>--copy-info</code> parameter of the <a href="http://svnbook.red-bean.com/en/1.5/svn.ref.svnlook.c.changed.html"><code>svnlook changed</code></a> command.</p>
<p>The output of a normal <code>svnlook changed</code> looks like this:</p>
<pre class="brush: bash; title: ; notranslate">$ svnlook changed -t 670-ja /var/svn/repo
A   tags/0.1.1/</pre>
<p>Whereas the the command with <code>--copy-info</code> looks like this:</p>
<pre class="brush: bash; title: ; notranslate">$ svnlook changed -t 670-ja --copy-info /var/svn/repo
A + tags/0.1.1/
    (from trunk/:r6911)</pre>
<p>The <strong>+</strong> at position 3 indicates a copy, so in combination with the <strong>tags/</strong> string, you can block commits to tags without this <strong>+</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/08/disallow-changes-in-subversion-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keeping track of your config files</title>
		<link>http://blog.jachim.be/2010/06/keeping-track-of-your-config-files/</link>
		<comments>http://blog.jachim.be/2010/06/keeping-track-of-your-config-files/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 08:27:16 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[config files]]></category>
		<category><![CDATA[HeadURL]]></category>
		<category><![CDATA[Id]]></category>
		<category><![CDATA[svn keywords]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=130</guid>
		<description><![CDATA[I know and use Subversion properties (and the keyword substitution) for quite a while now, but never used all of them and mostly stayed with the Id keyword. This results in a substituted string like this: Because my colleague Arno and myself do a lot of server maintenance and configuration, we ended up maintaining a [...]]]></description>
			<content:encoded><![CDATA[<p>I know and use <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.props.html">Subversion properties</a> (and the <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html">keyword substitution</a>) for quite a while now, but never used all of them and mostly stayed with the <code>Id</code> keyword.</p>
<p>This results in a substituted string like this:</p>
<pre class="brush: php; title: ; notranslate">$Id: ProductController.php 227 2010-04-28 08:25:32Z jachim $</pre>
<p>Because <a href="http://noisejunk.eu/">my colleague Arno</a> and myself do a lot of server maintenance and configuration, we ended up maintaining a lot of configuration files in a dedicated repostitory. The big problem here is the fact that you need discipline to check in the changes in Subversion and exporting them into place (<a href="http://svnbook.red-bean.com/en/1.5/svn.ref.svn.c.export.html">manually</a> or with a <a href="http://svnbook.red-bean.com/en/1.5/svn.ref.reposhooks.html">hook</a>).</p>
<p>In order to help us pointing out which files are in the repository and where, we&#8217;ve added 2 keywords in every file:</p>
<pre class="brush: plain; title: ; notranslate">
// $HeadURL$
// $Id$
</pre>
<p>Which gets nicely transformed into usefull information on the servers&#8217; filesystem:</p>
<pre class="brush: plain; title: ; notranslate">
// $HeadURL: http://server/trunk/dnsserver/var/named/chroot/etc/zones/dmz.zones $
// $Id: dmz.zones 1889 2010-05-31 12:26:20Z jachim $
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/06/keeping-track-of-your-config-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom URL&#8217;s in Zend Framework</title>
		<link>http://blog.jachim.be/2010/03/custom-urls-in-zend-framework/</link>
		<comments>http://blog.jachim.be/2010/03/custom-urls-in-zend-framework/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 11:13:24 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[custom routes]]></category>
		<category><![CDATA[route]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=111</guid>
		<description><![CDATA[I am searching for a url solution in Zend Framework for quite a while now, and I hope the solution I came up with helps other people trying to do the same thing. More important, I hope more experienced (Zend Framework) developers can point out problems or suggest better solutions for this problem. The CMS [...]]]></description>
			<content:encoded><![CDATA[<p>I am searching for a url solution in <a href="http://framework.zend.com/">Zend Framework</a> for quite a while now, and I hope the solution I came up with helps other people trying to do the same thing.</p>
<p>More important, I hope more experienced <em>(Zend Framework)</em> developers can point out problems or suggest better solutions for this problem.</p>
<p>The CMS of my company makes it possible for users to create a tree structure of products/sections/chapters/etc&#8230; with an unlimited depth. This makes the url they &#8216;generate&#8217; very variable.</p>
<p>I&#8217;ve searched the internet for solutions and for quite a while I used the solution of <a href="http://my.opera.com/zomg/blog/2007/09/19/extending-zend-framework-route-and-router-for-custom-routing">Jani</a>. Because this completely overrides the Router object, I continued my search via the <a href="http://n4.nabble.com/Generated-urls-to-map-to-controllers-and-actions-td1570272.html">Zend MVC mailing list</a> and had an extensive look at the <a href="http://framework.zend.com/manual/en/zend.controller.router.html">Zend_Controller_Router manual page</a>.</p>
<p>During the search <a href="http://www.jansch.nl/">Ivo Jansch</a> <a href="http://twitter.com/ijansch/status/9642243174">tweeted </a>about ZF URL&#8217;s and <a href="http://twitter.com/ijansch/statuses/9682741688">pointed</a> me towards chaining, but the solution for my specific problem lies in adding <strong>Routes </strong>to the route stack.</p>
<p>I wanted to override the default route so that a language is required in the url. To accomplisch this I added an new function in the Bootstrap.php file:</p>
<pre class="brush: php; title: ; notranslate">
protected function _initLanguageRoute()
{
    $this-&gt;bootstrap('frontController');
    $fc = $this-&gt;frontController;
    $router = $fc-&gt;getRouter();
    $route = new Zend_Controller_Router_Route(
        ':language/:controller/:action/*',
        array(
            'module' =&gt; 'default',
            'language' =&gt; 'nl',
            'controller' =&gt; 'index',
            'action' =&gt; 'index'
        ),
        array(
            'language' =&gt; '[a-z]{2}'
        ),
        $translator
    );
    $router-&gt;addRoute('default', $route);
}
</pre>
<p>To add a variable route (calculated by the CMS), I extended the Zend_Controller_Router_Route_Abstract class so the route could also be used by the Url <a href="http://framework.zend.com/manual/en/zend.view.helpers.html">View helper</a>.</p>
<p>The database I use below, has calculated colums already, but a custom mapping can be calculated in the class as well. As long as the request object is pointed to some controller and action.</p>
<pre class="brush: php; title: ; notranslate">
class Coudenysj_Controller_Router_Route_Mapping extends Zend_Controller_Router_Route_Abstract
{

    private $_db;

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

    /**
     * A method to publish the way the route operates.
     *
     * @see Zend/Controller/Router/Rewrite.php:392
     *
     * @return int
     */
    public function getVersion()
    {
        return 1;
    }

    /**
     * The required functions (required by Interface).
     *
     * @param Zend_Config $config The config object with defaults.
     *
     * @return void
     */
    public static function getInstance(Zend_Config $config)
    {
        return;
    }

    /**
     * Matches a user submitted path with a previously defined route.
     * Assigns and returns an array of defaults on a successful match.
     *
     * @param string $path Path used to match against this routing map
     *
     * @return array|false An array of assigned values or a false on a mismatch
     */
    public function match($path)
    {
        $path = trim($path, '/');

        return $this-&gt;_db-&gt;fetchRow(
            'SELECT lang, controller, action, id
            FROM mapping
            WHERE url = ?;',
            array($path)
        );
    }

    /**
     * Assembles a URL path defined by this route
     *
     * @param array   $data    An array of variable and value pairs used as parameters
     * @param boolean $reset   Not used (required by interface)
     * @param boolean $encode  Not used (required by interface)
     * @param boolean $partial Not used (required by interface)
     *
     * @return string|false Route path with user submitted parameters
     */
    public function assemble($data = array(), $reset = false, $encode = false, $partial = false)
    {
        if (!isset($data['language'])) {
            if (Zend_Registry::isRegistered('Zend_Locale')) {
                $locale = Zend_Registry::get('Zend_Locale');
                $data['language'] = $locale-&gt;getLanguage();
            } else {
                return false;
            }
        }
        if (   !isset($data['controller'])
            || !isset($data['action'])
            || !isset($data['id'])
        ) {
            return false;
        }

        $result = $this-&gt;_db-&gt;fetchRow(
            'SELECT url
            FROM mapping
            WHERE lang = ? AND controller = ? AND action = ? AND id = ?;',
            array(
                $data['language'],
                $data['controller'],
                $data['action'],
                $data['id'],
            )
        );
        return $result['url'];
    }
}
</pre>
<p>Now I can add a new &#8216;cms&#8217; route to the Router object in the Bootstrap.php file:</p>
<pre class="brush: php; title: ; notranslate">
protected function _initMappingRoute()
{
    $db = new Zend_Db::factory(...);
    $this-&gt;bootstrap('frontController');
    $fc = $this-&gt;frontController;
    $router = $fc-&gt;getRouter();
    $router-&gt;addRoute(
        'cms', new Coudenysj_Controller_Router_Route_Mapping($db)
    );
}
</pre>
<p><em>Remember that the route stack is processed backwards, so the &#8216;cms&#8217; route is the first one to try and route the url.</em></p>
<p>This route can now also be used in the view:</p>
<pre class="brush: php; title: ; notranslate">
echo $this-&gt;url(
    array(
        'id' =&gt; $id,
        'controller' =&gt; $controller,
        'action' =&gt; $action
    ),
    'cms' // the name of our route
);
</pre>
<p>This solution works for me (for now) and suggestions to improve it are very welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/03/custom-urls-in-zend-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>3 years ago in Cambridge</title>
		<link>http://blog.jachim.be/2010/03/3-years-ago-in-cambridge/</link>
		<comments>http://blog.jachim.be/2010/03/3-years-ago-in-cambridge/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 05:47:33 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cambridge]]></category>
		<category><![CDATA[howest]]></category>
		<category><![CDATA[intership]]></category>
		<category><![CDATA[leonardo]]></category>
		<category><![CDATA[mct]]></category>
		<category><![CDATA[pih]]></category>
		<category><![CDATA[s24]]></category>
		<category><![CDATA[studio24]]></category>
		<category><![CDATA[uk]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=102</guid>
		<description><![CDATA[It has been around three years now, since I started my internship at Studio 24. Studio 24 is a Cambrigde (UK) based web agency with over 10 years of expierence, happy to share their knowledge with students willing to learn. In the last year of my training MCT at Howest (University College West Flanders), I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.studio24.net/"><img class="alignright size-full wp-image-104" title="Studio 24 - where the web works" src="http://blog.jachim.be/wp-content/uploads/2010/03/studio24.gif" alt="Studio 24 logo" width="112" height="73" /></a>It has been around three years now, since I started my internship at <a href="http://www.studio24.net/">Studio 24</a>.</p>
<p><strong>Studio 24</strong> is a <a href="http://maps.google.co.uk/?q=Cambridge">Cambrigde (<acronym title="United Kingdom">UK</acronym>)</a> based web agency with over 10 years of expierence, happy to share their knowledge with students willing to learn.</p>
<p>In the last year of my training <a title="PIH on Howest.be" href="http://www.howest.be/Default.aspx?target=pih&amp;lan=nl&amp;item=71">MCT</a> at <a href="http://www.howest.be">Howest <em>(University College West Flanders)</em></a>, I decided to do my internship abroad, so I ended up in the beautiful Cambridge for over 3 months.</p>
<p>With the support of my house mates Leena (<acronym title="Sweden">SE</acronym>), Chris (<acronym title="Australia">AU</acronym>), Matthew (<acronym title="United Kingdom">UK</acronym>) &amp; Alex (<acronym title="United Kingdom">UK</acronym>) and my bosses/colleagues <a href="http://twitter.com/simonrjones">Simon</a>, Jonathan, <a href="http://twitter.com/richbs">Richard</a>, <a href="http://twitter.com/edwardcasbon">Edward</a>, David, <a href="http://twitter.com/etianen">Dave</a> &amp; Gaëlle, I found my way through Cambridge and the professional web world.</p>
<p>A lot of what I learned in those 3 months, I still use and advocate/implement in my current company. Some examples of technologies, procedures, software, etc&#8230; I discoverd or worked with:</p>
<ul>
<li><a href="http://subversion.apache.org/">Subversion</a></li>
<li><a href="http://framework.zend.com/">Zend Framework</a></li>
<li><a href="http://en.wikipedia.org/wiki/Domain_Name_System">DNS</a></li>
<li><a href="http://en.wikipedia.org/wiki/Wiki">Wiki</a></li>
<li><a href="http://basecamphq.com/">Basecamp</a></li>
<li><a href="http://en.wikipedia.org/wiki/Content_management_system">CMS</a></li>
<li><a href="http://www.webstandards.org/">Web standards</a> &amp; <a href="http://www.w3.org/">W3C</a></li>
<li>Correct CSS (and slicing)</li>
<li>Correct HTML</li>
<li><a href="http://en.wikipedia.org/wiki/SOAP">SOAP</a></li>
<li>Dealing with customers</li>
<li>Etc&#8230;</li>
</ul>
<p>Using all these things and the variaty of <a href="http://www.studio24.net/portfolio/index.html">customers </a>Studio 24 has, resulted in an astonishing list of projects I worked on. So much, I only could use a thirth of them in my presentation for the jury back at home.</p>
<p>Here&#8217;s an extraction:</p>
<ul>
<li><a href="http://www.cambridgefilmfestival.org.uk/">Cambridge Film Festival</a></li>
<li><a href="http://www.klicktv.co.uk/">Klick TV</a></li>
<li><a href="http://www.realvnc.com/">RealVNC</a></li>
<li><a href="http://www.zeus.com/">Zeus Technology</a></li>
<li>Smaller projects for the <a href="http://www.cambridge.gov.uk/">Cambridge City Council</a></li>
<li>Etc&#8230;</li>
</ul>
<p>I had a great time, and encourage every student to have a look at the <a href="http://eacea.ec.europa.eu/llp/index_en.php">Lifelon Learning programme</a> of the <a href="http://europa.eu/">EU</a>, which helped me pay for my accommodation.</p>
<p>Looking back, I&#8217;m glad everyone around me &#8216;pushed&#8217; me in the Cambridge adventure and I would do it again, if I had the change!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/03/3-years-ago-in-cambridge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deleting Subversion repository files (for real)</title>
		<link>http://blog.jachim.be/2010/01/deleting-subversion-repository-files-for-real/</link>
		<comments>http://blog.jachim.be/2010/01/deleting-subversion-repository-files-for-real/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 10:39:24 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[deleting files]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[svn-obliterate]]></category>
		<category><![CDATA[svndumpfilter]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=92</guid>
		<description><![CDATA[Keeping files and directories in the repository is one of the key principles of Subversion, so once you&#8217;ve committed something, it&#8217;s there for ever. You can delete files, but they still exist somewhere in the repository, so you can go back in time. But there is always that time where you&#8217;ve (accidentally) committed a password [...]]]></description>
			<content:encoded><![CDATA[<p>Keeping files and directories in the repository is one of the <a href="http://svnbook.red-bean.com/en/1.5/svn.intro.whatis.html#svn.intro.whatis">key principles</a> of <a href="http://subversion.tigris.org/">Subversion</a>, so once you&#8217;ve committed something, it&#8217;s there for ever. You can delete files, but they still exist somewhere in the repository, so you can go back in time.</p>
<p>But there is always that time where you&#8217;ve (accidentally) committed a password file, a directory full of hi-res images, or some other contents you don&#8217;t want other people to see that you want to get rid off. That&#8217;s where the hard part starts&#8230;</p>
<p>After <a href="http://www.google.com/search?q=permanently%20remove%20files%20subversion">searching the internet</a> and checking the <a href="http://subversion.tigris.org/faq.html#removal">Subversion FAQ</a> it looks quite hard, but with some guidance, you&#8217;ll find out it&#8217;s not.</p>
<h3>Finding the problems</h3>
<p>First you have to do a (complete) checkout of the repository you want to clean:</p>
<pre class="brush: bash; title: ; notranslate">svn co http://svn.apache.org/repos/asf/ asf</pre>
<p>Now you can start to locate the problems and delete the files/directories (not <code><a href="http://svnbook.red-bean.com/en/1.5/svn.ref.svn.c.delete.html">svn delete</a></code>!):</p>
<pre class="brush: bash; title: ; notranslate">rm -Rf subversion/trunk/tools/buildbot;
rm -Rf subversion/trunk/README;
rm -Rf subversion/trunk/build;</pre>
<p>When you&#8217;re done delete files and directories, you can generate a list of &#8216;missing&#8217; files.</p>
<p>Checking your files:</p>
<pre class="brush: bash; title: ; notranslate">svn status
!      subversion/trunk/tools/buildbot
!      subversion/trunk/README
!      subversion/trunk/build</pre>
<p>Generating that list (outside the working copy):</p>
<pre class="brush: bash; title: ; notranslate">svn status | sed s/&quot;!      &quot;// &gt; ../filter.txt</pre>
<h3>Fixing the problems</h3>
<p>Now you have a nice list of files to delete (make sure it includes the parent directories, right to the root), you should login on the server hosting the repository.</p>
<p>We first want to make sure there is a backup:</p>
<pre class="brush: bash; title: ; notranslate">svnadmin dump file:///var/svn/asf &gt; ~/backup_svn/asf.dump</pre>
<p>Now we can use that backup file as the input of file for the <code><a href="http://svnbook.red-bean.com/en/1.5/svn.reposadmin.maint.html#svn.reposadmin.maint.tk.svndumpfilter">svndumpfilter</a></code> command. In combination with the filter list we&#8217;ve generated on the client, we can create a filtered dump version:</p>
<pre class="brush: bash; title: ; notranslate">svndumpfilter exclude `cat filter.txt` &lt; ~/backup_svn/asf.dump &gt; asf_filtered.dump</pre>
<p>To load that file back in the repository, we should &#8216;delete&#8217; the original repository. (The httpd commands are just to make sure no one commits while processing the changes).</p>
<pre class="brush: bash; title: ; notranslate">
/etc/init.d/httpd stop;
mv /var/svn/asf ~/backup_svn/asf;
svnadmin create --fs-type fsfs /var/svn/asf;
svnadmin load /var/svn/asf &amp;lt; asf_filtered.dump;
/etc/init.d/httpd start;
</pre>
<p>Please note that directories and command line options can be different, but the outcome should be the same.</p>
<p>Now we have the same repository, without the (accidentally) committed files/directories!</p>
<h3>New problems</h3>
<p>After the filtering, it is possible that complete revisions are empty. It is possible to <a href="http://svnbook.red-bean.com/en/1.5/svn.ref.svndumpfilter.html#svn.ref.svndumpfilter.options">skip empty revisions</a>, but then all revisions are renumbered, and that could be problematic for other software (e.g. <a href="http://trac.edgewall.org/">Trac</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2010/01/deleting-subversion-repository-files-for-real/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hostnames in Logwatch reports</title>
		<link>http://blog.jachim.be/2009/11/hostnames-in-logwatch-reports/</link>
		<comments>http://blog.jachim.be/2009/11/hostnames-in-logwatch-reports/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 09:21:44 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[hostname]]></category>
		<category><![CDATA[logformat]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[logwatch]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[subdomain]]></category>
		<category><![CDATA[virtual hosts]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=80</guid>
		<description><![CDATA[Where I work, we have a lot of servers to maintain, and only 2 server admins (me and my colleague). We use Nagios to keep us informed about the server status and Logwatch to analyze to server logs on a daily basis. We have per server a lot of subdomains/vhosts and these virtual hosts all [...]]]></description>
			<content:encoded><![CDATA[<p>Where I work, we have a lot of servers to maintain, and only 2 <em>server admins</em> (me and <a href="http://noisejunk.eu/">my colleague</a>). We use <a href="http://www.nagios.org/">Nagios </a>to keep us informed about the server status and <a href="http://www.logwatch.org/">Logwatch </a>to analyze to server logs on a daily basis.</p>
<p>We have per server a lot of <a href="http://en.wikipedia.org/wiki/Subdomain">subdomains</a>/<a href="http://en.wikipedia.org/wiki/Virtual_hosting">vhosts</a> and these virtual hosts all write into their own log <em>(blog.jachim.be_acces_log, www.jachim.be_error_log, etc&#8230;)</em>.</p>
<p>The log entries look like this:</p>
<pre class="brush: bash; title: ; notranslate">192.168.200.6 - - [10/Nov/2009:09:55:41 +0100] &quot;GET /a/i/red_cube.png HTTP/1.0&quot; 200 190
192.168.200.6 - - [10/Nov/2009:09:55:41 +0100] &quot;GET /a/i/search/search_icon.gif HTTP/1.0&quot; 200 428
192.168.200.6 - - [10/Nov/2009:09:55:41 +0100] &quot;GET /index.php HTTP/1.0&quot; 200 6541</pre>
<p>When Logwatch merges all the httpd log files, the host information (in the log filename) is lost, resulting in Logwatch reports like this:</p>
<pre class="brush: bash; title: ; notranslate">Requests with error response codes
    401 Unauthorized
       /: 4 Time(s)
       /a/i/blue_cube.png: 1 Time(s)
       /favicon.ico: 2 Time(s)
       /wp/login: 2 Time(s)
...</pre>
<p>We actually want reports like this:</p>
<pre class="brush: bash; title: ; notranslate">Requests with error response codes
    401 Unauthorized
       www.jachim.be/: 4 Time(s)
       jachim.be/a/i/blue_cube.png: 1 Time(s)
       blog.jachim.be/favicon.ico: 2 Time(s)
       blog.jachim.be/wp/login: 2 Time(s)
...</pre>
<p>Now we have all the information we want and are able to fix the possible problems much easier.</p>
<p>Because this is not possible in Logwatch (<a href="http://list.logwatch.org/pipermail/logwatch/2003-April/000350.html">see mailinglist</a>), I&#8217;ve added it in the Apache logs.</p>
<p>I&#8217;ve added a new logformat named <code>logwatch</code> in <code>httpd.conf</code>:</p>
<pre class="brush: bash; title: ; notranslate">LogFormat &quot;%h %l %u %t \&quot;%m %{Host}i%U%q %H\&quot; %&gt;s %b&quot; logwatch</pre>
<p>Now the new format is available and can be used in the Virtual Host:</p>
<pre class="brush: bash; title: ; notranslate">CustomLog logs/www.jachim.be-access_log logwatch</pre>
<p><strong>Resources:</strong></p>
<ul>
<li><a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html">Apache mod_log_config</a></li>
<li><a href="http://list.logwatch.org/pipermail/logwatch/">Logwatch Mailing List</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2009/11/hostnames-in-logwatch-reports/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Random PHP function explained</title>
		<link>http://blog.jachim.be/2009/10/random-php-function-explained/</link>
		<comments>http://blog.jachim.be/2009/10/random-php-function-explained/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 08:19:54 +0000</pubDate>
		<dc:creator>coudenysj</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[explained]]></category>
		<category><![CDATA[explore]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[harudoc]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[manual]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[wikipedia]]></category>

		<guid isPermaLink="false">http://blog.jachim.be/?p=72</guid>
		<description><![CDATA[A few weeks ago, Jamie Bicknell notified me he read my article about the Random PHP function. Because I didn&#8217;t publish any code, he wrote a 3 line implementation of how he would fetch the functions for the randomness. I promised him I would publish the code that weekend, and here we are, a few [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-73" title="file1_Open_Source_PHP_logo_667" src="http://blog.jachim.be/wp-content/uploads/2009/10/file1_Open_Source_PHP_logo_667.jpg" alt="file1_Open_Source_PHP_logo_667" width="150" height="150" />A few weeks ago, <a href="http://www.jamiebicknell.com/">Jamie Bicknell</a> <a href="http://twitter.com/jamiebicknell/status/4914210884">notified</a> me he read <a href="/2009/08/random-php-function/">my article</a> about the <strong>Random PHP function</strong>. Because I didn&#8217;t publish any code, he wrote a 3 line implementation of how he would fetch the functions for  the randomness.</p>
<p>I <a href="http://twitter.com/coudenysj/status/4914321604">promised</a> him I would publish the code that weekend, and here we are, a few weeks later&#8230;</p>
<p>The script actually parses the <a href="http://php.net/quickref.php">http://php.net/quickref.php</a> page, saves the result, and redirects the user.</p>
<p><code><span style="color: #000000"><span style="color: #0000BB">$cacheFile&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'./functions.tmp'</span><span style="color: #007700">;<br />if&nbsp;(!</span><span style="color: #0000BB">is_file</span><span style="color: #007700">(</span><span style="color: #0000BB">$cacheFile</span><span style="color: #007700">))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$quickref&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'http://php.net/quickref.php'</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$xml&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">DOMDocument</span><span style="color: #007700">::</span><span style="color: #0000BB">loadHTMLFile</span><span style="color: #007700">(</span><span style="color: #0000BB">$quickref</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$links&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$xml</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getElementsByTagName</span><span style="color: #007700">(</span><span style="color: #DD0000">'a'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$functions&nbsp;</span><span style="color: #007700">=&nbsp;array();<br />&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(</span><span style="color: #0000BB">$links&nbsp;</span><span style="color: #007700">as&nbsp;</span><span style="color: #0000BB">$link</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #0000BB">$link</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getAttribute</span><span style="color: #007700">(</span><span style="color: #DD0000">'href'</span><span style="color: #007700">),&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">8</span><span style="color: #007700">)&nbsp;==&nbsp;</span><span style="color: #DD0000">'/manual/'</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$functions</span><span style="color: #007700">[</span><span style="color: #0000BB">$link</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">nodeValue</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #0000BB">$link</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getAttribute</span><span style="color: #007700">(</span><span style="color: #DD0000">'href'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">file_put_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$cacheFile</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">serialize</span><span style="color: #007700">(</span><span style="color: #0000BB">$functions</span><span style="color: #007700">));<br />}&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$functions&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">unserialize</span><span style="color: #007700">(</span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$cacheFile</span><span style="color: #007700">));<br />}<br /></span><span style="color: #0000BB">$function&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$functions</span><span style="color: #007700">[</span><span style="color: #0000BB">array_rand</span><span style="color: #007700">(</span><span style="color: #0000BB">$functions</span><span style="color: #007700">)];<br /></span><span style="color: #0000BB">$function&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'http://php.net'&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #0000BB">$function</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'Location:&nbsp;'&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #0000BB">$function</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">303</span><span style="color: #007700">);<br />die();</span></span></code></p>
<p>Some improvements:</p>
<ul>
<li>Invalidate the cache file when a <a href="http://www.php.net/releases/index.php?serialize=1&amp;max=1">new PHP version</a> is announced.</li>
<li>Read random lines from the file <em>(instead of loading the complete array in the memory)</em>.</li>
</ul>
<p><ins datetime="2009-10-28T11:51:11+00:00">Update:</ins> Forgot the mention the <a href="http://www.jamiebicknell.com/blog/16-Oct-09/Redirect-to-a-Random-PHP-Function">actual blogpost</a> of Jamie Bicknell&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jachim.be/2009/10/random-php-function-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

