<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Jurgens du Toit</title>
 <link href="http://jrgns.net/sitemap.xml" rel="self"/>
 <link href="http://jrgns.net/"/>
 <updated>2017-02-02T05:34:34+00:00</updated>
 <id>http://jrgns.net/</id>
 <author>
   <name>Jurgens du Toit</name>
   <email>jrgns@jrgns.net</email>
 </author>

 
 <entry>
   <title></title>
   <link href="http://jrgns.net/2017/02/02/2011-10-14-backend-core-a-restful-mvc-php-framework.html"/>
   <updated>2017-02-02T05:34:34+00:00</updated>
   <id>http://jrgns.net/2017/02/02/2011-10-14-backend-core-a-restful-mvc-php-framework</id>
   <content type="html">&lt;p&gt;I like frameworks. I like working with them, I like writing them. I wrote &lt;a href=&quot;http://backend-php.net&quot;&gt;Backend-PHP&lt;/a&gt;, which I’m using personally and at &lt;a href=&quot;http://www.brandedinternet.co.za&quot;&gt;Branded Internet&lt;/a&gt;. Unfortunately it has a number of major flaws: It’s not easily unit testable, not really a REST web service, and it doesn’t conform to any popular coding standards. So I wrote &lt;a href=&quot;https://github.com/jrgns/backend-core&quot;&gt;Backend-Core&lt;/a&gt; as the first step towards addressing these issues.&lt;!--break--&gt;&lt;/p&gt;

&lt;h2 id=&quot;minimal&quot;&gt;Minimal&lt;/h2&gt;

&lt;p&gt;Backend-Core is only intended as a minimal, core system. It doesn’t implement any application logic or data source abstraction. I decided to focus on the core functionality and design of a RESTful MVC system, and make sure that it works as it should. Eventually I’ll extend it with a seperate code base that will include application and data source logic.&lt;/p&gt;

&lt;h2 id=&quot;mvc&quot;&gt;MVC&lt;/h2&gt;

&lt;p&gt;The system is structured into Model, View and Controller components:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Model - The model contains all the &lt;strong&gt;business&lt;/strong&gt; logic for an application. As this is a core system, the models are empty.&lt;/li&gt;
  &lt;li&gt;View - The view determines how the results of a query will be displayed.&lt;/li&gt;
  &lt;li&gt;Controller - The controller contains the &lt;strong&gt;application&lt;/strong&gt; logic. Once again, this is only the core, not an application, so the controller just calls the model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found that a number of MVC systems confuse what should go into the Model and what should go into the Controller. I’m aiming for thin Controllers containing application logic, and thick Models containing the business logic.&lt;/p&gt;

&lt;h2 id=&quot;unit-testing&quot;&gt;Unit Testing&lt;/h2&gt;

&lt;p&gt;Backend-PHP used static global classes quite liberally, without even a thought around dependency injection. This makes unit testing unreliable and a real headache to add to the framework.&lt;/p&gt;

&lt;p&gt;Backend-Core, on the other hand, was designed to use &lt;a href=&quot;http://martinfowler.com/articles/injection.html#ConstructorVersusSetterInjection&quot;&gt;constructor injection&lt;/a&gt; across the board, and includes a number of unit tests, supported by PHPUnit. This should increase the overall stability of the system.&lt;/p&gt;

&lt;h2 id=&quot;restful-service&quot;&gt;RESTful Service&lt;/h2&gt;

&lt;p&gt;Something I didn’t understand about REST when I initial wrote Backend-PHP, was that every REST URL should refer to a noun, with &lt;a href=&quot;http://stackoverflow.com/questions/2001773/understanding-rest-verbs-error-codes-and-authentication/2022938#2022938&quot;&gt;the only verbs being GET, POST, PUT and DELETE&lt;/a&gt;, as specified by the HTTP request. This resulted in it &lt;em&gt;not&lt;/em&gt; complying with REST standards, as a lot of the URLs contained extra verbs, or didn’t refer to nouns directly.&lt;/p&gt;

&lt;p&gt;Backend-Core supports the REST / HTTP verbs directly, and uses the same methods as CakePHP to identify which verb to use:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;_method&lt;/code&gt; POST variable&lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;X_HTTP_METHOD_OVERRIDE&lt;/code&gt; header sent with the request&lt;/li&gt;
  &lt;li&gt;The HTTP request’s method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables it to be used from a Web browser as well as from a REST compliant client.&lt;/p&gt;

&lt;h2 id=&quot;documentation-and-coding-standards&quot;&gt;Documentation and Coding Standards&lt;/h2&gt;

&lt;p&gt;The code complies with the &lt;a href=&quot;http://framework.zend.com/manual/en/coding-standard.html&quot;&gt;ZEND coding standard&lt;/a&gt;, as enforced by &lt;a href=&quot;http://pear.php.net/package/PHP_CodeSniffer/redirected&quot;&gt;PHP Code Sniffer&lt;/a&gt;. It’s documented using the &lt;a href=&quot;http://www.phpdoc.org/&quot;&gt;PHPdoc standard&lt;/a&gt;. Hopefully this will make it easier for people to contribute to and extend the system.&lt;/p&gt;

&lt;p&gt;Feel free to fork, comment and use this.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Logstash Config Guide</title>
   <link href="http://jrgns.net/blog/2015/01/12/logstash-config-guide.html"/>
   <updated>2015-01-12T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2015/01/12/logstash-config-guide</id>
   <content type="html">&lt;p&gt;The ELK stack has been becoming more and more popular, specifically &lt;a href=&quot;http://www.elasticsearch.org/&quot;&gt;Elasticsearch&lt;/a&gt;. The &lt;a href=&quot;http://www.google.com/trends/explore#q=elasticsearch&quot;&gt;search volume&lt;/a&gt; for it has been growing constantly since 2010. It’s faithful sidekick, &lt;a href=&quot;http://logstash.net/&quot;&gt;Logstash&lt;/a&gt;, has been growing along with it, and ever since I’ve started looking at it, I’m just loving it more and more.&lt;/p&gt;

&lt;p&gt;The fact that you can string together totally disparate systems, from XMPP to Redmine and files on S3 to Nagios, with a simple config makes it a wonderful plaything and very useful utility. The rub, though, is in the config: Even though a great effort is made to write proper docs, I’ve found the documentation to be unclear, incomplete and sometimes confusing. So I’ve decided to do something about it:&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;Pain Free Logstash Configuration&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
&lt;a href=&quot;https://leanpub.com/logstashconfigguide&quot;&gt;
&lt;img src=&quot;https://s3.amazonaws.com/titlepages.leanpub.com/logstashconfigguide/medium?1421001125&quot; /&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
Buy it now on &lt;a href=&quot;https://leanpub.com/logstashconfigguide&quot;&gt;Leanpub&lt;/a&gt;
&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;The plan is to write focused guides on some of the more popular Logstash plugins in the hopes of making it easier for people to set up and configure them. Each chapter will point out the bare minimum required to get you up and running and also highlight some of the more interesting, but not necessarily necessary settings for a plugin. You’ll also find a complete reference of all the available settings, with working examples for each of them.&lt;/p&gt;

&lt;p&gt;It’s still early days, but I’ll be publishing a number of preliminary posts on [EagerELK][5] to get things going. Subscribe there, or just buy the book on &lt;a href=&quot;https://leanpub.com/logstashconfigguide&quot;&gt;Leanpub&lt;/a&gt;, to stay up to date.&lt;/p&gt;

&lt;p&gt;The book will be focusing on version 1.4.2 of Logstash (since 1.5 is still in beta), but I’ll update it once 1.5 is stable and being adopted. If you sign up for the 1.4.2 version, you’ll receive a free upgrade to the 1.5 version. Two books for the price of one!&lt;/p&gt;

&lt;p&gt;Any questions or comments are welcome, let me know below!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Populate a Symfony 2 Form with the referring entity</title>
   <link href="http://jrgns.net/blog/2014/02/03/populate-form-with-referring-entity-symfony.html"/>
   <updated>2014-02-03T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2014/02/03/populate-form-with-referring-entity-symfony</id>
   <content type="html">&lt;p&gt;In any web project it often happens that you have an entity, say a Group, to which you want to add a linked entity, say a Student. So you’ll have a “Add a Student” link on the page displaying the Group. When your users click through, there’s probably a dropdown with the different groups, and your users expect the Group they’re coming from to be prepopulated.&lt;/p&gt;

&lt;p&gt;There’s various ways to do this, but I’d like to show you a simple, non intrusive one for Symfony 2. You don’t have to add any parameters to the link, it just works. In your &lt;code class=&quot;highlighter-rouge&quot;&gt;Student&lt;/code&gt; Controller, the &lt;code class=&quot;highlighter-rouge&quot;&gt;newAction&lt;/code&gt; method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// src/My/Bundle/Controller/StudentController.php
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Student&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$form&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StudentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Get the refering URL Path
&lt;/span&gt;        &lt;span class=&quot;nv&quot;&gt;$ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str_replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app_dev.php/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parse_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'referer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PHP_URL_PATH&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Get the matching route
&lt;/span&gt;        &lt;span class=&quot;nv&quot;&gt;$route&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'router'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'_route'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'_route'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'group_show'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Find the referring group
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doctrine'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'MyBundle:Group'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findOneById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'id'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'group'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'MyBundle:Student:new.html.twig'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'entity'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'form'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We basically try and match the referring URL to a route, and if found, retrieve that entity, and set it in the form. Simple!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>MS-SQL Stored Procedures in Sequel: Getting the value of output variables</title>
   <link href="http://jrgns.net/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel.html"/>
   <updated>2014-01-03T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel</id>
   <content type="html">&lt;p&gt;We had the opportunity to muck around with a couple of technologies at &lt;a href=&quot;http://www.tutuka.com&quot;&gt;Tutuka&lt;/a&gt; the last few weeks. I managed to do
some work with Ruby, specifically &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;Sinatra&lt;/a&gt; and &lt;a href=&quot;http://sequel.jeremyevans.net/&quot;&gt;Sequel&lt;/a&gt;. We use MS-SQL extensively and eventually we ran into an issue where
we couldn’t get the values of output variables from stored procedures. After extensive googling we found out that it’s
not supported. There were a couple of clues on how it might be done (particularly this &lt;a href=&quot;https://github.com/rails-sqlserver/tiny_tds/issues/24&quot;&gt;TinyTDS Issue&lt;/a&gt;), so after chatting
with Jeremy (the maintainer of Sequel) I decided to try and the necessary support.&lt;/p&gt;

&lt;h1 id=&quot;it-worked&quot;&gt;It Worked!&lt;/h1&gt;

&lt;p&gt;I was relatively surprised on how easy it was. As of yesterday (2014-01-02) it’s now part of the Sequel version 4.6&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Add Database#call_mssql_sproc on MSSQL for calling stored procedures and handling output parameters (jrgns, jeremyevans) (#748)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h1 id=&quot;how-to-use-it&quot;&gt;How to use it&lt;/h1&gt;

&lt;p&gt;You can get a good idea on how to use it from the &lt;a href=&quot;https://github.com/jeremyevans/sequel/blob/master/doc/mssql_stored_procedures.rdoc&quot;&gt;documentation&lt;/a&gt;, but here’s a summary.&lt;/p&gt;

&lt;p&gt;Let’s say your stored procedure is defined as follows:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CREATE PROCEDURE dbo.SequelTest(
  @Input varchar(25),
  @Output int OUTPUT
)
AS
  SET @Output = LEN(@Input)
  RETURN 0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you don’t care about the type or the name of the output variable, execution is as simple specifying that an argument
is an output parameter by passing the &lt;code class=&quot;highlighter-rouge&quot;&gt;:output&lt;/code&gt; symbol as the argument value.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;gt; ['Input String', :output]})

&amp;gt; {:result =&amp;gt; 0, :numrows =&amp;gt; 1, :var1 =&amp;gt; &quot;1&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;numrows&lt;/code&gt; element will contain the result code returned by the stored proc and the number of rows affected
respectively.&lt;/p&gt;

&lt;p&gt;If you need to specify the type of the output variable, do so by specifying the second element of the array:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;gt; ['Input String', [:output, 'int']]})

&amp;gt; {:result =&amp;gt; 0, :numrows =&amp;gt; 1, :var1 =&amp;gt; 1}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you need to specify the name of the output variable, do so by specifying the third element of the array:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;gt; ['Input String', [:output, nil, 'output']]})

&amp;gt; {:result =&amp;gt; 0, :numrows =&amp;gt; 1, :output =&amp;gt; &quot;1&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>PHP: The slums of the Programming World?</title>
   <link href="http://jrgns.net/blog/2013/10/10/is-php-the-slums-of-the-programming-world.html"/>
   <updated>2013-10-10T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/10/10/is-php-the-slums-of-the-programming-world</id>
   <content type="html">&lt;p&gt;I presented this at &lt;a href=&quot;http://www.tech4africa.com&quot;&gt;Tech4Africa 2013&lt;/a&gt;. The slides can be found &lt;a href=&quot;http://jrgns.net/talks/phpslums&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;quick-history-of-php&quot;&gt;Quick History of PHP&lt;/h1&gt;

&lt;p&gt;PHP was initially created by Rasmus Lerdorf when he got irritated by repetitive coding of CGI calls. He consolidated a number of
functions into a C library and created a parser which would call these functions out of HTML. And so PHP was born! Versions
2 and 3 were formalizations and extensions of the libraries, still using Rasmus’ parser.&lt;/p&gt;

&lt;p&gt;The Zend Engine replaced Rasmus’ parser for version 4, introducing OOP capabilities, and in Version 5 Zend Engine 2 was
introduced. Recent versions of PHP saw even more improvements, most notable namespaces in 5.3 and a built in web server
and traits in 5.4&lt;/p&gt;

&lt;p&gt;There’s no ideology or design philosophy, except that it should be a &lt;a href=&quot;http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html&quot;&gt;simple tool to solve problems&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“I’ve never thought of PHP as more than a simple tool to solve problems”&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://twitter.com/rasmus/status/1938080214814720&quot;&gt;Rasmus Lerdorf 2010&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;lies-damned-lies-and-&quot;&gt;Lies, Damned Lies and …&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/img/tiobe-language-trends.png&quot; alt=&quot;TIOBE Language trends&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Despite a worsening reputation, the language hasn’t decreased in popularity.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/web-language-trends.png&quot; alt=&quot;Web Language Trends&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Less searches are being done for PHP.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/framework-trends.png&quot; alt=&quot;Framework Trends&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you look at the JavaScript vs JQuery trends, JavaScript is also decreasing, but JQuery is increasing. It seems like
the programming community is realising that frameworks are a good idea.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/php-framework-trends.png&quot; alt=&quot;PHP Framework Trends&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So if you look at PHP frameworks, searches on them are also increasing, especially after 2013 when Zend 2 and Symfony 2
were released.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/php-usage.png&quot; alt=&quot;PHP Usage&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No shortage of hosts offering PHP.&lt;/p&gt;

&lt;h1 id=&quot;who-uses-it&quot;&gt;Who uses it?&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;User facing portion of Facebook through HipHop PHP (which generates C++)&lt;/li&gt;
  &lt;li&gt;Wordpress - Application turned framework&lt;/li&gt;
  &lt;li&gt;Yahoo (for now). They are replacing it with Node.&lt;/li&gt;
  &lt;li&gt;Wikipedia / Mediawiki&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;embrace-the-cactus&quot;&gt;Embrace the Cactus&lt;/h1&gt;

&lt;p&gt;It’s easy to create insecure / buggy code in PHP:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    mysql_query(&quot;SELECT * FROM `users` WHERE `username` = $_GET['username']&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;PHP accounts for only 18% of applications covered by the &lt;abbr class=&quot;Common Vulnerabilities and Exposures&quot;&gt;&lt;a href=&quot;http://www.coelho.net/php_cve.html&quot;&gt;CVE&lt;/a&gt;&lt;/abbr&gt;, but accounts for almost 29% of the  vulnerabilities&lt;/p&gt;

&lt;p&gt;It’s developed a bad reputation in the programming community:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Bringing a knife to a gun fight is like bringing PHP to a modern web stack.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://twitter.com/iamdevloper/status/380285502580338688&quot;&gt;@iamdevloper&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Settings such as &lt;code class=&quot;highlighter-rouge&quot;&gt;register_globals&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;magic_quotes&lt;/code&gt; that defaulted to &lt;code class=&quot;highlighter-rouge&quot;&gt;on&lt;/code&gt; opened up a lot of security holes&lt;/p&gt;

&lt;p&gt;No unified community. In general, the community is great. In the rare cases where the PHP documentation (or even the language) is insufficient,
you can usually find something of value in the comments. Yet, there is a lot of conflict in both the official (like PHP internals) and
the unofficial (like &lt;a href=&quot;http://www.php-fig.org/&quot;&gt;PHP-FIG&lt;/a&gt;) communities.&lt;/p&gt;

&lt;p&gt;If you look at the debate on what to use for indentation, &lt;a href=&quot;http://philsturgeon.co.uk/blog/2013/04/psr2-the-tough-decision&quot;&gt;tabs&lt;/a&gt; vs &lt;a href=&quot;https://github.com/php-fig/fig-standards/pull/35&quot;&gt;spaces&lt;/a&gt;, the community is in total disarray.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/tabs-not-spaces.png&quot; alt=&quot;Tabs Not Spaces Slugfest&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Inconsistencies in naming functions:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;strrev     // String Function
str_repeat // String Function
explode    // String Function
// At least somewhat consistent
strpos($haystack, $needle)
array_key_exists($needle, $haystack)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Object Oriented, or just Object Capable? - &lt;a href=&quot;http://michaelkimsal.com/blog/php-is-not-object-oriented/&quot;&gt;Michael Kimsal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you can do Object Oriented Programming as well as Procedural and Functional Programming in PHP (especially PHP 5.3 and later).&lt;/p&gt;

&lt;h1 id=&quot;see-you-on-the-flip-side&quot;&gt;See you on the flip side…&lt;/h1&gt;

&lt;h2 id=&quot;php-53&quot;&gt;PHP 5.3&lt;/h2&gt;

&lt;p&gt;PHP 5.3 is for me a watershed version on PHP’s history - It introduced a number of features / capabilities that made it possible
for some of the other factors I’ll mention to come into existence. The most notable feature is namespaces, making it easier
to name classes in a sane way. A lot of people welcomed the introduction of lambda functions and closures.&lt;/p&gt;

&lt;p&gt;I think the PHP developers and community realized that PHP was becoming outdated and had a lot of valid issues that needed
to be addressed. For me 5.3 was a definite step in the right direction. It introduced (amongst other things):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Namespaces&lt;/li&gt;
  &lt;li&gt;Closures and Lambda functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;php-fig&quot;&gt;PHP-FIG&lt;/h2&gt;

&lt;p&gt;Although it seems to generate a lot of conflict, the PHP-FIG has managed to at least get the different frameworks talking.
It’s an unofficial (as in not sponsored by PHP) group formed by various frameworks and projects whose aim it is to get
the projects talking and to find ways to work together. It’s not always plain sailing, but it seems to get to valuable
decisions. Eventually.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md&quot;&gt;PSR-0&lt;/a&gt; has enabled the creation of packaging software such as composer / packagist&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md&quot;&gt;PSR-1&lt;/a&gt; and &lt;a href=&quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md&quot;&gt;PSR-2&lt;/a&gt; generated a lot of conflict, but at least all of the participating frameworks partially agreed on coding standards&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md&quot;&gt;PSR-3&lt;/a&gt; and &lt;a href=&quot;https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md&quot;&gt;PSR-4&lt;/a&gt; aren’t momentous decisions, but they at least pave the way forward for increased collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;packagist--composer&quot;&gt;Packagist / Composer&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; is a tool to manage dependencies for a project, and manages and installs dependencies on a per project
basis. Very much on par with node’s npm and ruby’s bundler. &lt;a href=&quot;https://packagist.org/&quot;&gt;Packagist&lt;/a&gt; is a repository for composer packages and
makes it dead simple to find a package / library that will address your specific need. Before this, we had PEAR, but
that was usually a headache to set up and version properly locally, not to mention on a shared host.
Now it’s as simple as doing&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    composer require &lt;span class=&quot;s2&quot;&gt;&quot;vendor/library&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To a certain extent the improvements in PHP 5.3 and some of the work from PHP-FIG made this possible, although composer
could have existed without them.&lt;/p&gt;

&lt;h2 id=&quot;modern-frameworks&quot;&gt;Modern Frameworks&lt;/h2&gt;

&lt;p&gt;The combination of PHP 5.3 (specifically namespaces and proper OO support), the work of the PHP-GIH and the development
of Composer made it possible to not only create frameworks such as Symfony2, Zend2 and Laravel, but also to reuse components
from these frameworks in other projects. Drupal 8 uses a lot of Symfony2’s components. PPI is a framework built using
both Zend2 and Symfony2 components. You can now easily choose and combine libraries without having to manage class names
or dependencies. This has at least two direct advantages for project developers:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Instant access to a whole range of precoded, quality, libraries.&lt;/li&gt;
  &lt;li&gt;No more wasting time on managing dependencies and name clashes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;so-slum-or-diamond-in-the-rough&quot;&gt;So, Slum or Diamond in the Rough?&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;Good systems cater for users’ mistakes, great systems also cater for developers’ mistakes…&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://twitter.com/jrgns/status/365357629469499392&quot;&gt;Jrgns&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My opinion is, there is no right answer. To a certain extent, PHP can be described as a horrible language that makes it
very easy to introduce bugs and security issues. It doesn’t give you guidance on how to do anything, and can’t seem to
decide if it’s procedural or object oriented. In the same breath, it gives you a lot of freedom to code according to your
style, and makes a lot of common coding tasks very easy to do. Successful business have been built and are still running
on PHP.&lt;/p&gt;

&lt;p&gt;If you’ve never coded anything but PHP and have no formal programming education (including good programming books), you’re
probably coding crappy PHP. Probably. I’d suggest you start reading up on good programming practices, start reading code
that’s of a high quality, and start learning other programming languages, especially stricter ones like Java, or start
using frameworks such as Symfony2 and Laravel that at least guides you in the right direction. Speaking multiple natural
languages keeps your brain sharp and young. Coding in &lt;a href=&quot;http://www.sciencemag.org/content/330/6002/332.summary&quot;&gt;multiple languages&lt;/a&gt; makes you a better coder.&lt;/p&gt;

&lt;p&gt;If you know what you’re doing and you perhaps have some extra experience in a more structured language such as Java or Ruby,
you’re probably coding quality PHP. It’s un-opinionated, so, as long as you know what you’re doing, it can be a great tool.
Don’t discount the language just because it’s lost it’s coolness factor. You can write quality code in PHP.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/sheer-iron-willed-discipline.png&quot; alt=&quot;Sheer Iron WIlled Discipline&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you can pull it off, you’re badass as hell, but most of the time you’re only going to end up stabbing yourself.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://twitter.com/ohpalmer/status/380290678502461440&quot;&gt;ohpalmer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</content>
 </entry>
 
 <entry>
   <title>A DIY Dynamic DNS service using Cloudflare</title>
   <link href="http://jrgns.net/blog/2013/09/26/diy-dynamic-dns-using-cloudflare.html"/>
   <updated>2013-09-26T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/09/26/diy-dynamic-dns-using-cloudflare</id>
   <content type="html">&lt;p&gt;DynDNS was always the dynamic IP service of choice, but I could never get it
to work properly, and I was always stuck with their lame domain names as I’m
too cheap to pay for their serivces.&lt;/p&gt;

&lt;p&gt;Luckily services of all kinds, including DNS Providers, have caught on to the
fact that people want API’s. If there’s an API to do DNS updates, I can script
a solution.&lt;/p&gt;

&lt;p&gt;Some of my domains run off of &lt;a href=&quot;https://www.cloudflare.com/&quot;&gt;Cloudflare&lt;/a&gt; which needs to overwrite your DNS.
And, hey presto, they have an &lt;a href=&quot;http://www.cloudflare.com/docs/client-api.html&quot;&gt;API&lt;/a&gt;. So here it is:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
curl https://www.cloudflare.com/api_json.html &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'a=rec_edit'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'tkn=1234512345qweqwe1234512345'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'id=12345'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'email=jrgns@jrgns.net'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'z=jrgns.net'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'type=A'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'name=home'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s2&quot;&gt;&quot;content=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'service_mode=0'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    -d &lt;span class=&quot;s1&quot;&gt;'ttl=3600'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Quick and dirty. This updates a domain (home.jrgns.net) with id 12345 with the
IP address that’s passed as the first argument to the script. There’s a bunch of
ways to get your external IP, my favourite is &lt;code class=&quot;highlighter-rouge&quot;&gt;curl http://api.externalip.net/ip&lt;/code&gt;,
but I just run this script as the &lt;code class=&quot;highlighter-rouge&quot;&gt;postscript&lt;/code&gt; of my ddclient (which updates another
service)&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;# /etc/ddclient.conf

protocol=dyndns2
use=web, web=myip.dnsomatic.com
ssl=yes
server=updates.someservice.com
login=mylogin@gmail.com
password='123456'
daemon=3600
postscript=/home/jrgns/bin/cloudflare_dynamic_dns.sh&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I’m sure the same can be done with outer services such as Route 53? Has anyone
tried something like this?&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Setting a default order for Doctrine 2 / Symfony 2</title>
   <link href="http://jrgns.net/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2.html"/>
   <updated>2013-09-17T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2</id>
   <content type="html">&lt;p&gt;Usually when you’re working with data you expect some kind of default ordering.
It might be the primary key, or, more commonly, the data set will be ordered by
a timestamp field or the data’s most important property. In Doctrine you can create
&lt;a href=&quot;http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes&quot;&gt;custom repository classes&lt;/a&gt; to tweak queries to your liking:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// src/Acme/StoreBundle/Entity/ProductRepository.php
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Acme\StoreBundle\Entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Doctrine\ORM\EntityRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProductRepository&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EntityRepository&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findAllOrderedByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getEntityManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'SELECT p FROM AcmeStoreBundle:Product p ORDER BY p.name ASC'&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is all fine and dandy, but do you really want to repeat yourself everytime
you write a query for a model that will almost &lt;strong&gt;always&lt;/strong&gt; be ordered
by the same field? Or get caught out by calls to default repository methods that
&lt;em&gt;don’t&lt;/em&gt; use the ordering you like? No, you don’t. Enter this piece of code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// src/Acme/StoreBundle/Entity/ProductRepository.php
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Acme\StoreBundle\Entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Doctrine\ORM\EntityRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProductRepository&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EntityRepository&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$criteria&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$orderBy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Default Ordering
&lt;/span&gt;        &lt;span class=&quot;nv&quot;&gt;$orderBy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$orderBy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'added'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'desc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$orderBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Default Filtering
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;array_key_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'active'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$criteria&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$criteria&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'active'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$criteria&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$orderBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.EntityRepository.html#_findBy&quot;&gt;findBy&lt;/a&gt; method of the EntityRepository class is the method used by most
(if not all) of the the repository methods that fetch data. This includes &lt;code class=&quot;highlighter-rouge&quot;&gt;findBy&lt;/code&gt;
methods where you can specify an arbitrary column and value:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// find a group of products based on an arbitrary column value
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$repository&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findByPrice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;19.99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So to ensure a default ordering, we override this method and check if an orderBy
clause has been set. If not, set it to our default ordering — in this case by the
&lt;code class=&quot;highlighter-rouge&quot;&gt;added&lt;/code&gt; field, descending. For good measure we also add default filtering —
the &lt;code class=&quot;highlighter-rouge&quot;&gt;active&lt;/code&gt; field needs to equal 1. Once that’s done, call the parent method
with the default values set.&lt;/p&gt;

&lt;p&gt;Easy as π&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Pre-populating an Entity in a Symfony 2 Form</title>
   <link href="http://jrgns.net/blog/2013/07/22/prepopulating-entity-in-symfony-2-form.html"/>
   <updated>2013-07-22T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/07/22/prepopulating-entity-in-symfony-2-form</id>
   <content type="html">&lt;p&gt;I’ve been working on &lt;a href=&quot;http://www.teach-a-rific.com&quot;&gt;teach-a-rific.com&lt;/a&gt; in my spare time, and I’m learning a lot
about how &lt;a href=&quot;http://symfony.com/doc/current/book/forms.html&quot;&gt;Symfony 2 Forms&lt;/a&gt; work. One thing I need to do a lot, is to show a
form with a &lt;a href=&quot;http://symfony.com/doc/current/reference/forms/types/entity.html&quot;&gt;entity field&lt;/a&gt; pre-populated. In this situation you also don’t want
the user to be able to edit the field. This is how I did it.&lt;/p&gt;

&lt;p&gt;First, you need to retrieve the mapped entity, in this case a &lt;code class=&quot;highlighter-rouge&quot;&gt;Student&lt;/code&gt;, and set it
in the entity which you’re creating a form for. In this case a &lt;code class=&quot;highlighter-rouge&quot;&gt;ContactDetail&lt;/code&gt;.
This all happens in the &lt;code class=&quot;highlighter-rouge&quot;&gt;newAction&lt;/code&gt; method of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ContactDetailController&lt;/code&gt;.
Notice how I save the student ID in a session variable. More on this later.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//ContactDetailController::newAction
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$detail&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ContactDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$studentId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'student_id'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDoctrine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'NotesNoteBundle:Student'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$studentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'session'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'contact_detail:create:student'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$studentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$detail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setStudent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ContactDetailType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$detail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;On to the form. Quite simply, if the entity already has a &lt;code class=&quot;highlighter-rouge&quot;&gt;Student&lt;/code&gt;, don’t add the
field for the student.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Form\AbstractType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Form\FormBuilderInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\OptionsResolver\OptionsResolverInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContactDetailType&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AbstractType&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buildForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;FormBuilderInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getStudent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'student'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$builder&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'type'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'choice'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'choices'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Email'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Email'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Cellphone'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Cellphone'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'content'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;On to the actual form. If the student field is defined in the form, display the
form widget. Otherwise display the student in an uneditable text input. Displaying
the student can be skipped if it’s not necessary.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;{% if form.student is defined %}
    {{ form_row(form.student, { form_type: 'horizontal' }) }}
{% elseif form.vars.data.student.id is defined %}
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;control-group&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;control-label&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Student&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;controls&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;input uneditable-input&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;{{ form.vars.data.student }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endif %}&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And on to the &lt;code class=&quot;highlighter-rouge&quot;&gt;updateAction&lt;/code&gt;. Just get the &lt;code class=&quot;highlighter-rouge&quot;&gt;Student&lt;/code&gt; whose ID we stored in the session,
and set it on the &lt;code class=&quot;highlighter-rouge&quot;&gt;ContactDetail&lt;/code&gt; before populating the form:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//ContactDetailController::createAction
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ContactDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$studentId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'session'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'contact_detail:create:student'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDoctrine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'NotesNoteBundle:Student'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$studentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setStudent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$student&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Simple enough. Any suggestions on how to improve it, or comments on how to do it
differently?&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>A Summary of Symfony 2 Authorization</title>
   <link href="http://jrgns.net/blog/2013/04/29/summary-of-symfony-2-authorization.html"/>
   <updated>2013-04-29T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/04/29/summary-of-symfony-2-authorization</id>
   <content type="html">&lt;p&gt;Symfony 2 comes with a great &lt;a href=&quot;http://symfony.com/doc/current/book/security.html&quot;&gt;security component&lt;/a&gt; that provides both &lt;a href=&quot;http://symfony.com/doc/current/components/security/authentication.html&quot;&gt;Authentication&lt;/a&gt;
(identifying the user) and &lt;a href=&quot;http://symfony.com/doc/current/components/security/authorization.html&quot;&gt;Authorization&lt;/a&gt; (determining the permissions for the user)
functionality. It has sane defaults, works out of the box, and is extendable enough
to cater for any scenario. This post describe the default authorization functionality
available to the developer.&lt;/p&gt;

&lt;p&gt;Out of the box, Symfony 2 offers two method with which to authorize a user:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Role based authorization&lt;/li&gt;
  &lt;li&gt;Access control lists (ACL’s)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;role-based-authorization&quot;&gt;Role Based Authorization&lt;/h2&gt;

&lt;p&gt;With role based authorization, you specify a number of roles (which can be hierarchical)
and specify the access of these roles, all within your application config:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#project/app/config/security.yml
security:
    role_hierarchy:
        ROLE_ANONYMOUS:
        ROLE_USER:        ROLE_ANONYMOUS
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_USER }
        - { path: ^/admin/, role: ROLE_ADMIN }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In the config above, there’s roles (or types of users). Anonymous, normal users, admin
users and super admin users. Anonymous users can only access the public part of the site.
Logged in users can access the whole site, except for the admin area. Admin users can access
the admin area of the site. Relatively simple and easy to set up, but not very customizable
on a fine grained level.&lt;/p&gt;

&lt;h2 id=&quot;access-control-lists&quot;&gt;Access Control Lists&lt;/h2&gt;

&lt;p&gt;Say for instance that users generate content, and that users can only access the content
they generated. The role based rules are too general for this, so we’ll turn to Access Control
Lists for a solution.&lt;/p&gt;

&lt;p&gt;The concept of ACL’s boils down to a list of many to many relations between users
and resources defining who has access to what. Even though Symfony provides built
in &lt;a href=&quot;http://symfony.com/doc/current/cookbook/security/acl.html&quot;&gt;ACL functionality&lt;/a&gt;, this can become hairy quite quickly, as you need to manage
Access Control Entries (ACE) in your controller code.&lt;/p&gt;

&lt;p&gt;Although Symfony provides an &lt;a href=&quot;http://api.symfony.com/2.0/Symfony/Component/Security/Acl/Dbal/AclProvider.html&quot;&gt;ACL Provider&lt;/a&gt; with which the coder can create and
check ACL’s, it can become hairy quite quickly, as it needs to be managed in each and
every Controller Action.&lt;/p&gt;

&lt;p&gt;This boilerplate code wil appear in controller actions that deal with creating Entities
and their ACL’s:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Security\Acl\Domain\ObjectIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Security\Acl\Domain\UserSecurityIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Security\Acl\Permission\MaskBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Inside a controller action
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// creating the ACL
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aclProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'security.acl.provider'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$objectIdentity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ObjectIdentity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromDomainObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$acl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aclProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createAcl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$objectIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// retrieving the security identity of the currently logged-in user
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$securityContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'security.context'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$securityContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$securityIdentity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UserSecurityIdentity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromAccount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// grant owner access
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$acl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;insertObjectAce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$securityIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MaskBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MASK_OWNER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$aclProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;updateAcl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$acl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The “creating the ACL” block retrieves the Security Provider, generates an identity
for the object using the &lt;code class=&quot;highlighter-rouge&quot;&gt;ObjectIdentity&lt;/code&gt; class, and then creates the ACL using the
security provider.&lt;/p&gt;

&lt;p&gt;The second block retrieves the Security Context and the current user. From there it
generates the an identifier for the user using the &lt;code class=&quot;highlighter-rouge&quot;&gt;UserSecurityIdentity&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;The third block then inserts an Access Control Entry and updates the ACL.&lt;/p&gt;

&lt;p&gt;That’s a lot of code. If there’s a generic way to handle this, please let me know
in the comments.&lt;/p&gt;

&lt;h2 id=&quot;behind-the-scenes&quot;&gt;Behind the Scenes&lt;/h2&gt;

&lt;p&gt;The key component in how Symfony manages authentication is the &lt;a href=&quot;http://api.symfony.com/2.2/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.html&quot;&gt;AccessDecisionManager&lt;/a&gt;.
Each time a request is made, the &lt;code class=&quot;highlighter-rouge&quot;&gt;AccessDecisionManager&lt;/code&gt; lets registered Voters vote on
if the user may access the resource. The voters will determine their vote by inspecting
the current security token, a set of attributes, and an optional object. Access will
then be granted (or denied) depending on the votes and the &lt;code class=&quot;highlighter-rouge&quot;&gt;AccessDecisionManager's&lt;/code&gt;
decision strategy. Both the role based auth and ACL’s use this mechanism.&lt;/p&gt;

&lt;p&gt;I’ll go into how to use the &lt;code class=&quot;highlighter-rouge&quot;&gt;AccessDecisionManager&lt;/code&gt; and Voters in a later post.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>I'm the most Organized Disorganized person you'll meet</title>
   <link href="http://jrgns.net/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet.html"/>
   <updated>2013-02-28T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet</id>
   <content type="html">&lt;p&gt;One of the most telling compliments I ever received was from a good friend: “You’re
the most organized, disorganized person I know!”. It’s quite telling once you wrap your
head around it. It stuck by me, and it’s helping me shape my career.&lt;/p&gt;

&lt;p&gt;I’ve always been absent minded. Classic “if you’re head wasn’t tied to your body, you’ll
loose it!” stuff. I’d put something down, and then search for it for half an hour, only
to discover it’s been in my pocket the whole time. One time I was talking to my mom on
the phone, realised that I didn’t know where my phone was, and proceed to tell my mom
about it… At the end of the day, details just didn’t stick in my head.&lt;/p&gt;

&lt;p&gt;Now I’m in an industry where detail is everything. Businesses lose thousands
because of a missing negative sign. One line of code out of place crashes an application
and loses a company users, money and its reputation. I always tell people that creating
systems is like eating an elephant: bit by bit. what they don’t realise is that if you
get one byte wrong, everything comes crashing down.&lt;/p&gt;

&lt;p&gt;So how wise is it for a guy who can’t keep track of both his sandles to be in the details
business? Either very foolish, or a stroke of genius. Genius? Let’s look that compliment
again: The most &lt;em&gt;organized&lt;/em&gt; disorganized person. To cope with all these details, I
started to rely on systems. I organized my life in such a way that I didn’t need to
worry about the details.&lt;/p&gt;

&lt;p&gt;Using systems ensures that even the most unorganized person won’t miss any of the details.
I used calandering to keep track of appointments. A todo list for tasks. Evernote for
easy to forget yet important info. When I go out the door I chant “Phone, keys, wallet”
to ensure that I have the essentials. Every day I’m hacking my brain.&lt;/p&gt;

&lt;p&gt;The take away is that while people make mistakes, systems rarely do. Don’t rely
on people to take care of the details, rather put systems in place to take care it. If
it’s tricky or complicated to deploy an app, script it. If a process is long and protracted,
automate it. Create unit and behaviour tests for your code. Add state checks to the
application. Run regular audits on the numbers and make sure they balance.&lt;/p&gt;

&lt;p&gt;In the age of rapid development and continuous deployment, just writing your app isn’t
enough anymore. You need to write systems around your app to ensure that it is coded
correctly, deployed correctly, working correctly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP's array_merge_recursive function explained</title>
   <link href="http://jrgns.net/blog/2013/01/08/php-array-merge-recursive-function-explained.html"/>
   <updated>2013-01-08T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2013/01/08/php-array-merge-recursive-function-explained</id>
   <content type="html">&lt;p&gt;Reading the PHP docs, it’s not immediately clear how the &lt;a href=&quot;http://php.net/manual/en/function.array-merge-recursive.php&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge_recursive&lt;/code&gt;&lt;/a&gt; function behaves.
I’ve setup a couple of test cases and compared them with the plain &lt;a href=&quot;http://php.net/manual/en/function.array-merge.php&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge&lt;/code&gt;&lt;/a&gt; function to explain it further:&lt;/p&gt;

&lt;p&gt;The following snippet set’s up a couple of arrays, and outputs them for completeness sake.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$cats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'white'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Kitty'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'brown'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Bach'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'mixed'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Tomcat'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$dogs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'white'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Bowser'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'brown'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Rex'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'mixed'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Mutt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;var_dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Cats'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Dogs'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$dogs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;pre&gt;&lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Cats'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
&lt;b&gt;array&lt;/b&gt;
  'white' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; 
    &lt;b&gt;array&lt;/b&gt;
      0 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Kitty'&lt;/font&gt; &lt;i&gt;(length=5)&lt;/i&gt;
  'brown' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Bach'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
  'mixed' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; 
    &lt;b&gt;array&lt;/b&gt;
      0 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Tomcat'&lt;/font&gt; &lt;i&gt;(length=6)&lt;/i&gt;
&lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Dogs'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
&lt;b&gt;array&lt;/b&gt;
  'white' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Bowser'&lt;/font&gt; &lt;i&gt;(length=6)&lt;/i&gt;
  'brown' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Rex'&lt;/font&gt; &lt;i&gt;(length=3)&lt;/i&gt;
  'mixed' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Mutt'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
&lt;/pre&gt;

&lt;p&gt;This snippet highlights what happens when the arrays being merged have matching keys.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;var_dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Cats and Dogs - plain'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$dogs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;var_dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Cats and Dogs - recursive'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_merge_recursive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$dogs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;All values that’s not already in an array will be placed in an array,
and merged with other values with the same keys. Arrays are left as they are and then merged.&lt;/p&gt;

&lt;pre&gt;
&lt;b&gt;array&lt;/b&gt;
  'white' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; 
    &lt;b&gt;array&lt;/b&gt;
      0 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Kitty'&lt;/font&gt; &lt;i&gt;(length=5)&lt;/i&gt;
      1 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Bowser'&lt;/font&gt; &lt;i&gt;(length=6)&lt;/i&gt;
  'brown' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; 
    &lt;b&gt;array&lt;/b&gt;
      0 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Bach'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
      1 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Rex'&lt;/font&gt; &lt;i&gt;(length=3)&lt;/i&gt;
  'mixed' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; 
    &lt;b&gt;array&lt;/b&gt;
      0 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Tomcat'&lt;/font&gt; &lt;i&gt;(length=6)&lt;/i&gt;
      1 &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Mutt'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
&lt;/pre&gt;

&lt;p&gt;Compare this with the normal &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge&lt;/code&gt; function, where the values of the latter arrays replace
all the values with the same key.&lt;/p&gt;

&lt;pre&gt;
&lt;b&gt;array&lt;/b&gt;
  'white' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Bowser'&lt;/font&gt; &lt;i&gt;(length=6)&lt;/i&gt;
  'brown' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Rex'&lt;/font&gt; &lt;i&gt;(length=3)&lt;/i&gt;
  'mixed' &lt;font color=&quot;#888a85&quot;&gt;=&amp;gt;&lt;/font&gt; &lt;small&gt;string&lt;/small&gt; &lt;font color=&quot;#cc0000&quot;&gt;'Mutt'&lt;/font&gt; &lt;i&gt;(length=4)&lt;/i&gt;
&lt;/pre&gt;

&lt;p&gt;Values with numerical keys get added to the original array with a renumbering of keys. This
is the same behaviour as that of &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge&lt;/code&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Setting up the Swiftmailer Spooler</title>
   <link href="http://jrgns.net/blog/2012/12/20/setting-up-the-swiftmailer-spooler.html"/>
   <updated>2012-12-20T00:00:00+00:00</updated>
   <id>http://jrgns.net/blog/2012/12/20/setting-up-the-swiftmailer-spooler</id>
   <content type="html">&lt;p&gt;The &lt;a href=&quot;http://swiftmailer.org/&quot;&gt;Swiftmailer&lt;/a&gt; library comes with a nifty feature where mails can be spooled to disk
and sent later asynchronously instead of mailing them immediately. This results in quicker
response times from your scripts, and by extension happier users. This post will explain
how to set it up &lt;em&gt;outside&lt;/em&gt; of the Symfony 2 framework.&lt;/p&gt;

&lt;h2 id=&quot;spooling-the-mail&quot;&gt;Spooling the Mail&lt;/h2&gt;

&lt;p&gt;Swiftmailer defines a number of Transports with which mails can be sent. A common one
is the &lt;code class=&quot;highlighter-rouge&quot;&gt;Swift_SmtpTransport&lt;/code&gt;. To spool mails, we’ll use the &lt;code class=&quot;highlighter-rouge&quot;&gt;Swift_SpoolTransport&lt;/code&gt; for
the initial sending, and then still use &lt;code class=&quot;highlighter-rouge&quot;&gt;Swift_SmtpTransport&lt;/code&gt; for the background sending.
The following comes (with some changes) from a post in the &lt;a href=&quot;https://groups.google.com/forum/?fromgroups=#!searchin/swiftmailer/spool/swiftmailer/xQPP5qtNnMA/k3QXcRebG-wJ&quot;&gt;Swiftmailer Google Group&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Setup the spooler, passing it the name of the folder to spool to
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_FileSpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__DIR__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/spool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Setup the transport and mailer
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$transport&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_SpoolTransport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$mailer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_Mailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$transport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a message
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_Message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Excellent Subject'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'sende...@domain.com'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'John Doe'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'your_emailAddress@domain.com'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setBody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'spool messages !!!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

 &lt;span class=&quot;c1&quot;&gt;// Send the message
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$mailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SPOOLED &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; emails&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will spool the email to specified folder instead of sending it. At this stage,
the actual sending of the mail hasn’t happened yet. You will need to flush the spooled
messages using a cron or background script that calls the flashQueue method to do that.&lt;/p&gt;

&lt;h2 id=&quot;sending-the-mail&quot;&gt;Sending the Mail&lt;/h2&gt;

&lt;p&gt;The background script will use the &lt;code class=&quot;highlighter-rouge&quot;&gt;Swift_SmtpTransport&lt;/code&gt; to send the spooled mails:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//create an instance of the spool object pointing to the right position in the filesystem
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_FileSpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__DIR__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/spool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//create a new instance of Swift_SpoolTransport that accept an argument as Swift_FileSpool
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$transport&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_SpoolTransport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//now create an instance of the transport you usually use with swiftmailer
//to send real-time email
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$realTransport&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Swift_SmtpTransport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;smtp.gmail.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;465&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;ssl&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setPassword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$transport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setMessageLimit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTimeLimit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$sent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$spool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flushQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$realTransport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SENT &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; emails&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And that’s it. All that’s left now is to call the background script periodically using
something like cron.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Building PHP Projects with Jenkins</title>
   <link href="http://jrgns.net/building-php-projects-with-jenkins/index.html"/>
   <updated>2012-06-09T18:46:23+00:00</updated>
   <id>http://jrgns.net/building-php-projects-with-jenkins/building-php-projects-with-jenkins</id>
   <content type="html">&lt;p&gt;It can become quite difficult to keep PHP code structured and clean. There’s a couple of good tools out there (&lt;a href=&quot;http://pear.php.net/package/PHP_CodeSniffer/redirected&quot;&gt;PHP Code Sniffer&lt;/a&gt;, &lt;a href=&quot;http://phpmd.org/&quot;&gt;PHP Mess Detector&lt;/a&gt;, etc) to help you manage it, but it adds a lot of overhead that can bring your productivity down. One way to keep the advantage of checking your code without taking a productivity hit, is using a build system like Jenkins.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;Look at &lt;a href=&quot;http://erichogue.ca/2011/05/php/continuous-integration-in-php/&quot;&gt;this blog post&lt;/a&gt; to setup Jenkins and the various tools. There’s also a &lt;a href=&quot;http://jenkins-php.org/&quot;&gt;Jenkins PHP Template&lt;/a&gt; that will help a great deal in getting things started.&lt;/p&gt;

&lt;p&gt;I’m planning to play around with it, and post updates here about how it goes.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Decorator Pattern Implemented Properly In PHP</title>
   <link href="http://jrgns.net/decorator-pattern-implemented-properly-in-php/index.html"/>
   <updated>2012-03-17T11:14:56+00:00</updated>
   <id>http://jrgns.net/decorator-pattern-implemented-properly-in-php/decorator-pattern-implemented-properly-in-php</id>
   <content type="html">&lt;p&gt;While working on &lt;a href=&quot;http://backend-php.net&quot;&gt;Backend-PHP&lt;/a&gt; I needed to do a proper implementation of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Decorator_pattern&quot;&gt;Decorator Pattern&lt;/a&gt; in PHP. Just googling PHP decorator pattern will come up with a number of simple solutions, but none of them are usable in a general, robust way that a framework requires. So I extended and tweaked the implementations a bit.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;##TL;DR&lt;/p&gt;

&lt;p&gt;Most decorator pattern implementations for PHP found on the web is broken. They need some extra functionality to work properly, especially for nested decorators. See the complete solution in the &lt;a href=&quot;https://github.com/backend/Backend-PHP-Core/blob/master/Decorators/Decorator.php&quot;&gt;Backend-PHP code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;##The Basics&lt;/p&gt;

&lt;p&gt;I’m assuming you know how decorators work. If not, read up on it first! I’ve implemented a base &lt;code class=&quot;highlighter-rouge&quot;&gt;Decorator&lt;/code&gt; class to handle the base functionality for Decorators. The simple implementations out there serve as a good base for an initial implementation:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Decorator
{
    protected $object; //The object to decorate

    function __construct( $object)
    {
        $this-&amp;gt;object = $object;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is enough to get you started, but you will need to wrap the original object’s properties and methods manually. Let’s define a couple of magic functions to do that automatically:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public function __call($method, $args)
    {
        if (is_callable($this-&amp;gt;object, $method) {
            return call_user_func_array(array($this-&amp;gt;object, $method), $args);
        }
        throw new Exception(
            'Undefined method - ' . get_class($this-&amp;gt;object) . '::' . $method
        );
    }

    public function __get($property)
    {
        if (property_exists($this-&amp;gt;object, $property)) {
            return $this-&amp;gt;object-&amp;gt;$property;
        }
        return null;
    }

    public function __set($property, $value)
    {
        $this-&amp;gt;object-&amp;gt;$property = $value;
        return $this;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;That should give you a working basic implementation.&lt;/p&gt;

&lt;p&gt;##More Advanced&lt;/p&gt;

&lt;p&gt;That will work as long as you don’t nest decorators, ie, decorate an already decorated object:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$object = new DecoratorOne(new DecoratorTwo(new SomeClass()));
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Why? The magic functions will check the decorated object for the properties and methods, but in the case of &lt;code class=&quot;highlighter-rouge&quot;&gt;DecoratorOne&lt;/code&gt; above, the decorated object will be another decorator, and you won’t get the expected behaviour. This happens because &lt;code class=&quot;highlighter-rouge&quot;&gt;property_exists&lt;/code&gt; doesn’t trigger the &lt;code class=&quot;highlighter-rouge&quot;&gt;__get&lt;/code&gt; (or &lt;code class=&quot;highlighter-rouge&quot;&gt;__set&lt;/code&gt;) methods. &lt;code class=&quot;highlighter-rouge&quot;&gt;is_callable&lt;/code&gt; does check for the &lt;code class=&quot;highlighter-rouge&quot;&gt;__call&lt;/code&gt; function, but that doesn’t necessarily produce the expected results, especially if you stack decorators that modify method execution.&lt;/p&gt;

&lt;p&gt;We solve this by adding two more functions:&lt;/p&gt;

&lt;p&gt;###getOriginalObject&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public function getOriginalObject()
{
    $object = $this-&amp;gt;object;
    while ($object instanceof Decorator) {
        $object = $object-&amp;gt;getOriginalObject();
    }
    return $object;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;getOriginalObject&lt;/code&gt; will return the original, undecorated object. This is handy to get the correct class name or access to undecorated methods and properties:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo get_class($decoratedClass) //Will give the name of the Decorator

echo get_class($decoratedClass-&amp;gt;getOriginalObject()) //Will give the name of the original object
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;###isCallable&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public function isCallable($method, $checkSelf = false)
{
    //Check the original object
    $object = $this-&amp;gt;getOriginalObject();
    if (is_callable(array($object, $method))) {
        return $object;
    }
    //Check Decorators
    $object = $checkSelf ? $this : $this-&amp;gt;object;
    while ($object instanceof Decorator) {
        if (is_callable(array($object, $method))) {
            return $object;
        }
        $object = $this-&amp;gt;object;
    }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;isCallable&lt;/code&gt; will check the original object for the specified method, and if not found, it will check the other decorators for the method. The option exists to check itself as well.&lt;/p&gt;

&lt;p&gt;##The Result&lt;/p&gt;

&lt;p&gt;Now we can modify the magic functions like so:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public function __call($method, $args)
{
    if ($object = $this-&amp;gt;isCallable($method)) {
        return call_user_func_array(array($object, $method), $args);
    }
    throw new Exception(
        'Undefined method - ' . get_class($this-&amp;gt;getOriginalObject()) . '::' . $method
    );
}

public function __get($property)
{
    $object = $this-&amp;gt;getOriginalObject();
    if (property_exists($object, $property)) {
        return $object-&amp;gt;$property;
    }
    return null;
}

public function __set($property, $value)
{
    $object = $this-&amp;gt;getOriginalObject();
    $object-&amp;gt;$property = $value;
    return $this;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will give you a robust Decorator Pattern implementation from which you can then create more Decorators. See the complete implementation in the &lt;a href=&quot;https://github.com/backend/Backend-PHP-Core/blob/master/Decorators/Decorator.php&quot;&gt;Backend-PHP code&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Low Hanging Fruit Of Testing</title>
   <link href="http://jrgns.net/the-low-hanging-fruit-of-testing/index.html"/>
   <updated>2012-03-16T15:14:03+00:00</updated>
   <id>http://jrgns.net/the-low-hanging-fruit-of-testing/the-low-hanging-fruit-of-testing</id>
   <content type="html">&lt;p&gt;I’ve been getting more into Testing (specifically Unit Testing) the past few weeks, and although I’m still struggling to firstly get it right, and secondly see the long term benefits, I know that the quality of my code is already better. Let’s call it the low hanging fruit of Testing.&lt;/p&gt;

&lt;p&gt;I find that I’m reordering and sometimes rewriting functions, and sometimes whole classes, because just the need to test it already shows some design flaws. A class with too many private methods, a function with no clear input / output, all of that shows up when you start to write tests.&lt;/p&gt;

&lt;p&gt;The fact that I have to think of my code and classes in terms of an API requires that I make sure of what the purpose of a function is, and what it’s signature and return should look like. Because it’s difficult to test large, complex functions, I’m refactoring those into smaller, more modular functions.&lt;/p&gt;

&lt;p&gt;So I’m spending more time with the code, making improvements as I read and think about the code. So yeah, I’m not utilizing the full power of testing yet (not to speak of Test Driven Development), but I’m already enjoying the fruits.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>json-encode'ing Private and Protected Properties</title>
   <link href="http://jrgns.net/json-encode-ing-private-and-protected-properties/index.html"/>
   <updated>2012-02-24T06:51:15+00:00</updated>
   <id>http://jrgns.net/json-encode-ing-private-and-protected-properties/json-encode-ing-private-and-protected-properties</id>
   <content type="html">&lt;p&gt;When you &lt;code class=&quot;highlighter-rouge&quot;&gt;json_encode&lt;/code&gt; an object, it will ignore all protected and private properties if the &lt;code class=&quot;highlighter-rouge&quot;&gt;json_encode&lt;/code&gt; isn’t called from within the object. Sometimes you want to output the protected and private properties of an object when you’re JSON encoding it. Here’s how to do it in an easy and elegant way:&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;##The Problem&lt;/p&gt;

&lt;p&gt;The properties of an object &lt;code class=&quot;highlighter-rouge&quot;&gt;json_encode&lt;/code&gt; includes in it’s eventual output depends on the scope of the function call: If it’s from inside the object, it will include &lt;strong&gt;all&lt;/strong&gt; the properties, private and protected. If it’s from outside of the object, it will only include the public properties.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tester&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$public&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Public'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$protected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Protected'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$private&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Private'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Tester&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Outputs {&quot;public&quot;:&quot;Public&quot;,&quot;protected&quot;:&quot;Protected&quot;,&quot;private&quot;:&quot;Private&quot;}
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Outputs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;public&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Public&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This isn’t necessarily the desired outcome. Sometimes you want more control over what is being included in the encoding function.&lt;/p&gt;

&lt;p&gt;##The Solution&lt;/p&gt;

&lt;p&gt;The easiest way to solve this is to add a &lt;code class=&quot;highlighter-rouge&quot;&gt;_toJson&lt;/code&gt; function to your object, and call that instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;json_encode&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_toJson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$properties&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StdClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;_class&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;get_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$properties&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;getProperties&lt;/code&gt; function should return the properties you want to include in the encoding. At it’s simplest it can be&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getProperties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;get_object_vars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then, to call it, just check if the function exists, otherwise just call json_encode:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;method_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_toJson'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;_toJson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s relatively simple to do it as a Decorator as well, which will enable you to give this functionality to multiple classes without the need to duplicate the code. See how I did it in the &lt;a href=&quot;https://github.com/backend/Backend-PHP&quot;&gt;Backend-PHP&lt;/a&gt; framework.&lt;/p&gt;

&lt;p&gt;Do you have a better way to do it? Say so in the comments.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>22seven.com - Folly, or Genius?</title>
   <link href="http://jrgns.net/22seven-com-folly-or-genius/index.html"/>
   <updated>2012-01-28T08:37:06+00:00</updated>
   <id>http://jrgns.net/22seven-com-folly-or-genius/22seven-com-folly-or-genius</id>
   <content type="html">&lt;p&gt;##Promising Product&lt;/p&gt;

&lt;p&gt;Last week Christo Davel, founder of the now defunct &lt;a href=&quot;http://mg.co.za/article/2005-11-02-online-bank-20twenty-up-for-sale&quot;&gt;twenty20&lt;/a&gt; bank, released an online personal accounting service called &lt;strong&gt;&lt;a href=&quot;http://22seven.com&quot;&gt;22seven.com&lt;/a&gt;&lt;/strong&gt;. It &lt;a href=&quot;http://www.itweb.co.za/index.php?option=com_content&amp;amp;view=article&amp;amp;id=50971:22seven-goes-live&quot;&gt;looked&lt;/a&gt; like a great product. Something I was looking for for quite a while: A simple online interface that automatically imports my transaction details, and reports on how much I’m spending on what.&lt;/p&gt;

&lt;p&gt;I will never use it, though. Why? The app asks for your online banking login details.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;##But…&lt;/p&gt;

&lt;p&gt;In case you don’t know. This is “not a good thing”(tm). As &lt;a href=&quot;https://twitter.com/?tw_e=details&amp;amp;tw_i=162563523292041216&amp;amp;tw_p=tweetembed#!/MichaelJordaan/statuses/162563523292041216&quot;&gt;tweeted&lt;/a&gt; by Micheal Jordaan, CEO of FNB, you’re taking a big risk by doing so. Once you’ve given it to them, it’s out there, somewhere. Yes, they &lt;a href=&quot;https://www.22seven.com/security.html&quot;&gt;secure&lt;/a&gt; the information, but to use it, it needs to become readable at some point. If it can become readable, someone can steal it. From a dishonest employee, to a hacker that found his way on to their servers.&lt;/p&gt;

&lt;p&gt;The question is, why did they decide to go the route of asking for a user’s banking login details? The banks have been struggling to educate users so that they don’t enter the online banking sites from any other place than the bank’s site, and that they &lt;em&gt;don’t&lt;/em&gt; give their login credentials to any third party. As far as I know, the South African banks will refund any money you lost because of online fraud, &lt;strong&gt;except&lt;/strong&gt; if they can prove that you gave your credentials to someone else. And this service is asking for it, wholesale.&lt;/p&gt;

&lt;p&gt;##The Problem&lt;/p&gt;

&lt;p&gt;The problem is that this isn’t the only company that went this route. Sidpayment, a product from Setcom, gives merchants the ability to do online EFTs. The problem is that it’s a Java app that looks over the customer’s shoulder while he’s doing a once off payment through his internet banking. The opportunity for hacks and attacks abound. I’m sure both these knew the risks and were aware of the potential &lt;a href=&quot;http://memeburn.com/2012/01/new-startup-22seven-under-fire-from-banks/&quot;&gt;backlash&lt;/a&gt;, but why did they knowingly proceed with it?&lt;/p&gt;

&lt;p&gt;There’s a simple answer: &lt;strong&gt;They had no choice&lt;/strong&gt;. The banks in South Africa are walled gardens, with all of &lt;strong&gt;your&lt;/strong&gt; information locked up in it. There’s no way to access it, except through their portals: the branch and online banking. Even FNB, who seems to be embracing newer technologies, doesn’t have anything that even looks like an API. All they have is an accounting app that looks like it was written by (no offence) accountants. So how are third party applications supposed to access a client’s transaction details?&lt;/p&gt;

&lt;p&gt;Is there even a need for third parties to access people’s transaction information? Of course there is! In a number of other countries you see &lt;a href=&quot;http://www.wesabe.com&quot;&gt;innovation&lt;/a&gt; in &lt;a href=&quot;http://mint.com&quot;&gt;personal finance&lt;/a&gt; because they have access to information. There’s a number of services that track your credit card and spending patterns. These services depend on (sometimes read-only) data they get from banks and financial institutions.&lt;/p&gt;

&lt;p&gt;##Come on, Banks!&lt;/p&gt;

&lt;p&gt;If we are to see innovation and progress in personal accounting in South Africa, the banks need to lead the way by not walling everything off, but by giving accredited and approved third party developers and companies access to API’s. Perhaps 22seven.com’s play was to force the hand of the big banks, and not as stupid as it seems.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Setting up Puppet on Ubuntu 10.4</title>
   <link href="http://jrgns.net/setting-up-puppet-on-ubuntu-10.4/index.html"/>
   <updated>2011-11-16T04:24:06+00:00</updated>
   <id>http://jrgns.net/setting-up-puppet-on-ubuntu-10.4/setting-up-puppet-on-ubuntu-10.4</id>
   <content type="html">&lt;p&gt;I’m trying to use puppet to setup standard dev and (eventually) production environments. As Ubuntu 10.4 is the current LTS release (at least until 12.4), I need to get puppet running on 10.4. The problem is that although the latest stable release for puppet is 2.7.6, puppet in the ubuntu repo is version 0.25.4. Here’s how to firstly set it up, and then upgrade it to the latest version.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;First install packages required by Puppet via aptitude&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install irb libopenssl-ruby libreadline-ruby rdoc ri ruby ruby-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And then install puppet and puppet master, also through aptitude&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install puppet puppetmaster
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can skip install puppet if your working on the master machine, or skip puppetmaster if your working on a client. &lt;em&gt;I’ll be installing the client and the master on the same machine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can then follow the following steps from &lt;a href=&quot;http://docs.puppetlabs.com/references/0.25.4/configuration.html&quot;&gt;the documentation&lt;/a&gt; to get the default setup going. &lt;em&gt;Run all commands as root&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#Generate a default config file
puppetd --genconfig &amp;gt; etc/puppet/puppet.conf
#Generate a default site manifest
puppetd --genmanifest &amp;gt; etc/puppet/manifests/site.pp
#Add the puppet user and group
puppetd --mkusers
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We also need to tell the client which server it should use as it’s master. Add the following line to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;127.0.0.1 puppet&lt;/p&gt;

&lt;p&gt;Puppet uses the host name &lt;code class=&quot;highlighter-rouge&quot;&gt;puppet&lt;/code&gt; as the default master. You can change this by setting the server config value in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/puppet.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can then test your client setup by running&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;puppetd --test
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;cert-issues&quot;&gt;Cert Issues&lt;/h2&gt;

&lt;p&gt;At this point I ran into a stupid config issue, where the client complained bombed out with the following error:&lt;/p&gt;

&lt;p&gt;could not retrieve catalog from remote server: hostname was not match with the server certificate&lt;/p&gt;

&lt;p&gt;Despite the &lt;a href=&quot;http://projects.puppetlabs.com/issues/7224&quot;&gt;bad english and uninformative message&lt;/a&gt;, I eventually figured out that even though a puppet client by default uses the puppet hostname as its master, the name on the cert that was generated for the hostname isn’t puppet, but the current machine’s name. This mismatch causes the confusion, so either change the server config value, or regen the cert with hostname puppet. I just changed the config value to my machine’s name. This actually negates the need for the added line in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>PHP Community in South Africa, lack thereof</title>
   <link href="http://jrgns.net/php-community-in-south-africa-lack-thereof/index.html"/>
   <updated>2011-10-05T05:07:46+00:00</updated>
   <id>http://jrgns.net/php-community-in-south-africa-lack-thereof/php-community-in-south-africa-lack-thereof</id>
   <content type="html">&lt;p&gt;I really like working with PHP. It’s a great language despite, a number of shortcomings, and I get to make a living out of writing PHP code. I also love to socialize, and the past few weeks I’ve been looking for a way to combine these two.&lt;/p&gt;

&lt;p&gt;I’ve looked for conferences or get togethers that I can attend. I looked for online groups or chatrooms about PHP where South Africans gathered. But I couldn’t find any. Well, any active, constructive ones in any case.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;I see that there’s an active &lt;a href=&quot;http://drupal.co.za&quot;&gt;Drupal&lt;/a&gt; community in and around Jo’burg, so I’ll try to attend some of their meetups.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Why Johnny Died (or, How I Finally Realised Why Singletons And Global Variables Are Bad)</title>
   <link href="http://jrgns.net/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad/index.html"/>
   <updated>2011-09-28T04:06:19+00:00</updated>
   <id>http://jrgns.net/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad</id>
   <content type="html">&lt;p&gt;Johnny (an asthma sufferer and fictitious character) died yesterday. He got an asthma attack, but he could not find his inhaler, and sadly passed away. Usually his mother kept it for him and made sure he used it, but on the first day he ventured out alone, he got an asthma attack, realised that he didn’t have his inhaler with him, and died. What does this have to do with Singletons or Global variables? Read on…&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;I’ve been struggling to get my head around why singletons and global variables are bad. Particularly in the context of unit testing. I’m &lt;a href=&quot;http://stackoverflow.com/questions/228590/what-is-the-best-method-for-getting-a-database-connection-object-into-a-function/228715#228715&quot;&gt;quite a fan&lt;/a&gt;
of a global static class that can manage certain resources for you. But if you just look around a bit, you’ll find a &lt;a href=&quot;http://www.webapper.com/blog/index.php/2008/01/23/evils-of-global-variables-when-unit-testing/&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html&quot;&gt;resources&lt;/a&gt; around the fact that they are a bad idea.&lt;/p&gt;

&lt;p&gt;I read up quite a bit on why exactly globals and singletons are bad, but couldn’t find any convincing explanations. Until yesterday, when I read this &lt;a href=&quot;http://stackoverflow.com/questions/1020312/are-singletons-really-that-bad&quot;&gt;question&lt;/a&gt; and &lt;a href=&quot;http://stackoverflow.com/questions/1020312/are-singletons-really-that-bad/1020384#1020384&quot;&gt;answer&lt;/a&gt; on stackoverflow. Particularly&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;every class can potentially depend on
a singleton, which means the class can
not be reused in other projects unless
we also reuse all our singletons&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, if you want your classes / objects to be modular and easily transportable and reusable in other code bases, you &lt;strong&gt;cannot&lt;/strong&gt; use global variables or singletons. To properly unit test, you need to use your class in a clean environment, with only it’s stated dependencies injected into it on creation. Otherwise there’s no guarantee that your tests will fail or succeed consistently. Doing this also promotes code reuse, as you know that the global state won’t be affected in some averse way.&lt;/p&gt;

&lt;p&gt;What does this have to do with Johnny? Look at him as an object of the class Human, who has a dependency on an Inhaler object. His mother is a global variable or class that supplies him with the Inhaler when he needs it. All fine and dandy if Johnny operates within the context of his mother’s home. Take him out of that context, and he dies when he needs the inhaler. Rather give him the inhaler, and let him keep it in his pocket. Dependency injected!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>A PHP Virtual Host</title>
   <link href="http://jrgns.net/php-virtualhost/index.html"/>
   <updated>2011-09-13T03:18:03+00:00</updated>
   <id>http://jrgns.net/php-virtualhost/php-virtualhost</id>
   <content type="html">&lt;p&gt;I hate repetitive work. I love solving a puzzle. So it often happens that I’d spend 2 hours writing a script to solve a repetitive problem, than just taking the 2 minutes to do it manually. Creating apache config files are tedious and boring, so I wrote a PHP script that emulates Virtual Hosting.&lt;/p&gt;

&lt;p&gt;You can get the code on &lt;a href=&quot;https://github.com/jrgns/php-virtualhost&quot;&gt;GitHub&lt;/a&gt;. A &lt;strong&gt;Warning&lt;/strong&gt;: The code is &lt;strong&gt;not&lt;/strong&gt; production ready. Use it at your own risk. Here’s what it does:&lt;/p&gt;

&lt;p&gt;An &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file &lt;a href=&quot;?q=content/redirect_request_to_index&quot;&gt;redirects all requests&lt;/a&gt; to the &lt;code class=&quot;highlighter-rouge&quot;&gt;index.php&lt;/code&gt; file, which sits in &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www&lt;/code&gt;. We get the host from the &lt;code class=&quot;highlighter-rouge&quot;&gt;$_SERVER&lt;/code&gt; variable, and check if a folder for that host exists.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'HTTP_HOST'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getcwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;no_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So if we wanted to server jrgns.net from it, the folder &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/jrgns.net&lt;/code&gt; should exist on the server. If it doesn’t, a generic message is displayed.&lt;/p&gt;

&lt;p&gt;Courtesy of the &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file, the whole URL, except the host name, gets passed to the script in the &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; query variable. As we might be requesting a stylesheet such as jrgns.net/styles/basic.css, the virtual host should pick that up. If no file is requested, check for and serve an index file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_REQUEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'f'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;$indexes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
		&lt;span class=&quot;s1&quot;&gt;'index.php'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'index.html'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'index.htm'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'main.php'&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$indexes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nb&quot;&gt;chdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_REQUEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'f'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;explode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'js'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Content-Type: text/javascript'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'css'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Content-Type: text/css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;nb&quot;&gt;readfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I use a very rudimentary way to get the file extension, and then send the content header. There are probably better ways to do this, but it works. The rest is just the generic message that gets displayed if we don’t know what you’re looking for.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;no_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    	&lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    	&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    		&lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Unknown Domain: &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    	&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    		&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    			&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Unknown Domain: &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
    
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;no_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Like I said. Simple!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>A JavaScript trim function</title>
   <link href="http://jrgns.net/js-trim/index.html"/>
   <updated>2011-07-18T04:55:32+00:00</updated>
   <id>http://jrgns.net/js-trim/js-trim</id>
   <content type="html">&lt;p&gt;A simple enough &lt;code class=&quot;highlighter-rouge&quot;&gt;trim&lt;/code&gt; function for JavaScript:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function trim(string) {
    return string.replace(/^\s*|\s*$/g, '')
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;!--break--&gt;

&lt;p&gt;The regular expression translates as&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^&lt;/code&gt; - At the beginning of the line&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;\s*&lt;/code&gt; - Take all the white space you can find, if there is any&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;|&lt;/code&gt; - OR&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;\s*&lt;/code&gt; - Take all the white space you can find, if there is any&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$&lt;/code&gt; - At the end of the line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;g&lt;/code&gt; parameter at the end ensures that all instances are replaced.&lt;/p&gt;

&lt;p&gt;The replace function uses the regular expressions to replace the white space it found at the beginning or the end of the string with an empty string.&lt;/p&gt;

&lt;p&gt;Easy enough!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Quick Guide To Creating A Website Quickly</title>
   <link href="http://jrgns.net/quick_guide_to_creating_a_website_quickly/index.html"/>
   <updated>2011-07-11T21:31:53+00:00</updated>
   <id>http://jrgns.net/quick_guide_to_creating_a_website_quickly/quick_guide_to_creating_a_website_quickly</id>
   <content type="html">&lt;p&gt;The last two weeks I had the privilege of staying in a house on the beach near Mosselbay. This time of the year whales start coming into the bay, and, if you’re lucky, you can spot them breaching or displaying their flukes or fins. This inspired me to create &lt;a href=&quot;http://whalespotter.co.za&quot;&gt;WhaleSpotter&lt;/a&gt;, a site that uses Twitter to help people spot whales along South Africa’s south coast. It took me less than 2 hours to do it. Here’s how.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;###Know &lt;em&gt;exactly&lt;/em&gt; what you want to Do&lt;/p&gt;

&lt;p&gt;This speaks for it self. Spend a few minutes to lay out what you want, and how you want to achieve it. If you need to write it down, explain it to someone or whiteboard it, do it. This will save a lot of time later in the process, as you won’t track back or waste time with features or ideas that doesn’t fit.&lt;/p&gt;

&lt;p&gt;###Keep it Simple&lt;/p&gt;

&lt;p&gt;Keep the number of features down to a minimum. If you can fit everything on one page, do. This is quick and dirty, not long and elaborate. You can expand it later. Your aim now is to get something up and running.&lt;/p&gt;

&lt;p&gt;###Know and use your Tools&lt;/p&gt;

&lt;p&gt;Frameworks cut down a lot in development time. They provide functionality and structure so that you don’t have to work on it. I dev’ed my own MVC framework, &lt;a href=&quot;http://backend-php.net&quot;&gt;Backend&lt;/a&gt;, so I used that. It provides a nice templating system, along with basic configuration, caching and utility functions. Use what ever you’re comfortable with, as long as it reduces the work you have to do, not increase it.&lt;/p&gt;

&lt;p&gt;###Use Resources wisely&lt;/p&gt;

&lt;p&gt;Other resources can also cut down on time taken to get your site up. I used &lt;a href=&quot;http://images.google.com&quot;&gt;Google Images&lt;/a&gt; to get a logo. Look at &lt;a href=&quot;http://themeforest.net/&quot;&gt;Themeforest&lt;/a&gt; for a design that will work for your site. Copy and paste code from your own projects or open source projects on the web. The site was in part inspired by &lt;a href=&quot;http://replaceawordinafamousquotewithduck.com/&quot;&gt;http://replaceawordinafamousquotewithduck.com/&lt;/a&gt;, and I copied some of the twitter parsing code from the &lt;a href=&quot;https://github.com/duckduckgo/replaceawordinafamousquotewithduck&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;###So&lt;/p&gt;

&lt;p&gt;Know where you’re going. Keep it simple. Know your tools and options. Outsource as much as possible.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Good Developers Think like a Startup</title>
   <link href="http://jrgns.net/good_developers_think_like_a_startup/index.html"/>
   <updated>2011-05-05T08:25:54+00:00</updated>
   <id>http://jrgns.net/good_developers_think_like_a_startup/good_developers_think_like_a_startup</id>
   <content type="html">&lt;p&gt;I have the privilege to be the Head of Development of &lt;a href=&quot;http://www.brandedinternet.co.za&quot;&gt;Branded Internet&lt;/a&gt;, a white label ISP in South Africa. I also like to read and think about how startups work, and what they do to make them successful. As I see it, the basic recipe  for a startup is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Find a niche market or problem&lt;/li&gt;
  &lt;li&gt;Find a revolutionary / novel way to solve that problem&lt;/li&gt;
  &lt;li&gt;Build the solution&lt;/li&gt;
  &lt;li&gt;Market it&lt;/li&gt;
  &lt;li&gt;See the money roll in.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you see the company you’re developing for as your client or target market, software development follows basically the same recipe.&lt;!--break--&gt;&lt;/p&gt;

&lt;h3 id=&quot;find-a-problem&quot;&gt;Find a problem&lt;/h3&gt;

&lt;p&gt;Usually people come to the developers of a company with a problem. &lt;em&gt;I need App X to do Y and Z&lt;/em&gt;. &lt;em&gt;App C doesn’t do D correctly&lt;/em&gt;. I’m not very good at spotting problems that are potentially money making, so I’m quite happy to be a developer where people come to me looking for solutions. That’s the first step sorted.&lt;/p&gt;

&lt;h3 id=&quot;find-a-way-to-solve-the-problem&quot;&gt;Find a way to solve the problem&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;http://lorempixum.com/200/300/abstract/&quot; style=&quot;float: right;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Startups depend on the fact that they solve previously unsolved problems, or they solve problems in such a way that people want to throw money their way for the privilege to use the startup’s solution. I suspect that this may just be one of the reasons why developers at bigger companies don’t necessarily produce quality code: There’s no incentive to do it quickly, elegantly or intelligently. Just get it done. If it takes you three times longer than projected with a code base larger than the Kalahari, who cares. It’s done, and you got your salary at the end of the month.&lt;/p&gt;

&lt;p&gt;If a startup thinks like that, it’s dead in the water.&lt;/p&gt;

&lt;p&gt;Solving problems better is always better. Yes, there’s major time and money constraints on most developers, and elegance isn’t always achievable, but good developers should always be open to solve problems in a novel way. Don’t be a mill churning out code, be a creator of great code!&lt;/p&gt;

&lt;h3 id=&quot;build-the-solution&quot;&gt;Build the Solution&lt;/h3&gt;

&lt;p&gt;Do what you do. Be a thinker, then a typist. And do it well.&lt;/p&gt;

&lt;h3 id=&quot;market-it&quot;&gt;Market it&lt;/h3&gt;

&lt;p&gt;Having built the solution is not where it stops. For most developers, it’s where they wished it stopped, because, let’s face it, if we liked speaking to people, we wouldn’t have become developers. But unfortunately you as a developer need to take it further. You need to market what you’ve done. A product that no one knows or knows how to use doesn’t exist.&lt;/p&gt;

&lt;p&gt;You need to tell your superior and your peers about the fact that the project is up and running.
You need to document the code and the use cases so that other developers (including your future self) knows what’s going on.
You need to train your clients (the users) who originally requested your help on using the project.
You need to get feedback from your clients on if this solves their problem, and go back to the code if it doesn’t.&lt;/p&gt;

&lt;h3 id=&quot;reap-the-rewards&quot;&gt;Reap the Rewards&lt;/h3&gt;

&lt;p&gt;I find it immensely rewarding to be able to solve problems for people. Yes, the salary is great, but there’s times that I will literally code for free. Not just because I like solving problems, but because I know that I can make someone’s work day less frustrating. You get the gold and the golden glow.&lt;/p&gt;

&lt;h3 id=&quot;tldr&quot;&gt;tl;dr&lt;/h3&gt;

&lt;p&gt;By thinking or your rote work in terms of a startup, where you need to be agile and more than just a normal developer, going out of your comfort zone and speaking to people, your average work can become great work, and your worth will be measured in more than just a salary check.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Why Object Orientation is Great</title>
   <link href="http://jrgns.net/why_oo_is_great/index.html"/>
   <updated>2011-02-08T07:00:21+00:00</updated>
   <id>http://jrgns.net/why_oo_is_great/why_oo_is_great</id>
   <content type="html">&lt;p&gt;I’m working on some statistics surrounding &lt;a href=&quot;http://www.brandedinternet.co.za&quot;&gt;BI’s&lt;/a&gt; API Documentation coverage: Just how much user documentation have we written?&lt;/p&gt;

&lt;p&gt;When I started out, the number was abysmally low: 11% of the 1300 functions. Not good. But I didn’t feel too bad when I realized that because it’s written as an Object Orientated system, I can very quickly improve the coverage.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;As I went through the undocumented functions, it became clear that a lot of them are defined in some of our base classes. So, by documenting them in the base classes, I will immediately improve the documentation coverage for a whole bunch of classes. I tried it with one function, and lo and behold, the percentage jumped with 6 points!&lt;/p&gt;

&lt;p&gt;So, what do we learn from this? Object orientation is powerful when you implement changes deep down in the object stack, as it propagates through the whole stack. It also reduces the work load (most of the time) as there’s no need to repeat yourself.&lt;/p&gt;

&lt;p&gt;The downside to consider is that the documentation written is very general (as it should be in a base class), and will probably be overwritten in some of the sub classes.&lt;/p&gt;

&lt;p&gt;But that’s Object Orientation: Solve 80% of the problem with 20% of the code, and the other 20% of the problem with the other 80% of the code!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Getting Started with node.js</title>
   <link href="http://jrgns.net/getting_started_with_node_js/index.html"/>
   <updated>2010-10-11T06:31:40+00:00</updated>
   <id>http://jrgns.net/getting_started_with_node_js/getting_started_with_node_js</id>
   <content type="html">&lt;p&gt;Looking for a new challenge, I started a small project in node.js. Here’s a few simple tips on how to get going quickly.&lt;!--break--&gt;&lt;/p&gt;

&lt;h2 id=&quot;its-javascipt&quot;&gt;It’s JavaScipt&lt;/h2&gt;

&lt;p&gt;Yeah, that’s obvious, but sometimes stating the obvious is necessary. Node.js is essentially server side JavaScript. This means that all your JS knowledge and tutorials and manuals will be usefull once you get stuck.&lt;/p&gt;

&lt;h2 id=&quot;its-event-driven&quot;&gt;It’s Event Driven&lt;/h2&gt;

&lt;p&gt;Node.js is an event driven framework, which can take some getting used to, but it is very powerful in the long run. You can write straight forward bottom to top code, but then you’ll be missing out on the real power of node.js. An example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//Get the events module
var   events = require('events')
    , fs     = require('fs');

//Create a new event object
var file_emitter = new events.EventEmitter();

//Create a listener for our event object
var newFileListener = file_emitter.on('found', function(file) {
    //Do something to the found file
}

//Check for files in a folder
var files = fs.readdirSync('/some/folder');
files.forEach(function(file) {
	//Emit (Trigger) the &quot;found&quot; event on our event object
	file_emitter.emit('found', dest);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;multiple-files&quot;&gt;Multiple Files&lt;/h2&gt;

&lt;p&gt;Any good coder knows that putting your code in multiple files is a quick win for organized coded. Here’s how to do it in node.js:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//In utils.js
exports.trim = trim;
function trim(string) {
	return string.replace(/^\s*|\s*$/g, '')
}

//In the file you want to use the trim function
var utils = require('./utils')
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;.js&lt;/code&gt; part of the file is automatically added/detected. This is to include a file in the same folder as the calling file, but you can easily just add the correct path traversals to get to other files. The important part in the file being included is setting the function name in the &lt;code class=&quot;highlighter-rouge&quot;&gt;exports&lt;/code&gt; Object.&lt;/p&gt;

&lt;h2 id=&quot;file-io&quot;&gt;File I/O&lt;/h2&gt;

&lt;p&gt;Files are all treated as streams in node.js. This means that you can start acting on the data in a file before node has even finished reading the file.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//Open a file as a Readable stream
stream = fs.ReadStream(file);
stream.setEncoding('ascii');
stream.on('data', function(data) {
    //Do something to the file's data mid stream
});
stream.on('close', function () {
    //Do something to the file once it's finished reading
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Writing to a file is just as simple&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;stream = fs.createWriteStream(filename, { 'encoding': 'base64' });
stream.write(data);
stream.end();
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;want-more&quot;&gt;Want More?&lt;/h2&gt;

&lt;p&gt;See &lt;a href=&quot;http://github.com/jrgns/parser_email&quot;&gt;parser_email on github&lt;/a&gt; for the full source of the examples given.&lt;/p&gt;

&lt;p&gt;Some useful sites:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;a href=&quot;http://nodejs.org/&quot;&gt;Official Site&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&quot;http://nodejs.org/api.html&quot;&gt;Documentation&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&quot;http://github.com/ry/node&quot;&gt;Source&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb&quot;&gt;Understanding node.js&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://howtonode.org/&quot;&gt;How to Node&lt;/a&gt;&lt;/p&gt;

  &lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Email Parser for node.js</title>
   <link href="http://jrgns.net/node_parser_email/index.html"/>
   <updated>2010-10-07T09:53:55+00:00</updated>
   <id>http://jrgns.net/node_parser_email/node_parser_email</id>
   <content type="html">&lt;p&gt;I need to parse Emails in node.js and after looking around on the web, I didn’t find much. Oh, no, I’ll have to write it myself… :)&lt;/p&gt;

&lt;p&gt;The source is hosted on &lt;a href=&quot;http://github.com/jrgns/parser_email&quot;&gt;GitHub&lt;/a&gt; .&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var   fs        = require('fs')
    , sys       = require('sys')
    , em_parse  = require('./parser_email')

stream = fs.ReadStream(file);
stream.setEncoding('ascii');
stream.on('data', function(data) {
	mail += data;
});
stream.on('close', function () {
	parser = em_parse.parser_email();
	parser.setContent(mail);
	parser.parseMail();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Why I Code</title>
   <link href="http://jrgns.net/why_i_code/index.html"/>
   <updated>2010-04-15T08:56:23+00:00</updated>
   <id>http://jrgns.net/why_i_code/why_i_code</id>
   <content type="html">&lt;p&gt;A a student I went to a career psychologist to explore my career needs and drives, and got told that I like solving problems in a creative way. As the son of an engineer and a very artsy mother, that kind of made sense. Seeing as I was already into computers and programming, I chose coding as my problem solving mechanism.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;Through the years I learned that I loved, never mind liked, solving problems this way. I wrote a &lt;a href=&quot;http://backend-php.net&quot;&gt;framework&lt;/a&gt;, because I saw a lot of unstructured and repetitive code in my projects. I dev’ed &lt;a href=&quot;http://whatsupinmelville.co.za&quot;&gt;What’s up in Melville&lt;/a&gt; because I needed information about the area I lived in. I saw &lt;a href=&quot;http://news.ycombinator.com&quot;&gt;Hacker News&lt;/a&gt;, and wanted the same site, but for South Africa, so I dev’ed &lt;a href=&quot;http://zacoders.net&quot;&gt;ZA Coders&lt;/a&gt;. All (hopefully) creative solutions to problems I faced.&lt;/p&gt;

&lt;p&gt;I am now Head of Development at &lt;a href=&quot;http://www.brandedinternet.co.za&quot;&gt;Branded Internet&lt;/a&gt;, and I’m still very passionate about solving problems through code. Any dev department at a company whose main aim is not to produce software, is to help the rest of the company to solve their problems through code. Finances needs to regularly generate a certain report, Dev scripts the code, and gives them the link. Support needs to information on an account, Dev scripts the code, and gives them the link.&lt;/p&gt;

&lt;p&gt;Sometimes Dev departments will write code to help themselves, but most of the work will be done for other departments. So the Dev department needs to communicate, needs to interact, so that they know which problems to solve to help the other departments do their job.&lt;/p&gt;

&lt;p&gt;Development departments exists to help other departments. In other words, it’s not about me.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Twitter API Request Entity too large / HTTP 413 error</title>
   <link href="http://jrgns.net/twitter_api_request_entity_too_large_http_413_error/index.html"/>
   <updated>2010-03-30T07:12:09+00:00</updated>
   <id>http://jrgns.net/twitter_api_request_entity_too_large_http_413_error/twitter_api_request_entity_too_large_http_413_error</id>
   <content type="html">&lt;p&gt;I’ve setup &lt;a href=&quot;http://zacoders.net&quot;&gt;zacoders.net&lt;/a&gt; that it will automatically tweet new RFC’s. A while back this functionality stopped working. Today I investigated a bit further, and here’s what I found.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;When posting an update, the Twitter API responded with a 413 HTTP error code, and the following text:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Request Entity Too Large

The requested resource

/1/statuses/update.json

does not allow request data with POST requests,
or the amount of data provided in the request
exceeds the capacity limit.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I realized that the &lt;a href=&quot;http://backend-php.net&quot;&gt;backend&lt;/a&gt;’s OAuth utility sent through POST requests with the parameters included in the URI, just like a GET request:&lt;/p&gt;

&lt;p&gt;POST HTTP/1.1 http://api.twitter.com/1/statuses/update.json?parameters=here&lt;/p&gt;

&lt;p&gt;What baffled me is that I only got this error when running it on my live server, not on my testing local server. I suspect it might be a difference in the Curl libraries, but I’m not sure.&lt;/p&gt;

&lt;p&gt;To fix it, I just updated the code to only add the parameters to the URI when it was a GET, and to POST the data when it was a POST, and voila, it’s working again.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>How to remove the www from your URL</title>
   <link href="http://jrgns.net/remove_www_from_url/index.html"/>
   <updated>2010-03-26T08:03:29+00:00</updated>
   <id>http://jrgns.net/remove_www_from_url/remove_www_from_url</id>
   <content type="html">&lt;p&gt;If you like simplicity, you might like to simplify your website’s URL. You can do this by adding the following in your &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file, or in the &lt;code class=&quot;highlighter-rouge&quot;&gt;VirtualHost&lt;/code&gt; declaration on your Apache setup.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.mysite.co.za$ [NC]
RewriteRule ^(.*)$ http://mysite.co.za/$1 [L,R=301]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The rewrite module for apache needs to be installed for this to work.&lt;/p&gt;

&lt;p&gt;Remember that you can tell Google to list all links to your site with / without the www by setting that in the &lt;a href=&quot;http://www.google.com/webmasters/tools/&quot;&gt;Webmaster Tools&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>New look!</title>
   <link href="http://jrgns.net/new_look/index.html"/>
   <updated>2010-03-24T23:05:40+00:00</updated>
   <id>http://jrgns.net/new_look/new_look</id>
   <content type="html">&lt;p&gt;At long last I’ve been able to find the time to port my website from drupal to &lt;a href=&quot;http://backend-php.net&quot;&gt;backend&lt;/a&gt;. Backend is a PHP framework I wrote myself and open sourced to get it out there.&lt;/p&gt;

&lt;p&gt;I’ve also redesigned the site, made it simpler and hopefully more usable. I’ll be adding more information as I go along.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>SQLite Viewer</title>
   <link href="http://jrgns.net/sqllite_view/index.html"/>
   <updated>2010-03-18T16:28:30+00:00</updated>
   <id>http://jrgns.net/sqllite_view/sqllite_view</id>
   <content type="html">&lt;p&gt;I’m playing around with &lt;a href=&quot;http://developers.google.com/gears/&quot;&gt;Google Gears&lt;/a&gt;, doing data imports, and generally playing around. I’m quite visiually oriented, so I need to SEE that the data has been added to a table. For my conventional PHP / MySQL apps, I usually use phpMyAdmin or the MySQL query browser, but for Gears developmen, which uses SQLite, I needed to use something else.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;I wrote a small JavaScript / Gears app which enables you to view the contents of a SQLite database. All you need to use it, is to download the file, and unzip it into the folder where your web app sits. And no, you won’t be able to use it for a remote DB. You need at least FTP access to the website you want to look at, and it will only show you your local data.&lt;/p&gt;

&lt;p&gt;You will also need to know the name of the database. At the moment I can see no simple way to supply the user with a listing of DB’s, so the app prompts the user for the DB name.&lt;/p&gt;

&lt;p&gt;The app currently links to the scripts and styles on my host, which is fine for light use. If you plan to use this app extensively, please start hosting the files on your own host and update the HTML!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Update On Backend</title>
   <link href="http://jrgns.net/Update on Backend/index.html"/>
   <updated>2010-03-18T16:23:37+00:00</updated>
   <id>http://jrgns.net/Update on Backend/Update on Backend</id>
   <content type="html">&lt;p&gt;Bakend: PHP framework, as it’s now called, now has it’s own website! Check it out at &lt;a href=&quot;http://backend-php.net&quot;&gt;http://backend-php.net&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow backend on Twitter at &lt;a href=&quot;http://twitter.com/backend_php&quot;&gt;@backend_php&lt;/a&gt;!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Backend 100 Revisions</title>
   <link href="http://jrgns.net/backend_100_revisions/index.html"/>
   <updated>2010-03-18T16:20:29+00:00</updated>
   <id>http://jrgns.net/backend_100_revisions/backend_100_revisions</id>
   <content type="html">&lt;p&gt;I’ve been working on &lt;a href=&quot;http://backend-php.net&quot;&gt;backend&lt;/a&gt;, a PHP framework the last couple of months, and it’s really starting to take shape. I’ve learned a lot about what one can do by coding smarter and the advantages open source code gives on.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;After getting somewhat disheartened a few weeks back, I decided to take a look at how &lt;a href=&quot;http://codeigniter.com/&quot;&gt;CodeIgnitir&lt;/a&gt; does things, and wow, it blew my mind. After spending some time with their code base, I had so many ideas I wanted to implement in backend and my thoughts around it was instantly rejuvinated. Problems that stopped me from progressing had new solutions, and the momentum I gathered from that helped to solve some problems that didn’t have any solutions directly at hand.&lt;/p&gt;

&lt;p&gt;So, backend just hit it’s 100th revision, somewhat arbitrarily, as I reset the branch at some point, and don’t always follow the exact same commit methodology, but hey, it looks like a milestone, I’ll treat it as one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What has changed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;URL mapping has improved a lot (thanks to CodeIgnitir). &lt;code class=&quot;highlighter-rouge&quot;&gt;?q=controller/action/param1/param2&lt;/code&gt; now maps to &lt;code class=&quot;highlighter-rouge&quot;&gt;Controller::action(param1, param2)&lt;/code&gt; without much effort. This has also helped to work towards being a RESTful API.&lt;/p&gt;

&lt;p&gt;The installation process is now very smooth and stable. The setting up of data sources need some work, but once that is done, getting the application up and running and fine tuning it is a breeze.&lt;/p&gt;

&lt;p&gt;The beginning of a Links structure with named link lists can be managed. The primary use will be for primary and secondary links for a website.&lt;/p&gt;

&lt;p&gt;I’ve managed to implement tags for content, as well as RSS feeds for content as a whole, or content in a tag. The ease with which I could do it really gives me hope that backend will make my coding life easier!&lt;/p&gt;

&lt;p&gt;All around polish and stability. Especially around the HTML templating  and rendering engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to from here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The permissions / security infrastructure still needs some work. I’ve managed to automatically install most of the default permissions, but there’s no useful management interface yet.&lt;/p&gt;

&lt;p&gt;I want to start using backend on my personal site (this one) and on another site I’ve got in the works, called &lt;a href=&quot;http://zacoders.net&quot;&gt;zacoders.net&lt;/a&gt;. More on that later.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>My take on single or multiple returns</title>
   <link href="http://jrgns.net/my_take_on_single_or_multiple_returns/index.html"/>
   <updated>2010-03-18T16:17:11+00:00</updated>
   <id>http://jrgns.net/my_take_on_single_or_multiple_returns/my_take_on_single_or_multiple_returns</id>
   <content type="html">&lt;p&gt;Originally posted on &lt;a href=&quot;http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement/1276951#1276951&quot;&gt;StackOverflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I force myself to use only one return statement, as it will in a sense generate code smell. Let me explain:&lt;!--break--&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if ($param1 != $param2) {
        if ($param1 == ($param3 * 2)) {
            if ($param2 == ($param3 / 3)) {
                $toret = true;
            } else {
                $error = 'Error 3';
            }
        } else {
            $error = 'Error 2';
        }
    } else {
        $error = 'Error 1';
    }
    return $toret;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(The conditions are arbritary…)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The more conditions, the larger the function gets, the more difficult it is to read. So if you’re attuned to the code smell, you’ll realise it, and want to refactor the code. Two possible solutions are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Multiple returns&lt;/li&gt;
  &lt;li&gt;Refactoring into separate functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Multiple Returns&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
function isCorrect($param1, $param2, $param3) {
    if ($param1 == $param2)       { $error = 'Error 1'; return false; }
    if ($param1 != ($param3 * 2)) { $error = 'Error 2'; return false; }
    if ($param2 != ($param3 / 3)) { $error = 'Error 3'; return false; }
    return true;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Separate Functions&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
function isEqual($param1, $param2) {
    return $param1 == $param2;
}

function isDouble($param1, $param2) {
    return $param1 == ($param2 * 2);
}

function isThird($param1, $param2) {
    return $param1 == ($param2 / 3);
}

function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if (!isEqual($param1, $param2)
        &amp;amp;&amp;amp; isDouble($param1, $param3)
        &amp;amp;&amp;amp; isThird($param2, $param3)
    ) {
        $toret = true;
    }
    return $toret;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Granted, it is longer and a bit messy, but in the process of refactoring the function this way, we’ve&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;created a number of reusable functions,&lt;/li&gt;
  &lt;li&gt;made the function more human readable, and&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;the focus of the functions is on why the values are correct.&lt;/p&gt;

  &lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Firefox requests a page twice?</title>
   <link href="http://jrgns.net/firefox_requests_a_page_twice/index.html"/>
   <updated>2010-03-18T16:13:43+00:00</updated>
   <id>http://jrgns.net/firefox_requests_a_page_twice/firefox_requests_a_page_twice</id>
   <content type="html">&lt;p&gt;I’m busy creating a site for a client who wants to know when certain internal links get clicked. Not a problem, I just insert a record into a table every time the links they want to know about get accesesd. Only problem is, when I check the table, I notice that every page impression gets logged twice.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;Now, this happened before, where I also needed to implement some page tracking, and it ended up being an image or something with src=””, and Firefox interpreting it as the same location as the current page (as with form with action=””). Don’t know if that is according to standards, either way, it messes up my page tracking.&lt;/p&gt;

&lt;p&gt;The simple solution is to find any images or HTML elements with source attributes that are empty. Only problem is I couldn’t find any this time. So, by taking out chunks of code, I eventually tracked it to srcover attributes in some of the images. Just as a side note, I don’t use srcover, the designers use them, and unfortunately I must make do with what the designers give me.&lt;/p&gt;

&lt;p&gt;So why does Firefox (I didn’t test on other browser) do this on srcover? Firebug shows that the images specified in srcover are downloaded, and the mouseovers work, so it’s not that the images are missing or anything.&lt;/p&gt;

&lt;p&gt;I’ll investigate when I have some time, and report back…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I found this page at &lt;a href=&quot;http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/PHP_Databases/Q_23101341.html&quot;&gt;Experts Exchange&lt;/a&gt;, but hey, they want me to pay to see it. No chance of that happening. If anyone is a member, and you don’t want money to share some wisdom, please do!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update number two:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I fount &lt;a href=&quot;http://forums.mozillazine.org/viewtopic.php?p=3022038&quot;&gt;this page&lt;/a&gt; which only talks about the empty src tag, but it also quotes the HTML spec that says that empty src tags refer to the same page their in. So why does srcover still re-request my page?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update number final:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ok, so it wasn’t Firefox’s fault, but the javascript that did the rollover images. When it preloades, it doesn’t check for empty src attributes, it just loads them. As it checks for both srcover and srcdown, which aren’t necessarily specified, it gets quite a lot of empty tags. I guess that Firefox uses a cached page for the rest of the requests.&lt;/p&gt;

&lt;p&gt;The javascript library is called imagerollover.js by Adam Smith. I couldn’t find a working website, so I don’t know if I have the latest version, but I’ll upload my modified version…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Parse Http Accept Header</title>
   <link href="http://jrgns.net/parse_http_accept_header/index.html"/>
   <updated>2010-03-18T16:10:35+00:00</updated>
   <id>http://jrgns.net/parse_http_accept_header/parse_http_accept_header</id>
   <content type="html">&lt;p&gt;I want to generate CSS on the fly for a personal project. I’m doing this by redirect all requests for files that does not exist to index.php, and then, if the request is for a stylesheet, index.php generates it.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;To identify a request for a stylesheet, we need to parse the Accept header in the HTTP Request. I’ve grouped all the functions together in a Parser class.&lt;/p&gt;

&lt;p&gt;This function retrieves the header, and then determines the mime type, precedence, and tokens for each type given. It’s then sorted according to &lt;a href=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&quot;&gt;RFC 2616&lt;/a&gt; specifications.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
public static function accept_header($header = false) {
	$toret = null;
	$header = $header ? $header : (array_key_exists('HTTP_ACCEPT', $_SERVER) ? $_SERVER['HTTP_ACCEPT']: false);
	if ($header) {
		$types = explode(',', $header);
		$types = array_map('trim', $types);
		foreach ($types as $one_type) {
			$one_type = explode(';', $one_type);
			$type = array_shift($one_type);
			if ($type) {
				list($precedence, $tokens) = self::accept_header_options($one_type);
				list($main_type, $sub_type) = array_map('trim', explode('/', $type));
				$toret[] = array('main_type' =&amp;gt; $main_type, 'sub_type' =&amp;gt; $sub_type, 'precedence' =&amp;gt; (float)$precedence, 'tokens' =&amp;gt; $tokens);
			}
		}
		usort($toret, array('Parser', 'compare_media_ranges'));
	}
	return $toret;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This helper function parses the options for each mime type, determining the precedence and tokens. It returns the precidence as a float, and an array of tokens.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
public static function accept_header_options($type_options) {
	$precedence = 1;
	$tokens = array();
	if (is_string($type_options)) {
		$type_options = explode(';', $type_options);
	}
	$type_options = array_map('trim', $type_options);
	foreach ($type_options as $option) {
		$option = explode('=', $option);
		$option = array_map('trim', $option);
		if ($option[0] == 'q') {
			$precedence = $option[1];
		} else {
			$tokens[$option[0]] = $option[1];
		}
	}
	$tokens = count ($tokens) ? $tokens : false;
	return array($precedence, $tokens);
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This function is used to sort the array of mime types we parsed from the header. At the moment it doesn’t check any tokens, but this code can easily be added on line 6.
&lt;?php
private static function compare_media_ranges($one, $two) {
	if ($one['main_type'] != '*' &amp;&amp; $two['main_type'] != '*') {
		if ($one['sub_type'] != '*' &amp;&amp; $two['sub_type'] != '*') {
			if ($one['precedence'] == $two['precedence']) {
				if (count ($one['tokens']) == count ($two['tokens'])) {
					return 0;
				} else if (count ($one['tokens']) &lt; count ($two['tokens'])) {
					return 1;
				} else {
					return -1;
				}
			} else if ($one['precedence'] &lt; $two['precedence']) {
				return 1;
			} else {
				return -1;
			}
		} else if ($one['sub_type'] == '*') {
			return 1;
		} else {
			return -1;
		}
	} else if ($one['main_type'] == '*') {
		return 1;
	} else {
		return -1;
	}
}
?&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Backend-PHP Framework</title>
   <link href="http://jrgns.net/backend_intro/index.html"/>
   <updated>2010-03-18T08:46:32+00:00</updated>
   <id>http://jrgns.net/backend_intro/backend_intro</id>
   <content type="html">&lt;div class=&quot;notice&quot;&gt;
&lt;h3&gt;Update: 21/11/2011&lt;/h3&gt;
Backend has undergone a major rewrite. Get the latest info &lt;a href=&quot;/content/backend-core-a-restful-mvc-php-framework&quot;&gt;here&lt;/a&gt;, and get the code on &lt;a href=&quot;https://github.com/jrgns/backend-core&quot;&gt;GitHub&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;In the past few years I’ve been working on a PHP framework / backend. Sometimes out of frustration with copying and pasting code, but usually because I’m to lazy to write a lot of code, so decide to write a little bit of code to do a lot… And then I write some more code, to do a little bit more, and before you know it, it’s yet another PHP framework. I tried to get some public input on the &lt;a href=&quot;http://launchpad.net/yaphpfter&quot;&gt;project&lt;/a&gt; once before, but that went nowhere, and I left it there - until of course I had to do some work that required the same type of thing, and now I’m at it again.&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;What makes backend different from my previous &lt;a href=&quot;http://www.codinghorror.com/blog/archives/000576.html&quot;&gt;failed&lt;/a&gt; experiment? Well, the fact that this is now the 7th or 8th time that I’ve rehashed the concept, and that this time, I’ve actually put some thought and effort into it. No, it’s not perfect, and it won’t solve the world’s problems, but it better and simpler, and hopefully more useful.&lt;/p&gt;

&lt;p&gt;One concept that I definitely want to run with in backend, is the concept of backend as a web service, as opposed to a framework or a content / data management system. Backend provides a client, as in a browser or an application, with the requested data, in a format that the client can understand. Be it a human readable web page, JSON, XML or even PHP variables. This struck me as important after reading &lt;a href=&quot;http://tomayko.com/writings/rest-to-my-wife&quot;&gt;this&lt;/a&gt; by Ryan Tomayko:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Wife: A web page is a resource?&lt;/p&gt;

  &lt;p&gt;Ryan: Kind of. A web page is a
“representation” of a resource.
Resources are just concepts.
URLs—those things that you type into
the browser…&lt;/p&gt;

  &lt;p&gt;Wife: I know what a URL is..&lt;/p&gt;

  &lt;p&gt;Ryan: Oh, right. Those tell the
browser that there’s a concept
somewhere. A browser can then go ask
for a specific representation of the
concept. Specifically, the browser
asks for the web page representation
of the concept.&lt;/p&gt;

  &lt;p&gt;Wife: What other kinds of
representations are there?&lt;/p&gt;

  &lt;p&gt;Ryan: Actually, representations is one
of these things that doesn’t get used
a lot. In most cases, a resource has
only a single representation. But
we’re hoping that representations will
be used more in the future because
there’s a bunch of new formats popping
up all over the place.&lt;/p&gt;

  &lt;p&gt;Wife: Like what?&lt;/p&gt;

  &lt;p&gt;Ryan: Hmm. Well, there’s this concept
that people are calling “Web
Services”. It means a lot of different
things to a lot of different people
but the basic concept is that machines
could use the web just like people do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So it’s important for me to make it easy for web developers to easily provide data in different formats. Backend can already provide any client with data in 4, yes 4, different formats:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HTML, or a human readable webpage&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://json.org/&quot;&gt;JSON&lt;/a&gt;, the new darling of AJAX fans&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.php.net/serialize&quot;&gt;(PHP) Serialized byte stream representations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.php.net/var-export&quot;&gt;PHP variables&lt;/a&gt;, as created by var_export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will hopefully increase backend’s usefulness as a web service. And yes, I know, XML is missing, but of those 4, HTML was necessary, although not necessarily easy, and the other three were extremely easy to implement, as they are all products of simple PHP functions. One day when someone uses backend and actually &lt;strong&gt;needs&lt;/strong&gt; XML, we can implement it. (Notice that I said &lt;em&gt;we&lt;/em&gt;, not &lt;em&gt;I&lt;/em&gt; - I rarely use XML, so I won’t know the requirements, so if I do it alone, it will probably be useless).&lt;/p&gt;

&lt;p&gt;At the moment backend is on version 0.1.2.1 in my personal repo. All that means is that I’ve decided I’ve reached a point where I can actually release the code to the public, and made some improvements, fixes and changes. When will it be marked as version 1.0?&lt;/p&gt;

&lt;p&gt;When we have the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A fully fledged and integrated admin space
2, Easy and intuitive setup / install system&lt;/li&gt;
  &lt;li&gt;Easy and intuitive update system&lt;/li&gt;
  &lt;li&gt;An intuitive plugin system&lt;/li&gt;
  &lt;li&gt;Intuitive and function DB Objects&amp;lt;&lt;/li&gt;
  &lt;li&gt;The ability to easily implement different data formats&lt;/li&gt;
  &lt;li&gt;The ability to use multiple and different data sources (MySQL, SQLite, flat files, etc.)&lt;/li&gt;
  &lt;li&gt;Working and secure user access control&lt;/li&gt;
  &lt;li&gt;Either a REST-full implementation, or a roadmap towards it&lt;/li&gt;
  &lt;li&gt;Something that makes coding easier&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s ten requirements for me to release backend v1.0…&lt;/p&gt;

&lt;p&gt;What’s already done?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Semi working DB Objects&lt;/li&gt;
  &lt;li&gt;Output of different data formats using views&lt;/li&gt;
  &lt;li&gt;Simple templating / caching system&lt;/li&gt;
  &lt;li&gt;Simple user access control&lt;/li&gt;
  &lt;li&gt;CRUD, actually, just CRU actions. I haven’t gotten round to the Deletes yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m using &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; as a JavaScript backend, and &lt;a href=&quot;http://www.blueprintcss.org/&quot;&gt;blueprint&lt;/a&gt; for my CSS needs. For now it’s under the &lt;a href=&quot;http://www.opensource.org/licenses/eclipse-1.0.php&quot;&gt;EPL&lt;/a&gt;, but I may switch to the MIT license at some point. I’m using MySQL exclusively at this point, but am hoping to add support for other DB’s / sources eventually.&lt;/p&gt;

&lt;p&gt;I’ll be putting the code on &lt;a href=&quot;http://launchpad.net/backend&quot;&gt;Launchpad&lt;/a&gt; soon, so if you want to contribute, or comment, please do!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Importing a file into a Google Gears DB using PHP</title>
   <link href="http://jrgns.net/import_to_google_gears/index.html"/>
   <updated>2010-03-18T08:45:19+00:00</updated>
   <id>http://jrgns.net/import_to_google_gears/import_to_google_gears</id>
   <content type="html">&lt;p&gt;I’m playing around with &lt;a href=&quot;http://developers.google.com/gears/&quot;&gt;Google Gears&lt;/a&gt;, particularly the database part, just to see what it’s usefull for, and if I can use it in an app I’m working on. At some point I realised that I will need to import data at some point. Here’s how I did it:&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;By using an HTML uploading form, and PHP to process the upload, you can create a JSON object which can be used to import data into whatever Gears DB you have. Use whatever you use to put all of the data into one array. The source can be a DB or a file upload, come to think of it. Convert the data to JSON using json_encode, and assign it to a JavaScript variable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var data = &lt;?php echo json_encode($data) ?&gt;;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After that, check that the table exists, loop through the data, and insert!&lt;/p&gt;

&lt;p&gt;The complete code below:&lt;/p&gt;

&lt;p&gt;The test data to import:&lt;/p&gt;

&lt;pre&gt;
&quot;one two&quot;,2,1
&quot;three four&quot;,3.4,2
&lt;/pre&gt;

&lt;p&gt;And the test page, HTML and PHP together:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php
$data = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	$data = array();
	if (!empty($_FILES['to_import']['tmp_name']) &amp;amp;&amp;amp; is_readable($_FILES['to_import']['tmp_name'])) {
		$fp = fopen($_FILES['to_import']['tmp_name'], 'r');
		while (($row = fgetcsv($fp)) !== false) {
			$data[] = $row;
		}
		fclose($fp);
	}
	$data;
}
?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;JSON / Gears import Test&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onload=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;do_import()&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;post&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;enctype=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;multipart/form-data&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;file&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;to_import&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'gears_init.js'&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;do_import&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gears&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'beta.database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database-test'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'CREATE TABLE IF NOT EXISTS Import'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				&lt;span class=&quot;s1&quot;&gt;' (Phrase text, Amount float, Something int)'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'INSERT INTO Import Values(?, ?, ?)'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

		&lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'SELECT * FROM Import'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isValidRow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' - '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' - '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Redirect All Requests To Index.php Using .htaccess</title>
   <link href="http://jrgns.net/redirect_request_to_index/index.html"/>
   <updated>2010-03-18T08:42:15+00:00</updated>
   <id>http://jrgns.net/redirect_request_to_index/redirect_request_to_index</id>
   <content type="html">&lt;p&gt;In one of my pet projects, I redirect all requests to index.php, which then decides what to do with it:&lt;!--break--&gt;&lt;/p&gt;

&lt;p&gt;###Simple Example&lt;/p&gt;

&lt;p&gt;This snippet in your .htaccess will ensure that all requests for files and folders that does not exists will be redirected to index.php:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This enables the rewrite engine:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteEngine on
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This checks for existing folders (-d) and files (-f):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And this does the actual redirecting:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteRule . index.php [L]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;###Extended Example&lt;/p&gt;

&lt;p&gt;You can extend this to pass the requested path to the index.php file by modifying the &lt;code class=&quot;highlighter-rouge&quot;&gt;RewriteRule&lt;/code&gt; to the following:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;^(.*)$&lt;/code&gt; part tells the rewrite module that we want to pass down the whole requested path as one parameter.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;QSA&lt;/code&gt; part tells the module to append any query strings to the request.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;?q=$1&lt;/code&gt; tells the module how to pass down the parameter. In this case, it’s passed down as the &lt;code class=&quot;highlighter-rouge&quot;&gt;q&lt;/code&gt; parameter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can extend this even further by using regular expressions. For example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RewriteRule ^([^/]*)(.*)$ index.php?first=$1&amp;amp;second=$2 [L,QSA]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will pass down the first part of the path as the &lt;code class=&quot;highlighter-rouge&quot;&gt;first&lt;/code&gt; parameter, and the rest as the &lt;code class=&quot;highlighter-rouge&quot;&gt;second&lt;/code&gt;. So the following request&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://yourhost.com/some/path/somewhere
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;will result in&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://yourhost.com/index.php?first=some&amp;amp;second=path/somewhere
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This allows for some creative ways to do clean URLs.&lt;/p&gt;

&lt;p&gt;###Trouble Shooting&lt;/p&gt;

&lt;p&gt;If it’s not working, make sure that mod_rewrite is installed on Apache. On a unix system you can just do&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo a2enmod rewrite
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;to achieve that.&lt;/p&gt;
</content>
 </entry>
 
 
 <entry>
   <title></title>
   <link href="http://jrgns.net/atom.xml"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;feed xmlns=&quot;http://www.w3.org/2005/Atom&quot;&gt;

 &lt;title&gt;Jurgens du Toit&lt;/title&gt;
 &lt;link href=&quot;http://jrgns.net/atom.xml&quot; rel=&quot;self&quot;/&gt;
 &lt;link href=&quot;http://jrgns.net/&quot;/&gt;
 &lt;updated&gt;2017-02-02T05:34:34+00:00&lt;/updated&gt;
 &lt;id&gt;http://jrgns.net/&lt;/id&gt;
 &lt;author&gt;
   &lt;name&gt;Jurgens du Toit&lt;/name&gt;
   &lt;email&gt;jrgns@jrgns.net&lt;/email&gt;
 &lt;/author&gt;

 
 &lt;entry&gt;
   &lt;title&gt;&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/2017/02/02/2011-10-14-backend-core-a-restful-mvc-php-framework.html&quot;/&gt;
   &lt;updated&gt;2017-02-02T05:34:34+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/2017/02/02/2011-10-14-backend-core-a-restful-mvc-php-framework&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I like frameworks. I like working with them, I like writing them. I wrote &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;Backend-PHP&amp;lt;/a&amp;gt;, which I’m using personally and at &amp;lt;a href=&amp;quot;http://www.brandedinternet.co.za&amp;quot;&amp;gt;Branded Internet&amp;lt;/a&amp;gt;. Unfortunately it has a number of major flaws: It’s not easily unit testable, not really a REST web service, and it doesn’t conform to any popular coding standards. So I wrote &amp;lt;a href=&amp;quot;https://github.com/jrgns/backend-core&amp;quot;&amp;gt;Backend-Core&amp;lt;/a&amp;gt; as the first step towards addressing these issues.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;minimal&amp;quot;&amp;gt;Minimal&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Backend-Core is only intended as a minimal, core system. It doesn’t implement any application logic or data source abstraction. I decided to focus on the core functionality and design of a RESTful MVC system, and make sure that it works as it should. Eventually I’ll extend it with a seperate code base that will include application and data source logic.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;mvc&amp;quot;&amp;gt;MVC&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;The system is structured into Model, View and Controller components:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Model - The model contains all the &amp;lt;strong&amp;gt;business&amp;lt;/strong&amp;gt; logic for an application. As this is a core system, the models are empty.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;View - The view determines how the results of a query will be displayed.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Controller - The controller contains the &amp;lt;strong&amp;gt;application&amp;lt;/strong&amp;gt; logic. Once again, this is only the core, not an application, so the controller just calls the model.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;I found that a number of MVC systems confuse what should go into the Model and what should go into the Controller. I’m aiming for thin Controllers containing application logic, and thick Models containing the business logic.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;unit-testing&amp;quot;&amp;gt;Unit Testing&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Backend-PHP used static global classes quite liberally, without even a thought around dependency injection. This makes unit testing unreliable and a real headache to add to the framework.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Backend-Core, on the other hand, was designed to use &amp;lt;a href=&amp;quot;http://martinfowler.com/articles/injection.html#ConstructorVersusSetterInjection&amp;quot;&amp;gt;constructor injection&amp;lt;/a&amp;gt; across the board, and includes a number of unit tests, supported by PHPUnit. This should increase the overall stability of the system.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;restful-service&amp;quot;&amp;gt;RESTful Service&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Something I didn’t understand about REST when I initial wrote Backend-PHP, was that every REST URL should refer to a noun, with &amp;lt;a href=&amp;quot;http://stackoverflow.com/questions/2001773/understanding-rest-verbs-error-codes-and-authentication/2022938#2022938&amp;quot;&amp;gt;the only verbs being GET, POST, PUT and DELETE&amp;lt;/a&amp;gt;, as specified by the HTTP request. This resulted in it &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; complying with REST standards, as a lot of the URLs contained extra verbs, or didn’t refer to nouns directly.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Backend-Core supports the REST / HTTP verbs directly, and uses the same methods as CakePHP to identify which verb to use:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;A &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;_method&amp;lt;/code&amp;gt; POST variable&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;A &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;X_HTTP_METHOD_OVERRIDE&amp;lt;/code&amp;gt; header sent with the request&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;The HTTP request’s method&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;This enables it to be used from a Web browser as well as from a REST compliant client.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;documentation-and-coding-standards&amp;quot;&amp;gt;Documentation and Coding Standards&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;The code complies with the &amp;lt;a href=&amp;quot;http://framework.zend.com/manual/en/coding-standard.html&amp;quot;&amp;gt;ZEND coding standard&amp;lt;/a&amp;gt;, as enforced by &amp;lt;a href=&amp;quot;http://pear.php.net/package/PHP_CodeSniffer/redirected&amp;quot;&amp;gt;PHP Code Sniffer&amp;lt;/a&amp;gt;. It’s documented using the &amp;lt;a href=&amp;quot;http://www.phpdoc.org/&amp;quot;&amp;gt;PHPdoc standard&amp;lt;/a&amp;gt;. Hopefully this will make it easier for people to contribute to and extend the system.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Feel free to fork, comment and use this.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;The Logstash Config Guide&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2015/01/12/logstash-config-guide.html&quot;/&gt;
   &lt;updated&gt;2015-01-12T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2015/01/12/logstash-config-guide&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;The ELK stack has been becoming more and more popular, specifically &amp;lt;a href=&amp;quot;http://www.elasticsearch.org/&amp;quot;&amp;gt;Elasticsearch&amp;lt;/a&amp;gt;. The &amp;lt;a href=&amp;quot;http://www.google.com/trends/explore#q=elasticsearch&amp;quot;&amp;gt;search volume&amp;lt;/a&amp;gt; for it has been growing constantly since 2010. It’s faithful sidekick, &amp;lt;a href=&amp;quot;http://logstash.net/&amp;quot;&amp;gt;Logstash&amp;lt;/a&amp;gt;, has been growing along with it, and ever since I’ve started looking at it, I’m just loving it more and more.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The fact that you can string together totally disparate systems, from XMPP to Redmine and files on S3 to Nagios, with a simple config makes it a wonderful plaything and very useful utility. The rub, though, is in the config: Even though a great effort is made to write proper docs, I’ve found the documentation to be unclear, incomplete and sometimes confusing. So I’ve decided to do something about it:&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Pain Free Logstash Configuration&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;text-align: center;&amp;quot;&amp;gt;
&amp;lt;a href=&amp;quot;https://leanpub.com/logstashconfigguide&amp;quot;&amp;gt;
&amp;lt;img src=&amp;quot;https://s3.amazonaws.com/titlepages.leanpub.com/logstashconfigguide/medium?1421001125&amp;quot; /&amp;gt;
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;text-align: center;&amp;quot;&amp;gt;
Buy it now on &amp;lt;a href=&amp;quot;https://leanpub.com/logstashconfigguide&amp;quot;&amp;gt;Leanpub&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;!--break--&amp;gt;

&amp;lt;p&amp;gt;The plan is to write focused guides on some of the more popular Logstash plugins in the hopes of making it easier for people to set up and configure them. Each chapter will point out the bare minimum required to get you up and running and also highlight some of the more interesting, but not necessarily necessary settings for a plugin. You’ll also find a complete reference of all the available settings, with working examples for each of them.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;It’s still early days, but I’ll be publishing a number of preliminary posts on [EagerELK][5] to get things going. Subscribe there, or just buy the book on &amp;lt;a href=&amp;quot;https://leanpub.com/logstashconfigguide&amp;quot;&amp;gt;Leanpub&amp;lt;/a&amp;gt;, to stay up to date.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The book will be focusing on version 1.4.2 of Logstash (since 1.5 is still in beta), but I’ll update it once 1.5 is stable and being adopted. If you sign up for the 1.4.2 version, you’ll receive a free upgrade to the 1.5 version. Two books for the price of one!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Any questions or comments are welcome, let me know below!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Populate a Symfony 2 Form with the referring entity&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2014/02/03/populate-form-with-referring-entity-symfony.html&quot;/&gt;
   &lt;updated&gt;2014-02-03T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2014/02/03/populate-form-with-referring-entity-symfony&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;In any web project it often happens that you have an entity, say a Group, to which you want to add a linked entity, say a Student. So you’ll have a “Add a Student” link on the page displaying the Group. When your users click through, there’s probably a dropdown with the different groups, and your users expect the Group they’re coming from to be prepopulated.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;There’s various ways to do this, but I’d like to show you a simple, non intrusive one for Symfony 2. You don’t have to add any parameters to the link, it just works. In your &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Student&amp;lt;/code&amp;gt; Controller, the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;newAction&amp;lt;/code&amp;gt; method:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// src/My/Bundle/Controller/StudentController.php
&amp;lt;/span&amp;gt;    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;newAction&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Student&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$form&amp;lt;/span&amp;gt;   &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;createForm&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;StudentType&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(),&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

        &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Get the refering URL Path
&amp;lt;/span&amp;gt;        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$ref&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;str_replace&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;app_dev.php/&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;parse_url&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$request&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;headers&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'referer'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;),&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;PHP_URL_PATH&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;));&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Get the matching route
&amp;lt;/span&amp;gt;        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$route&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;container&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'router'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;match&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$ref&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;empty&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$route&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'_route'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;])&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;===&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;false&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$route&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'_route'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;===&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'group_show'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Find the referring group
&amp;lt;/span&amp;gt;            &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$group&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'doctrine'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getRepository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'MyBundle:Group'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;findOneById&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$route&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'id'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;]))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
                &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$form&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'group'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setData&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$group&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;render&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'MyBundle:Student:new.html.twig'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'entity'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'form'&amp;lt;/span&amp;gt;   &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$form&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;createView&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(),&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;));&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;We basically try and match the referring URL to a route, and if found, retrieve that entity, and set it in the form. Simple!&amp;lt;/p&amp;gt;
&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;MS-SQL Stored Procedures in Sequel: Getting the value of output variables&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel.html&quot;/&gt;
   &lt;updated&gt;2014-01-03T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;We had the opportunity to muck around with a couple of technologies at &amp;lt;a href=&amp;quot;http://www.tutuka.com&amp;quot;&amp;gt;Tutuka&amp;lt;/a&amp;gt; the last few weeks. I managed to do
some work with Ruby, specifically &amp;lt;a href=&amp;quot;http://www.sinatrarb.com/&amp;quot;&amp;gt;Sinatra&amp;lt;/a&amp;gt; and &amp;lt;a href=&amp;quot;http://sequel.jeremyevans.net/&amp;quot;&amp;gt;Sequel&amp;lt;/a&amp;gt;. We use MS-SQL extensively and eventually we ran into an issue where
we couldn’t get the values of output variables from stored procedures. After extensive googling we found out that it’s
not supported. There were a couple of clues on how it might be done (particularly this &amp;lt;a href=&amp;quot;https://github.com/rails-sqlserver/tiny_tds/issues/24&amp;quot;&amp;gt;TinyTDS Issue&amp;lt;/a&amp;gt;), so after chatting
with Jeremy (the maintainer of Sequel) I decided to try and the necessary support.&amp;lt;/p&amp;gt;

&amp;lt;h1 id=&amp;quot;it-worked&amp;quot;&amp;gt;It Worked!&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;I was relatively surprised on how easy it was. As of yesterday (2014-01-02) it’s now part of the Sequel version 4.6&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;Add Database#call_mssql_sproc on MSSQL for calling stored procedures and handling output parameters (jrgns, jeremyevans) (#748)
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;h1 id=&amp;quot;how-to-use-it&amp;quot;&amp;gt;How to use it&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;You can get a good idea on how to use it from the &amp;lt;a href=&amp;quot;https://github.com/jeremyevans/sequel/blob/master/doc/mssql_stored_procedures.rdoc&amp;quot;&amp;gt;documentation&amp;lt;/a&amp;gt;, but here’s a summary.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Let’s say your stored procedure is defined as follows:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;CREATE PROCEDURE dbo.SequelTest(
  @Input varchar(25),
  @Output int OUTPUT
)
AS
  SET @Output = LEN(@Input)
  RETURN 0
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;If you don’t care about the type or the name of the output variable, execution is as simple specifying that an argument
is an output parameter by passing the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;:output&amp;lt;/code&amp;gt; symbol as the argument value.&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;amp;gt; ['Input String', :output]})

&amp;amp;gt; {:result =&amp;amp;gt; 0, :numrows =&amp;amp;gt; 1, :var1 =&amp;amp;gt; &amp;quot;1&amp;quot;}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;result&amp;lt;/code&amp;gt; and &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;numrows&amp;lt;/code&amp;gt; element will contain the result code returned by the stored proc and the number of rows affected
respectively.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you need to specify the type of the output variable, do so by specifying the second element of the array:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;amp;gt; ['Input String', [:output, 'int']]})

&amp;amp;gt; {:result =&amp;amp;gt; 0, :numrows =&amp;amp;gt; 1, :var1 =&amp;amp;gt; 1}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;If you need to specify the name of the output variable, do so by specifying the third element of the array:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;DB.call_mssql_sproc(:SequelTest, {:args =&amp;amp;gt; ['Input String', [:output, nil, 'output']]})

&amp;amp;gt; {:result =&amp;amp;gt; 0, :numrows =&amp;amp;gt; 1, :output =&amp;amp;gt; &amp;quot;1&amp;quot;}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;Enjoy!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;PHP: The slums of the Programming World?&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/10/10/is-php-the-slums-of-the-programming-world.html&quot;/&gt;
   &lt;updated&gt;2013-10-10T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/10/10/is-php-the-slums-of-the-programming-world&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I presented this at &amp;lt;a href=&amp;quot;http://www.tech4africa.com&amp;quot;&amp;gt;Tech4Africa 2013&amp;lt;/a&amp;gt;. The slides can be found &amp;lt;a href=&amp;quot;http://jrgns.net/talks/phpslums&amp;quot;&amp;gt;here&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;h1 id=&amp;quot;quick-history-of-php&amp;quot;&amp;gt;Quick History of PHP&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;PHP was initially created by Rasmus Lerdorf when he got irritated by repetitive coding of CGI calls. He consolidated a number of
functions into a C library and created a parser which would call these functions out of HTML. And so PHP was born! Versions
2 and 3 were formalizations and extensions of the libraries, still using Rasmus’ parser.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The Zend Engine replaced Rasmus’ parser for version 4, introducing OOP capabilities, and in Version 5 Zend Engine 2 was
introduced. Recent versions of PHP saw even more improvements, most notable namespaces in 5.3 and a built in web server
and traits in 5.4&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;There’s no ideology or design philosophy, except that it should be a &amp;lt;a href=&amp;quot;http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html&amp;quot;&amp;gt;simple tool to solve problems&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;“I’ve never thought of PHP as more than a simple tool to solve problems”&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;https://twitter.com/rasmus/status/1938080214814720&amp;quot;&amp;gt;Rasmus Lerdorf 2010&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;h1 id=&amp;quot;lies-damned-lies-and-&amp;quot;&amp;gt;Lies, Damned Lies and …&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/tiobe-language-trends.png&amp;quot; alt=&amp;quot;TIOBE Language trends&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Despite a worsening reputation, the language hasn’t decreased in popularity.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/web-language-trends.png&amp;quot; alt=&amp;quot;Web Language Trends&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Less searches are being done for PHP.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/framework-trends.png&amp;quot; alt=&amp;quot;Framework Trends&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you look at the JavaScript vs JQuery trends, JavaScript is also decreasing, but JQuery is increasing. It seems like
the programming community is realising that frameworks are a good idea.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/php-framework-trends.png&amp;quot; alt=&amp;quot;PHP Framework Trends&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So if you look at PHP frameworks, searches on them are also increasing, especially after 2013 when Zend 2 and Symfony 2
were released.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/php-usage.png&amp;quot; alt=&amp;quot;PHP Usage&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;No shortage of hosts offering PHP.&amp;lt;/p&amp;gt;

&amp;lt;h1 id=&amp;quot;who-uses-it&amp;quot;&amp;gt;Who uses it?&amp;lt;/h1&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;User facing portion of Facebook through HipHop PHP (which generates C++)&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Wordpress - Application turned framework&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Yahoo (for now). They are replacing it with Node.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Wikipedia / Mediawiki&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;h1 id=&amp;quot;embrace-the-cactus&amp;quot;&amp;gt;Embrace the Cactus&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;It’s easy to create insecure / buggy code in PHP:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;language-php highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;    mysql_query(&amp;quot;SELECT * FROM `users` WHERE `username` = $_GET['username']&amp;quot;);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;PHP accounts for only 18% of applications covered by the &amp;lt;abbr class=&amp;quot;Common Vulnerabilities and Exposures&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;http://www.coelho.net/php_cve.html&amp;quot;&amp;gt;CVE&amp;lt;/a&amp;gt;&amp;lt;/abbr&amp;gt;, but accounts for almost 29% of the  vulnerabilities&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;It’s developed a bad reputation in the programming community:&amp;lt;/p&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;Bringing a knife to a gun fight is like bringing PHP to a modern web stack.&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;https://twitter.com/iamdevloper/status/380285502580338688&amp;quot;&amp;gt;@iamdevloper&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;p&amp;gt;Settings such as &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;register_globals&amp;lt;/code&amp;gt; and &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;magic_quotes&amp;lt;/code&amp;gt; that defaulted to &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;on&amp;lt;/code&amp;gt; opened up a lot of security holes&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;No unified community. In general, the community is great. In the rare cases where the PHP documentation (or even the language) is insufficient,
you can usually find something of value in the comments. Yet, there is a lot of conflict in both the official (like PHP internals) and
the unofficial (like &amp;lt;a href=&amp;quot;http://www.php-fig.org/&amp;quot;&amp;gt;PHP-FIG&amp;lt;/a&amp;gt;) communities.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you look at the debate on what to use for indentation, &amp;lt;a href=&amp;quot;http://philsturgeon.co.uk/blog/2013/04/psr2-the-tough-decision&amp;quot;&amp;gt;tabs&amp;lt;/a&amp;gt; vs &amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/pull/35&amp;quot;&amp;gt;spaces&amp;lt;/a&amp;gt;, the community is in total disarray.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/tabs-not-spaces.png&amp;quot; alt=&amp;quot;Tabs Not Spaces Slugfest&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Inconsistencies in naming functions:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;language-php highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;strrev     // String Function
str_repeat // String Function
explode    // String Function
// At least somewhat consistent
strpos($haystack, $needle)
array_key_exists($needle, $haystack)
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;Object Oriented, or just Object Capable? - &amp;lt;a href=&amp;quot;http://michaelkimsal.com/blog/php-is-not-object-oriented/&amp;quot;&amp;gt;Michael Kimsal&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So you can do Object Oriented Programming as well as Procedural and Functional Programming in PHP (especially PHP 5.3 and later).&amp;lt;/p&amp;gt;

&amp;lt;h1 id=&amp;quot;see-you-on-the-flip-side&amp;quot;&amp;gt;See you on the flip side…&amp;lt;/h1&amp;gt;

&amp;lt;h2 id=&amp;quot;php-53&amp;quot;&amp;gt;PHP 5.3&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;PHP 5.3 is for me a watershed version on PHP’s history - It introduced a number of features / capabilities that made it possible
for some of the other factors I’ll mention to come into existence. The most notable feature is namespaces, making it easier
to name classes in a sane way. A lot of people welcomed the introduction of lambda functions and closures.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I think the PHP developers and community realized that PHP was becoming outdated and had a lot of valid issues that needed
to be addressed. For me 5.3 was a definite step in the right direction. It introduced (amongst other things):&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Namespaces&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Closures and Lambda functions&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;h2 id=&amp;quot;php-fig&amp;quot;&amp;gt;PHP-FIG&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Although it seems to generate a lot of conflict, the PHP-FIG has managed to at least get the different frameworks talking.
It’s an unofficial (as in not sponsored by PHP) group formed by various frameworks and projects whose aim it is to get
the projects talking and to find ways to work together. It’s not always plain sailing, but it seems to get to valuable
decisions. Eventually.&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md&amp;quot;&amp;gt;PSR-0&amp;lt;/a&amp;gt; has enabled the creation of packaging software such as composer / packagist&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md&amp;quot;&amp;gt;PSR-1&amp;lt;/a&amp;gt; and &amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md&amp;quot;&amp;gt;PSR-2&amp;lt;/a&amp;gt; generated a lot of conflict, but at least all of the participating frameworks partially agreed on coding standards&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md&amp;quot;&amp;gt;PSR-3&amp;lt;/a&amp;gt; and &amp;lt;a href=&amp;quot;https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md&amp;quot;&amp;gt;PSR-4&amp;lt;/a&amp;gt; aren’t momentous decisions, but they at least pave the way forward for increased collaboration&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;h2 id=&amp;quot;packagist--composer&amp;quot;&amp;gt;Packagist / Composer&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;http://getcomposer.org/&amp;quot;&amp;gt;Composer&amp;lt;/a&amp;gt; is a tool to manage dependencies for a project, and manages and installs dependencies on a per project
basis. Very much on par with node’s npm and ruby’s bundler. &amp;lt;a href=&amp;quot;https://packagist.org/&amp;quot;&amp;gt;Packagist&amp;lt;/a&amp;gt; is a repository for composer packages and
makes it dead simple to find a package / library that will address your specific need. Before this, we had PEAR, but
that was usually a headache to set up and version properly locally, not to mention on a shared host.
Now it’s as simple as doing&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;language-bash highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;    composer require &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;vendor/library&amp;quot;&amp;lt;/span&amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;To a certain extent the improvements in PHP 5.3 and some of the work from PHP-FIG made this possible, although composer
could have existed without them.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;modern-frameworks&amp;quot;&amp;gt;Modern Frameworks&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;The combination of PHP 5.3 (specifically namespaces and proper OO support), the work of the PHP-GIH and the development
of Composer made it possible to not only create frameworks such as Symfony2, Zend2 and Laravel, but also to reuse components
from these frameworks in other projects. Drupal 8 uses a lot of Symfony2’s components. PPI is a framework built using
both Zend2 and Symfony2 components. You can now easily choose and combine libraries without having to manage class names
or dependencies. This has at least two direct advantages for project developers:&amp;lt;/p&amp;gt;

&amp;lt;ol&amp;gt;
  &amp;lt;li&amp;gt;Instant access to a whole range of precoded, quality, libraries.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;No more wasting time on managing dependencies and name clashes.&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;

&amp;lt;h1 id=&amp;quot;so-slum-or-diamond-in-the-rough&amp;quot;&amp;gt;So, Slum or Diamond in the Rough?&amp;lt;/h1&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;Good systems cater for users’ mistakes, great systems also cater for developers’ mistakes…&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;https://twitter.com/jrgns/status/365357629469499392&amp;quot;&amp;gt;Jrgns&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;p&amp;gt;My opinion is, there is no right answer. To a certain extent, PHP can be described as a horrible language that makes it
very easy to introduce bugs and security issues. It doesn’t give you guidance on how to do anything, and can’t seem to
decide if it’s procedural or object oriented. In the same breath, it gives you a lot of freedom to code according to your
style, and makes a lot of common coding tasks very easy to do. Successful business have been built and are still running
on PHP.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you’ve never coded anything but PHP and have no formal programming education (including good programming books), you’re
probably coding crappy PHP. Probably. I’d suggest you start reading up on good programming practices, start reading code
that’s of a high quality, and start learning other programming languages, especially stricter ones like Java, or start
using frameworks such as Symfony2 and Laravel that at least guides you in the right direction. Speaking multiple natural
languages keeps your brain sharp and young. Coding in &amp;lt;a href=&amp;quot;http://www.sciencemag.org/content/330/6002/332.summary&amp;quot;&amp;gt;multiple languages&amp;lt;/a&amp;gt; makes you a better coder.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you know what you’re doing and you perhaps have some extra experience in a more structured language such as Java or Ruby,
you’re probably coding quality PHP. It’s un-opinionated, so, as long as you know what you’re doing, it can be a great tool.
Don’t discount the language just because it’s lost it’s coolness factor. You can write quality code in PHP.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;/img/sheer-iron-willed-discipline.png&amp;quot; alt=&amp;quot;Sheer Iron WIlled Discipline&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;If you can pull it off, you’re badass as hell, but most of the time you’re only going to end up stabbing yourself.&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;https://twitter.com/ohpalmer/status/380290678502461440&amp;quot;&amp;gt;ohpalmer&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;A DIY Dynamic DNS service using Cloudflare&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/09/26/diy-dynamic-dns-using-cloudflare.html&quot;/&gt;
   &lt;updated&gt;2013-09-26T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/09/26/diy-dynamic-dns-using-cloudflare&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;DynDNS was always the dynamic IP service of choice, but I could never get it
to work properly, and I was always stuck with their lame domain names as I’m
too cheap to pay for their serivces.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Luckily services of all kinds, including DNS Providers, have caught on to the
fact that people want API’s. If there’s an API to do DNS updates, I can script
a solution.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Some of my domains run off of &amp;lt;a href=&amp;quot;https://www.cloudflare.com/&amp;quot;&amp;gt;Cloudflare&amp;lt;/a&amp;gt; which needs to overwrite your DNS.
And, hey presto, they have an &amp;lt;a href=&amp;quot;http://www.cloudflare.com/docs/client-api.html&amp;quot;&amp;gt;API&amp;lt;/a&amp;gt;. So here it is:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-bash&amp;quot; data-lang=&amp;quot;bash&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;c&amp;quot;&amp;gt;#!/bin/bash&amp;lt;/span&amp;gt;
curl https://www.cloudflare.com/api_json.html &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'a=rec_edit'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'tkn=1234512345qweqwe1234512345'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'id=12345'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'email=jrgns@jrgns.net'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'z=jrgns.net'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'type=A'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'name=home'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;content=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'service_mode=0'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;se&amp;quot;&amp;gt;\&amp;lt;/span&amp;gt;
    -d &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'ttl=3600'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;Quick and dirty. This updates a domain (home.jrgns.net) with id 12345 with the
IP address that’s passed as the first argument to the script. There’s a bunch of
ways to get your external IP, my favourite is &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;curl http://api.externalip.net/ip&amp;lt;/code&amp;gt;,
but I just run this script as the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;postscript&amp;lt;/code&amp;gt; of my ddclient (which updates another
service)&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-text&amp;quot; data-lang=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;# /etc/ddclient.conf

protocol=dyndns2
use=web, web=myip.dnsomatic.com
ssl=yes
server=updates.someservice.com
login=mylogin@gmail.com
password='123456'
daemon=3600
postscript=/home/jrgns/bin/cloudflare_dynamic_dns.sh&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;I’m sure the same can be done with outer services such as Route 53? Has anyone
tried something like this?&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Setting a default order for Doctrine 2 / Symfony 2&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2.html&quot;/&gt;
   &lt;updated&gt;2013-09-17T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Usually when you’re working with data you expect some kind of default ordering.
It might be the primary key, or, more commonly, the data set will be ordered by
a timestamp field or the data’s most important property. In Doctrine you can create
&amp;lt;a href=&amp;quot;http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes&amp;quot;&amp;gt;custom repository classes&amp;lt;/a&amp;gt; to tweak queries to your liking:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// src/Acme/StoreBundle/Entity/ProductRepository.php
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;namespace&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Acme\StoreBundle\Entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Doctrine\ORM\EntityRepository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;class&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nc&amp;quot;&amp;gt;ProductRepository&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;extends&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;EntityRepository&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;findAllOrderedByName&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getEntityManager&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;createQuery&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
                &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'SELECT p FROM AcmeStoreBundle:Product p ORDER BY p.name ASC'&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getResult&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;This is all fine and dandy, but do you really want to repeat yourself everytime
you write a query for a model that will almost &amp;lt;strong&amp;gt;always&amp;lt;/strong&amp;gt; be ordered
by the same field? Or get caught out by calls to default repository methods that
&amp;lt;em&amp;gt;don’t&amp;lt;/em&amp;gt; use the ordering you like? No, you don’t. Enter this piece of code:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// src/Acme/StoreBundle/Entity/ProductRepository.php
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;namespace&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Acme\StoreBundle\Entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Doctrine\ORM\EntityRepository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;class&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nc&amp;quot;&amp;gt;ProductRepository&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;extends&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;EntityRepository&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;findBy&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$criteria&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$orderBy&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$limit&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$offset&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Default Ordering
&amp;lt;/span&amp;gt;        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$orderBy&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$orderBy&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;===&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;?&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'added'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'desc'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$orderBy&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

        &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Default Filtering
&amp;lt;/span&amp;gt;        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;array_key_exists&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'active'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$criteria&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;===&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;false&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$criteria&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'active'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;parent&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;findBy&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$criteria&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$orderBy&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$limit&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$offset&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;The &amp;lt;a href=&amp;quot;http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.EntityRepository.html#_findBy&amp;quot;&amp;gt;findBy&amp;lt;/a&amp;gt; method of the EntityRepository class is the method used by most
(if not all) of the the repository methods that fetch data. This includes &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;findBy&amp;lt;/code&amp;gt;
methods where you can specify an arbitrary column and value:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// find a group of products based on an arbitrary column value
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$products&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$repository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;findByPrice&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mf&amp;quot;&amp;gt;19.99&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;So to ensure a default ordering, we override this method and check if an orderBy
clause has been set. If not, set it to our default ordering — in this case by the
&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;added&amp;lt;/code&amp;gt; field, descending. For good measure we also add default filtering —
the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;active&amp;lt;/code&amp;gt; field needs to equal 1. Once that’s done, call the parent method
with the default values set.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Easy as π&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Pre-populating an Entity in a Symfony 2 Form&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/07/22/prepopulating-entity-in-symfony-2-form.html&quot;/&gt;
   &lt;updated&gt;2013-07-22T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/07/22/prepopulating-entity-in-symfony-2-form&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’ve been working on &amp;lt;a href=&amp;quot;http://www.teach-a-rific.com&amp;quot;&amp;gt;teach-a-rific.com&amp;lt;/a&amp;gt; in my spare time, and I’m learning a lot
about how &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/book/forms.html&amp;quot;&amp;gt;Symfony 2 Forms&amp;lt;/a&amp;gt; work. One thing I need to do a lot, is to show a
form with a &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/reference/forms/types/entity.html&amp;quot;&amp;gt;entity field&amp;lt;/a&amp;gt; pre-populated. In this situation you also don’t want
the user to be able to edit the field. This is how I did it.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;First, you need to retrieve the mapped entity, in this case a &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Student&amp;lt;/code&amp;gt;, and set it
in the entity which you’re creating a form for. In this case a &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;ContactDetail&amp;lt;/code&amp;gt;.
This all happens in the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;newAction&amp;lt;/code&amp;gt; method of the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;ContactDetailController&amp;lt;/code&amp;gt;.
Notice how I save the student ID in a session variable. More on this later.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//ContactDetailController::newAction
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$detail&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;ContactDetail&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$studentId&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$request&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;query&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'student_id'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getDoctrine&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getManager&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getRepository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'NotesNoteBundle:Student'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;find&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$studentId&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'session'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;set&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'contact_detail:create:student'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$studentId&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$detail&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setStudent&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$form&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;createForm&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;ContactDetailType&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(),&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$detail&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;On to the form. Quite simply, if the entity already has a &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Student&amp;lt;/code&amp;gt;, don’t add the
field for the student.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\Form\AbstractType&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\Form\FormBuilderInterface&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\OptionsResolver\OptionsResolverInterface&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;class&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nc&amp;quot;&amp;gt;ContactDetailType&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;extends&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;AbstractType&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;buildForm&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;FormBuilderInterface&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$builder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$options&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$builder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getData&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getStudent&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;===&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;kc&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$builder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;add&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'student'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$builder&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;add&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'type'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'choice'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'choices'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Email'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Email'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Cellphone'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Cellphone'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)))&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;add&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'content'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;On to the actual form. If the student field is defined in the form, display the
form widget. Otherwise display the student in an uneditable text input. Displaying
the student can be skipped if it’s not necessary.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;{% if form.student is defined %}
    {{ form_row(form.student, { form_type: 'horizontal' }) }}
{% elseif form.vars.data.student.id is defined %}
    &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;div&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;class=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;control-group&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;label&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;class=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;control-label&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;Student&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/label&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;div&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;class=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;controls&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;span&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;class=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;input uneditable-input&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;{{ form.vars.data.student }}&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/span&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/div&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/div&amp;amp;gt;&amp;lt;/span&amp;gt;
{% endif %}&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;And on to the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;updateAction&amp;lt;/code&amp;gt;. Just get the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Student&amp;lt;/code&amp;gt; whose ID we stored in the session,
and set it on the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;ContactDetail&amp;lt;/code&amp;gt; before populating the form:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//ContactDetailController::createAction
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt;  &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;ContactDetail&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$studentId&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'session'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'contact_detail:create:student'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getDoctrine&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getManager&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getRepository&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'NotesNoteBundle:Student'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;find&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$studentId&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setStudent&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$student&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;Simple enough. Any suggestions on how to improve it, or comments on how to do it
differently?&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;A Summary of Symfony 2 Authorization&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/04/29/summary-of-symfony-2-authorization.html&quot;/&gt;
   &lt;updated&gt;2013-04-29T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/04/29/summary-of-symfony-2-authorization&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Symfony 2 comes with a great &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/book/security.html&amp;quot;&amp;gt;security component&amp;lt;/a&amp;gt; that provides both &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/components/security/authentication.html&amp;quot;&amp;gt;Authentication&amp;lt;/a&amp;gt;
(identifying the user) and &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/components/security/authorization.html&amp;quot;&amp;gt;Authorization&amp;lt;/a&amp;gt; (determining the permissions for the user)
functionality. It has sane defaults, works out of the box, and is extendable enough
to cater for any scenario. This post describe the default authorization functionality
available to the developer.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Out of the box, Symfony 2 offers two method with which to authorize a user:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Role based authorization&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Access control lists (ACL’s)&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;h2 id=&amp;quot;role-based-authorization&amp;quot;&amp;gt;Role Based Authorization&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;With role based authorization, you specify a number of roles (which can be hierarchical)
and specify the access of these roles, all within your application config:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;#project/app/config/security.yml
security:
    role_hierarchy:
        ROLE_ANONYMOUS:
        ROLE_USER:        ROLE_ANONYMOUS
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_USER }
        - { path: ^/admin/, role: ROLE_ADMIN }
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;In the config above, there’s roles (or types of users). Anonymous, normal users, admin
users and super admin users. Anonymous users can only access the public part of the site.
Logged in users can access the whole site, except for the admin area. Admin users can access
the admin area of the site. Relatively simple and easy to set up, but not very customizable
on a fine grained level.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;access-control-lists&amp;quot;&amp;gt;Access Control Lists&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Say for instance that users generate content, and that users can only access the content
they generated. The role based rules are too general for this, so we’ll turn to Access Control
Lists for a solution.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The concept of ACL’s boils down to a list of many to many relations between users
and resources defining who has access to what. Even though Symfony provides built
in &amp;lt;a href=&amp;quot;http://symfony.com/doc/current/cookbook/security/acl.html&amp;quot;&amp;gt;ACL functionality&amp;lt;/a&amp;gt;, this can become hairy quite quickly, as you need to manage
Access Control Entries (ACE) in your controller code.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Although Symfony provides an &amp;lt;a href=&amp;quot;http://api.symfony.com/2.0/Symfony/Component/Security/Acl/Dbal/AclProvider.html&amp;quot;&amp;gt;ACL Provider&amp;lt;/a&amp;gt; with which the coder can create and
check ACL’s, it can become hairy quite quickly, as it needs to be managed in each and
every Controller Action.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This boilerplate code wil appear in controller actions that deal with creating Entities
and their ACL’s:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\Security\Acl\Domain\ObjectIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\Security\Acl\Domain\UserSecurityIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;use&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Symfony\Component\Security\Acl\Permission\MaskBuilder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Inside a controller action
&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// creating the ACL
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$aclProvider&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'security.acl.provider'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$objectIdentity&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;ObjectIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;fromDomainObject&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$entity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$acl&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$aclProvider&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;createAcl&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$objectIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// retrieving the security identity of the currently logged-in user
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$securityContext&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;get&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'security.context'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$user&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$securityContext&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getToken&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getUser&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$securityIdentity&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;UserSecurityIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;fromAccount&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$user&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// grant owner access
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$acl&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;insertObjectAce&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$securityIdentity&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;MaskBuilder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;MASK_OWNER&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$aclProvider&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;updateAcl&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$acl&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;The “creating the ACL” block retrieves the Security Provider, generates an identity
for the object using the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;ObjectIdentity&amp;lt;/code&amp;gt; class, and then creates the ACL using the
security provider.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The second block retrieves the Security Context and the current user. From there it
generates the an identifier for the user using the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;UserSecurityIdentity&amp;lt;/code&amp;gt; class.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The third block then inserts an Access Control Entry and updates the ACL.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;That’s a lot of code. If there’s a generic way to handle this, please let me know
in the comments.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;behind-the-scenes&amp;quot;&amp;gt;Behind the Scenes&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;The key component in how Symfony manages authentication is the &amp;lt;a href=&amp;quot;http://api.symfony.com/2.2/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.html&amp;quot;&amp;gt;AccessDecisionManager&amp;lt;/a&amp;gt;.
Each time a request is made, the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;AccessDecisionManager&amp;lt;/code&amp;gt; lets registered Voters vote on
if the user may access the resource. The voters will determine their vote by inspecting
the current security token, a set of attributes, and an optional object. Access will
then be granted (or denied) depending on the votes and the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;AccessDecisionManager's&amp;lt;/code&amp;gt;
decision strategy. Both the role based auth and ACL’s use this mechanism.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ll go into how to use the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;AccessDecisionManager&amp;lt;/code&amp;gt; and Voters in a later post.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;I'm the most Organized Disorganized person you'll meet&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet.html&quot;/&gt;
   &lt;updated&gt;2013-02-28T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;One of the most telling compliments I ever received was from a good friend: “You’re
the most organized, disorganized person I know!”. It’s quite telling once you wrap your
head around it. It stuck by me, and it’s helping me shape my career.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ve always been absent minded. Classic “if you’re head wasn’t tied to your body, you’ll
loose it!” stuff. I’d put something down, and then search for it for half an hour, only
to discover it’s been in my pocket the whole time. One time I was talking to my mom on
the phone, realised that I didn’t know where my phone was, and proceed to tell my mom
about it… At the end of the day, details just didn’t stick in my head.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Now I’m in an industry where detail is everything. Businesses lose thousands
because of a missing negative sign. One line of code out of place crashes an application
and loses a company users, money and its reputation. I always tell people that creating
systems is like eating an elephant: bit by bit. what they don’t realise is that if you
get one byte wrong, everything comes crashing down.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So how wise is it for a guy who can’t keep track of both his sandles to be in the details
business? Either very foolish, or a stroke of genius. Genius? Let’s look that compliment
again: The most &amp;lt;em&amp;gt;organized&amp;lt;/em&amp;gt; disorganized person. To cope with all these details, I
started to rely on systems. I organized my life in such a way that I didn’t need to
worry about the details.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Using systems ensures that even the most unorganized person won’t miss any of the details.
I used calandering to keep track of appointments. A todo list for tasks. Evernote for
easy to forget yet important info. When I go out the door I chant “Phone, keys, wallet”
to ensure that I have the essentials. Every day I’m hacking my brain.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The take away is that while people make mistakes, systems rarely do. Don’t rely
on people to take care of the details, rather put systems in place to take care it. If
it’s tricky or complicated to deploy an app, script it. If a process is long and protracted,
automate it. Create unit and behaviour tests for your code. Add state checks to the
application. Run regular audits on the numbers and make sure they balance.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;In the age of rapid development and continuous deployment, just writing your app isn’t
enough anymore. You need to write systems around your app to ensure that it is coded
correctly, deployed correctly, working correctly.&amp;lt;/p&amp;gt;
&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;PHP's array_merge_recursive function explained&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2013/01/08/php-array-merge-recursive-function-explained.html&quot;/&gt;
   &lt;updated&gt;2013-01-08T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2013/01/08/php-array-merge-recursive-function-explained&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Reading the PHP docs, it’s not immediately clear how the &amp;lt;a href=&amp;quot;http://php.net/manual/en/function.array-merge-recursive.php&amp;quot;&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;array_merge_recursive&amp;lt;/code&amp;gt;&amp;lt;/a&amp;gt; function behaves.
I’ve setup a couple of test cases and compared them with the plain &amp;lt;a href=&amp;quot;http://php.net/manual/en/function.array-merge.php&amp;quot;&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;array_merge&amp;lt;/code&amp;gt;&amp;lt;/a&amp;gt; function to explain it further:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The following snippet set’s up a couple of arrays, and outputs them for completeness sake.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$cats&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'white'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Kitty'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;),&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'brown'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Bach'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'mixed'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Tomcat'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$dogs&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'white'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Bowser'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'brown'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Rex'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'mixed'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Mutt'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;var_dump&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Cats'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$cats&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Dogs'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$dogs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;pre&amp;gt;&amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Cats'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
&amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
  'white' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; 
    &amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
      0 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Kitty'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=5)&amp;lt;/i&amp;gt;
  'brown' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Bach'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
  'mixed' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; 
    &amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
      0 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Tomcat'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=6)&amp;lt;/i&amp;gt;
&amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Dogs'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
&amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
  'white' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Bowser'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=6)&amp;lt;/i&amp;gt;
  'brown' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Rex'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=3)&amp;lt;/i&amp;gt;
  'mixed' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Mutt'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
&amp;lt;/pre&amp;gt;

&amp;lt;p&amp;gt;This snippet highlights what happens when the arrays being merged have matching keys.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;var_dump&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Cats and Dogs - plain'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;array_merge&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$cats&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$dogs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;));&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;var_dump&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Cats and Dogs - recursive'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;array_merge_recursive&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$cats&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$dogs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;));&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;All values that’s not already in an array will be placed in an array,
and merged with other values with the same keys. Arrays are left as they are and then merged.&amp;lt;/p&amp;gt;

&amp;lt;pre&amp;gt;
&amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
  'white' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; 
    &amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
      0 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Kitty'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=5)&amp;lt;/i&amp;gt;
      1 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Bowser'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=6)&amp;lt;/i&amp;gt;
  'brown' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; 
    &amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
      0 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Bach'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
      1 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Rex'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=3)&amp;lt;/i&amp;gt;
  'mixed' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; 
    &amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
      0 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Tomcat'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=6)&amp;lt;/i&amp;gt;
      1 &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Mutt'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
&amp;lt;/pre&amp;gt;

&amp;lt;p&amp;gt;Compare this with the normal &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;array_merge&amp;lt;/code&amp;gt; function, where the values of the latter arrays replace
all the values with the same key.&amp;lt;/p&amp;gt;

&amp;lt;pre&amp;gt;
&amp;lt;b&amp;gt;array&amp;lt;/b&amp;gt;
  'white' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Bowser'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=6)&amp;lt;/i&amp;gt;
  'brown' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Rex'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=3)&amp;lt;/i&amp;gt;
  'mixed' &amp;lt;font color=&amp;quot;#888a85&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;string&amp;lt;/small&amp;gt; &amp;lt;font color=&amp;quot;#cc0000&amp;quot;&amp;gt;'Mutt'&amp;lt;/font&amp;gt; &amp;lt;i&amp;gt;(length=4)&amp;lt;/i&amp;gt;
&amp;lt;/pre&amp;gt;

&amp;lt;p&amp;gt;Values with numerical keys get added to the original array with a renumbering of keys. This
is the same behaviour as that of &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;array_merge&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Setting up the Swiftmailer Spooler&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/blog/2012/12/20/setting-up-the-swiftmailer-spooler.html&quot;/&gt;
   &lt;updated&gt;2012-12-20T00:00:00+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/blog/2012/12/20/setting-up-the-swiftmailer-spooler&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;The &amp;lt;a href=&amp;quot;http://swiftmailer.org/&amp;quot;&amp;gt;Swiftmailer&amp;lt;/a&amp;gt; library comes with a nifty feature where mails can be spooled to disk
and sent later asynchronously instead of mailing them immediately. This results in quicker
response times from your scripts, and by extension happier users. This post will explain
how to set it up &amp;lt;em&amp;gt;outside&amp;lt;/em&amp;gt; of the Symfony 2 framework.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;spooling-the-mail&amp;quot;&amp;gt;Spooling the Mail&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Swiftmailer defines a number of Transports with which mails can be sent. A common one
is the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Swift_SmtpTransport&amp;lt;/code&amp;gt;. To spool mails, we’ll use the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Swift_SpoolTransport&amp;lt;/code&amp;gt; for
the initial sending, and then still use &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Swift_SmtpTransport&amp;lt;/code&amp;gt; for the background sending.
The following comes (with some changes) from a post in the &amp;lt;a href=&amp;quot;https://groups.google.com/forum/?fromgroups=#!searchin/swiftmailer/spool/swiftmailer/xQPP5qtNnMA/k3QXcRebG-wJ&amp;quot;&amp;gt;Swiftmailer Google Group&amp;lt;/a&amp;gt;:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Setup the spooler, passing it the name of the folder to spool to
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_FileSpool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;__DIR__&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;/spool&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Setup the transport and mailer
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$transport&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_SpoolTransport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;newInstance&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$mailer&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_Mailer&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;newInstance&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$transport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Create a message
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$message&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_Message&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;newInstance&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Excellent Subject'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setFrom&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'sende...@domain.com'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'John Doe'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setTo&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'your_emailAddress@domain.com'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setBody&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'spool messages !!!'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

 &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;// Send the message
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$result&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$mailer&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;send&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$message&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;SPOOLED &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$result&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt; emails&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;This will spool the email to specified folder instead of sending it. At this stage,
the actual sending of the mail hasn’t happened yet. You will need to flush the spooled
messages using a cron or background script that calls the flashQueue method to do that.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;sending-the-mail&amp;quot;&amp;gt;Sending the Mail&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;The background script will use the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Swift_SmtpTransport&amp;lt;/code&amp;gt; to send the spooled mails:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//create an instance of the spool object pointing to the right position in the filesystem
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_FileSpool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;__DIR__&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;/spool&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//create a new instance of Swift_SpoolTransport that accept an argument as Swift_FileSpool
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$transport&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_SpoolTransport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;newInstance&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//now create an instance of the transport you usually use with swiftmailer
//to send real-time email
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$realTransport&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Swift_SmtpTransport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;::&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;newInstance&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;smtp.gmail.com&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;465&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;ssl&amp;quot;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setUsername&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;username&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setPassword&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;password&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$transport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getSpool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setMessageLimit&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;10&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;setTimeLimit&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;100&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$sent&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$spool&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;flushQueue&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$realTransport&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;SENT &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$result&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt; emails&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;And that’s it. All that’s left now is to call the background script periodically using
something like cron.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Building PHP Projects with Jenkins&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/building-php-projects-with-jenkins/index.html&quot;/&gt;
   &lt;updated&gt;2012-06-09T18:46:23+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/building-php-projects-with-jenkins/building-php-projects-with-jenkins&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;It can become quite difficult to keep PHP code structured and clean. There’s a couple of good tools out there (&amp;lt;a href=&amp;quot;http://pear.php.net/package/PHP_CodeSniffer/redirected&amp;quot;&amp;gt;PHP Code Sniffer&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;http://phpmd.org/&amp;quot;&amp;gt;PHP Mess Detector&amp;lt;/a&amp;gt;, etc) to help you manage it, but it adds a lot of overhead that can bring your productivity down. One way to keep the advantage of checking your code without taking a productivity hit, is using a build system like Jenkins.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Look at &amp;lt;a href=&amp;quot;http://erichogue.ca/2011/05/php/continuous-integration-in-php/&amp;quot;&amp;gt;this blog post&amp;lt;/a&amp;gt; to setup Jenkins and the various tools. There’s also a &amp;lt;a href=&amp;quot;http://jenkins-php.org/&amp;quot;&amp;gt;Jenkins PHP Template&amp;lt;/a&amp;gt; that will help a great deal in getting things started.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’m planning to play around with it, and post updates here about how it goes.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Decorator Pattern Implemented Properly In PHP&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/decorator-pattern-implemented-properly-in-php/index.html&quot;/&gt;
   &lt;updated&gt;2012-03-17T11:14:56+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/decorator-pattern-implemented-properly-in-php/decorator-pattern-implemented-properly-in-php&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;While working on &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;Backend-PHP&amp;lt;/a&amp;gt; I needed to do a proper implementation of the &amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Decorator_pattern&amp;quot;&amp;gt;Decorator Pattern&amp;lt;/a&amp;gt; in PHP. Just googling PHP decorator pattern will come up with a number of simple solutions, but none of them are usable in a general, robust way that a framework requires. So I extended and tweaked the implementations a bit.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##TL;DR&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Most decorator pattern implementations for PHP found on the web is broken. They need some extra functionality to work properly, especially for nested decorators. See the complete solution in the &amp;lt;a href=&amp;quot;https://github.com/backend/Backend-PHP-Core/blob/master/Decorators/Decorator.php&amp;quot;&amp;gt;Backend-PHP code&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##The Basics&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’m assuming you know how decorators work. If not, read up on it first! I’ve implemented a base &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Decorator&amp;lt;/code&amp;gt; class to handle the base functionality for Decorators. The simple implementations out there serve as a good base for an initial implementation:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;class Decorator
{
    protected $object; //The object to decorate

    function __construct( $object)
    {
        $this-&amp;amp;gt;object = $object;
    }
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This is enough to get you started, but you will need to wrap the original object’s properties and methods manually. Let’s define a couple of magic functions to do that automatically:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;public function __call($method, $args)
    {
        if (is_callable($this-&amp;amp;gt;object, $method) {
            return call_user_func_array(array($this-&amp;amp;gt;object, $method), $args);
        }
        throw new Exception(
            'Undefined method - ' . get_class($this-&amp;amp;gt;object) . '::' . $method
        );
    }

    public function __get($property)
    {
        if (property_exists($this-&amp;amp;gt;object, $property)) {
            return $this-&amp;amp;gt;object-&amp;amp;gt;$property;
        }
        return null;
    }

    public function __set($property, $value)
    {
        $this-&amp;amp;gt;object-&amp;amp;gt;$property = $value;
        return $this;
    }
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;That should give you a working basic implementation.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##More Advanced&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;That will work as long as you don’t nest decorators, ie, decorate an already decorated object:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;$object = new DecoratorOne(new DecoratorTwo(new SomeClass()));
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;Why? The magic functions will check the decorated object for the properties and methods, but in the case of &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;DecoratorOne&amp;lt;/code&amp;gt; above, the decorated object will be another decorator, and you won’t get the expected behaviour. This happens because &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;property_exists&amp;lt;/code&amp;gt; doesn’t trigger the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;__get&amp;lt;/code&amp;gt; (or &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;__set&amp;lt;/code&amp;gt;) methods. &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;is_callable&amp;lt;/code&amp;gt; does check for the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;__call&amp;lt;/code&amp;gt; function, but that doesn’t necessarily produce the expected results, especially if you stack decorators that modify method execution.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;We solve this by adding two more functions:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###getOriginalObject&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;public function getOriginalObject()
{
    $object = $this-&amp;amp;gt;object;
    while ($object instanceof Decorator) {
        $object = $object-&amp;amp;gt;getOriginalObject();
    }
    return $object;
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;getOriginalObject&amp;lt;/code&amp;gt; will return the original, undecorated object. This is handy to get the correct class name or access to undecorated methods and properties:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;echo get_class($decoratedClass) //Will give the name of the Decorator

echo get_class($decoratedClass-&amp;amp;gt;getOriginalObject()) //Will give the name of the original object
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;###isCallable&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;public function isCallable($method, $checkSelf = false)
{
    //Check the original object
    $object = $this-&amp;amp;gt;getOriginalObject();
    if (is_callable(array($object, $method))) {
        return $object;
    }
    //Check Decorators
    $object = $checkSelf ? $this : $this-&amp;amp;gt;object;
    while ($object instanceof Decorator) {
        if (is_callable(array($object, $method))) {
            return $object;
        }
        $object = $this-&amp;amp;gt;object;
    }
    return false;
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;isCallable&amp;lt;/code&amp;gt; will check the original object for the specified method, and if not found, it will check the other decorators for the method. The option exists to check itself as well.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##The Result&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Now we can modify the magic functions like so:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;public function __call($method, $args)
{
    if ($object = $this-&amp;amp;gt;isCallable($method)) {
        return call_user_func_array(array($object, $method), $args);
    }
    throw new Exception(
        'Undefined method - ' . get_class($this-&amp;amp;gt;getOriginalObject()) . '::' . $method
    );
}

public function __get($property)
{
    $object = $this-&amp;amp;gt;getOriginalObject();
    if (property_exists($object, $property)) {
        return $object-&amp;amp;gt;$property;
    }
    return null;
}

public function __set($property, $value)
{
    $object = $this-&amp;amp;gt;getOriginalObject();
    $object-&amp;amp;gt;$property = $value;
    return $this;
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This will give you a robust Decorator Pattern implementation from which you can then create more Decorators. See the complete implementation in the &amp;lt;a href=&amp;quot;https://github.com/backend/Backend-PHP-Core/blob/master/Decorators/Decorator.php&amp;quot;&amp;gt;Backend-PHP code&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;The Low Hanging Fruit Of Testing&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/the-low-hanging-fruit-of-testing/index.html&quot;/&gt;
   &lt;updated&gt;2012-03-16T15:14:03+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/the-low-hanging-fruit-of-testing/the-low-hanging-fruit-of-testing&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’ve been getting more into Testing (specifically Unit Testing) the past few weeks, and although I’m still struggling to firstly get it right, and secondly see the long term benefits, I know that the quality of my code is already better. Let’s call it the low hanging fruit of Testing.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I find that I’m reordering and sometimes rewriting functions, and sometimes whole classes, because just the need to test it already shows some design flaws. A class with too many private methods, a function with no clear input / output, all of that shows up when you start to write tests.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The fact that I have to think of my code and classes in terms of an API requires that I make sure of what the purpose of a function is, and what it’s signature and return should look like. Because it’s difficult to test large, complex functions, I’m refactoring those into smaller, more modular functions.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So I’m spending more time with the code, making improvements as I read and think about the code. So yeah, I’m not utilizing the full power of testing yet (not to speak of Test Driven Development), but I’m already enjoying the fruits.&amp;lt;/p&amp;gt;
&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;json-encode'ing Private and Protected Properties&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/json-encode-ing-private-and-protected-properties/index.html&quot;/&gt;
   &lt;updated&gt;2012-02-24T06:51:15+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/json-encode-ing-private-and-protected-properties/json-encode-ing-private-and-protected-properties&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;When you &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;json_encode&amp;lt;/code&amp;gt; an object, it will ignore all protected and private properties if the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;json_encode&amp;lt;/code&amp;gt; isn’t called from within the object. Sometimes you want to output the protected and private properties of an object when you’re JSON encoding it. Here’s how to do it in an easy and elegant way:&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##The Problem&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The properties of an object &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;json_encode&amp;lt;/code&amp;gt; includes in it’s eventual output depends on the scope of the function call: If it’s from inside the object, it will include &amp;lt;strong&amp;gt;all&amp;lt;/strong&amp;gt; the properties, private and protected. If it’s from outside of the object, it will only include the public properties.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;class&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nc&amp;quot;&amp;gt;Tester&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$public&amp;lt;/span&amp;gt;       &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Public'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;protected&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$protected&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Protected'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;private&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$private&amp;lt;/span&amp;gt;     &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Private'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;foo&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;json_encode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$test&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Tester&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$test&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;foo&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;c1&amp;quot;&amp;gt;//Outputs {&amp;quot;public&amp;quot;:&amp;quot;Public&amp;quot;,&amp;quot;protected&amp;quot;:&amp;quot;Protected&amp;quot;,&amp;quot;private&amp;quot;:&amp;quot;Private&amp;quot;}
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;json_encode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$test&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;//&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;Outputs&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;public&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;:&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s2&amp;quot;&amp;gt;&amp;quot;Public&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;This isn’t necessarily the desired outcome. Sometimes you want more control over what is being included in the encoding function.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##The Solution&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The easiest way to solve this is to add a &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;_toJson&amp;lt;/code&amp;gt; function to your object, and call that instead of &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;json_encode&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;_toJson&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$properties&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;getProperties&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;     &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;StdClass&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;_class&amp;lt;/span&amp;gt;      &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;get_class&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;foreach&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$properties&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;as&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$name&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$value&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$name&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$value&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;json_encode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;getProperties&amp;lt;/code&amp;gt; function should return the properties you want to include in the encoding. At it’s simplest it can be&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;public&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;getProperties&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;get_object_vars&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$this&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;Then, to call it, just check if the function exists, otherwise just call json_encode:&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;method_exists&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'_toJson'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;?&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;_toJson&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;json_encode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$object&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;It’s relatively simple to do it as a Decorator as well, which will enable you to give this functionality to multiple classes without the need to duplicate the code. See how I did it in the &amp;lt;a href=&amp;quot;https://github.com/backend/Backend-PHP&amp;quot;&amp;gt;Backend-PHP&amp;lt;/a&amp;gt; framework.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Do you have a better way to do it? Say so in the comments.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;22seven.com - Folly, or Genius?&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/22seven-com-folly-or-genius/index.html&quot;/&gt;
   &lt;updated&gt;2012-01-28T08:37:06+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/22seven-com-folly-or-genius/22seven-com-folly-or-genius&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;##Promising Product&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Last week Christo Davel, founder of the now defunct &amp;lt;a href=&amp;quot;http://mg.co.za/article/2005-11-02-online-bank-20twenty-up-for-sale&amp;quot;&amp;gt;twenty20&amp;lt;/a&amp;gt; bank, released an online personal accounting service called &amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;http://22seven.com&amp;quot;&amp;gt;22seven.com&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;. It &amp;lt;a href=&amp;quot;http://www.itweb.co.za/index.php?option=com_content&amp;amp;amp;view=article&amp;amp;amp;id=50971:22seven-goes-live&amp;quot;&amp;gt;looked&amp;lt;/a&amp;gt; like a great product. Something I was looking for for quite a while: A simple online interface that automatically imports my transaction details, and reports on how much I’m spending on what.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I will never use it, though. Why? The app asks for your online banking login details.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##But…&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;In case you don’t know. This is “not a good thing”(tm). As &amp;lt;a href=&amp;quot;https://twitter.com/?tw_e=details&amp;amp;amp;tw_i=162563523292041216&amp;amp;amp;tw_p=tweetembed#!/MichaelJordaan/statuses/162563523292041216&amp;quot;&amp;gt;tweeted&amp;lt;/a&amp;gt; by Micheal Jordaan, CEO of FNB, you’re taking a big risk by doing so. Once you’ve given it to them, it’s out there, somewhere. Yes, they &amp;lt;a href=&amp;quot;https://www.22seven.com/security.html&amp;quot;&amp;gt;secure&amp;lt;/a&amp;gt; the information, but to use it, it needs to become readable at some point. If it can become readable, someone can steal it. From a dishonest employee, to a hacker that found his way on to their servers.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The question is, why did they decide to go the route of asking for a user’s banking login details? The banks have been struggling to educate users so that they don’t enter the online banking sites from any other place than the bank’s site, and that they &amp;lt;em&amp;gt;don’t&amp;lt;/em&amp;gt; give their login credentials to any third party. As far as I know, the South African banks will refund any money you lost because of online fraud, &amp;lt;strong&amp;gt;except&amp;lt;/strong&amp;gt; if they can prove that you gave your credentials to someone else. And this service is asking for it, wholesale.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##The Problem&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The problem is that this isn’t the only company that went this route. Sidpayment, a product from Setcom, gives merchants the ability to do online EFTs. The problem is that it’s a Java app that looks over the customer’s shoulder while he’s doing a once off payment through his internet banking. The opportunity for hacks and attacks abound. I’m sure both these knew the risks and were aware of the potential &amp;lt;a href=&amp;quot;http://memeburn.com/2012/01/new-startup-22seven-under-fire-from-banks/&amp;quot;&amp;gt;backlash&amp;lt;/a&amp;gt;, but why did they knowingly proceed with it?&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;There’s a simple answer: &amp;lt;strong&amp;gt;They had no choice&amp;lt;/strong&amp;gt;. The banks in South Africa are walled gardens, with all of &amp;lt;strong&amp;gt;your&amp;lt;/strong&amp;gt; information locked up in it. There’s no way to access it, except through their portals: the branch and online banking. Even FNB, who seems to be embracing newer technologies, doesn’t have anything that even looks like an API. All they have is an accounting app that looks like it was written by (no offence) accountants. So how are third party applications supposed to access a client’s transaction details?&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Is there even a need for third parties to access people’s transaction information? Of course there is! In a number of other countries you see &amp;lt;a href=&amp;quot;http://www.wesabe.com&amp;quot;&amp;gt;innovation&amp;lt;/a&amp;gt; in &amp;lt;a href=&amp;quot;http://mint.com&amp;quot;&amp;gt;personal finance&amp;lt;/a&amp;gt; because they have access to information. There’s a number of services that track your credit card and spending patterns. These services depend on (sometimes read-only) data they get from banks and financial institutions.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;##Come on, Banks!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If we are to see innovation and progress in personal accounting in South Africa, the banks need to lead the way by not walling everything off, but by giving accredited and approved third party developers and companies access to API’s. Perhaps 22seven.com’s play was to force the hand of the big banks, and not as stupid as it seems.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Setting up Puppet on Ubuntu 10.4&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/setting-up-puppet-on-ubuntu-10.4/index.html&quot;/&gt;
   &lt;updated&gt;2011-11-16T04:24:06+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/setting-up-puppet-on-ubuntu-10.4/setting-up-puppet-on-ubuntu-10.4&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’m trying to use puppet to setup standard dev and (eventually) production environments. As Ubuntu 10.4 is the current LTS release (at least until 12.4), I need to get puppet running on 10.4. The problem is that although the latest stable release for puppet is 2.7.6, puppet in the ubuntu repo is version 0.25.4. Here’s how to firstly set it up, and then upgrade it to the latest version.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;setup&amp;quot;&amp;gt;Setup&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;First install packages required by Puppet via aptitude&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;sudo apt-get update
sudo apt-get install irb libopenssl-ruby libreadline-ruby rdoc ri ruby ruby-dev
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;And then install puppet and puppet master, also through aptitude&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;sudo apt-get install puppet puppetmaster
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;You can skip install puppet if your working on the master machine, or skip puppetmaster if your working on a client. &amp;lt;em&amp;gt;I’ll be installing the client and the master on the same machine&amp;lt;/em&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You can then follow the following steps from &amp;lt;a href=&amp;quot;http://docs.puppetlabs.com/references/0.25.4/configuration.html&amp;quot;&amp;gt;the documentation&amp;lt;/a&amp;gt; to get the default setup going. &amp;lt;em&amp;gt;Run all commands as root&amp;lt;/em&amp;gt;:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;#Generate a default config file
puppetd --genconfig &amp;amp;gt; etc/puppet/puppet.conf
#Generate a default site manifest
puppetd --genmanifest &amp;amp;gt; etc/puppet/manifests/site.pp
#Add the puppet user and group
puppetd --mkusers
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;We also need to tell the client which server it should use as it’s master. Add the following line to &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;127.0.0.1 puppet&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Puppet uses the host name &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;puppet&amp;lt;/code&amp;gt; as the default master. You can change this by setting the server config value in &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;/etc/puppet/puppet.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You can then test your client setup by running&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;puppetd --test
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;h2 id=&amp;quot;cert-issues&amp;quot;&amp;gt;Cert Issues&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;At this point I ran into a stupid config issue, where the client complained bombed out with the following error:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;could not retrieve catalog from remote server: hostname was not match with the server certificate&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Despite the &amp;lt;a href=&amp;quot;http://projects.puppetlabs.com/issues/7224&amp;quot;&amp;gt;bad english and uninformative message&amp;lt;/a&amp;gt;, I eventually figured out that even though a puppet client by default uses the puppet hostname as its master, the name on the cert that was generated for the hostname isn’t puppet, but the current machine’s name. This mismatch causes the confusion, so either change the server config value, or regen the cert with hostname puppet. I just changed the config value to my machine’s name. This actually negates the need for the added line in &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;PHP Community in South Africa, lack thereof&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/php-community-in-south-africa-lack-thereof/index.html&quot;/&gt;
   &lt;updated&gt;2011-10-05T05:07:46+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/php-community-in-south-africa-lack-thereof/php-community-in-south-africa-lack-thereof&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I really like working with PHP. It’s a great language despite, a number of shortcomings, and I get to make a living out of writing PHP code. I also love to socialize, and the past few weeks I’ve been looking for a way to combine these two.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ve looked for conferences or get togethers that I can attend. I looked for online groups or chatrooms about PHP where South Africans gathered. But I couldn’t find any. Well, any active, constructive ones in any case.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I see that there’s an active &amp;lt;a href=&amp;quot;http://drupal.co.za&amp;quot;&amp;gt;Drupal&amp;lt;/a&amp;gt; community in and around Jo’burg, so I’ll try to attend some of their meetups.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Why Johnny Died (or, How I Finally Realised Why Singletons And Global Variables Are Bad)&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad/index.html&quot;/&gt;
   &lt;updated&gt;2011-09-28T04:06:19+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Johnny (an asthma sufferer and fictitious character) died yesterday. He got an asthma attack, but he could not find his inhaler, and sadly passed away. Usually his mother kept it for him and made sure he used it, but on the first day he ventured out alone, he got an asthma attack, realised that he didn’t have his inhaler with him, and died. What does this have to do with Singletons or Global variables? Read on…&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ve been struggling to get my head around why singletons and global variables are bad. Particularly in the context of unit testing. I’m &amp;lt;a href=&amp;quot;http://stackoverflow.com/questions/228590/what-is-the-best-method-for-getting-a-database-connection-object-into-a-function/228715#228715&amp;quot;&amp;gt;quite a fan&amp;lt;/a&amp;gt;
of a global static class that can manage certain resources for you. But if you just look around a bit, you’ll find a &amp;lt;a href=&amp;quot;http://www.webapper.com/blog/index.php/2008/01/23/evils-of-global-variables-when-unit-testing/&amp;quot;&amp;gt;few&amp;lt;/a&amp;gt; &amp;lt;a href=&amp;quot;http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html&amp;quot;&amp;gt;resources&amp;lt;/a&amp;gt; around the fact that they are a bad idea.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I read up quite a bit on why exactly globals and singletons are bad, but couldn’t find any convincing explanations. Until yesterday, when I read this &amp;lt;a href=&amp;quot;http://stackoverflow.com/questions/1020312/are-singletons-really-that-bad&amp;quot;&amp;gt;question&amp;lt;/a&amp;gt; and &amp;lt;a href=&amp;quot;http://stackoverflow.com/questions/1020312/are-singletons-really-that-bad/1020384#1020384&amp;quot;&amp;gt;answer&amp;lt;/a&amp;gt; on stackoverflow. Particularly&amp;lt;/p&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;every class can potentially depend on
a singleton, which means the class can
not be reused in other projects unless
we also reuse all our singletons&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;p&amp;gt;In other words, if you want your classes / objects to be modular and easily transportable and reusable in other code bases, you &amp;lt;strong&amp;gt;cannot&amp;lt;/strong&amp;gt; use global variables or singletons. To properly unit test, you need to use your class in a clean environment, with only it’s stated dependencies injected into it on creation. Otherwise there’s no guarantee that your tests will fail or succeed consistently. Doing this also promotes code reuse, as you know that the global state won’t be affected in some averse way.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;What does this have to do with Johnny? Look at him as an object of the class Human, who has a dependency on an Inhaler object. His mother is a global variable or class that supplies him with the Inhaler when he needs it. All fine and dandy if Johnny operates within the context of his mother’s home. Take him out of that context, and he dies when he needs the inhaler. Rather give him the inhaler, and let him keep it in his pocket. Dependency injected!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;A PHP Virtual Host&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/php-virtualhost/index.html&quot;/&gt;
   &lt;updated&gt;2011-09-13T03:18:03+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/php-virtualhost/php-virtualhost&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I hate repetitive work. I love solving a puzzle. So it often happens that I’d spend 2 hours writing a script to solve a repetitive problem, than just taking the 2 minutes to do it manually. Creating apache config files are tedious and boring, so I wrote a PHP script that emulates Virtual Hosting.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You can get the code on &amp;lt;a href=&amp;quot;https://github.com/jrgns/php-virtualhost&amp;quot;&amp;gt;GitHub&amp;lt;/a&amp;gt;. A &amp;lt;strong&amp;gt;Warning&amp;lt;/strong&amp;gt;: The code is &amp;lt;strong&amp;gt;not&amp;lt;/strong&amp;gt; production ready. Use it at your own risk. Here’s what it does:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;An &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;.htaccess&amp;lt;/code&amp;gt; file &amp;lt;a href=&amp;quot;?q=content/redirect_request_to_index&amp;quot;&amp;gt;redirects all requests&amp;lt;/a&amp;gt; to the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;index.php&amp;lt;/code&amp;gt; file, which sits in &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;/var/www&amp;lt;/code&amp;gt;. We get the host from the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;$_SERVER&amp;lt;/code&amp;gt; variable, and check if a folder for that host exists.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$host&amp;lt;/span&amp;gt;   &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$_SERVER&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'HTTP_HOST'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;];&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;getcwd&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'/'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$host&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'/'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;!&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;file_exists&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;no_host&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;die&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;So if we wanted to server jrgns.net from it, the folder &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;/var/www/jrgns.net&amp;lt;/code&amp;gt; should exist on the server. If it doesn’t, a generic message is displayed.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Courtesy of the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;.htaccess&amp;lt;/code&amp;gt; file, the whole URL, except the host name, gets passed to the script in the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;f&amp;lt;/code&amp;gt; query variable. As we might be requesting a stylesheet such as jrgns.net/styles/basic.css, the virtual host should pick that up. If no file is requested, check for and serve an index file.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;empty&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$_REQUEST&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'f'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;]))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$indexes&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;array&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'index.php'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'index.html'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'index.htm'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'main.php'&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;foreach&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$indexes&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;as&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$index&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;file_exists&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$index&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;chdir&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;include&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$index&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;die&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;else&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$file&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$_REQUEST&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'f'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;];&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;file_exists&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$file&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$info&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;explode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'.'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$file&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;switch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;end&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$info&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;))&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;case&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'js'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;:&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;header&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Content-Type: text/javascript'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;break&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;case&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'css'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;:&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;header&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'Content-Type: text/css'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;break&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nb&amp;quot;&amp;gt;readfile&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$folder&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$file&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;die&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;I use a very rudimentary way to get the file extension, and then send the content header. There are probably better ways to do this, but it works. The rest is just the generic message that gets displayed if we don’t know what you’re looking for.&amp;lt;/p&amp;gt;

&amp;lt;figure class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;language-php&amp;quot; data-lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;table style=&amp;quot;border-spacing: 0&amp;quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;gutter gl&amp;quot; style=&amp;quot;text-align: right&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;lineno&amp;quot;&amp;gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;    &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;no_host&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    	&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;global&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$host&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;amp;lt;!DOCTYPE html&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;html&amp;amp;gt;&amp;lt;/span&amp;gt;
    	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;head&amp;amp;gt;&amp;lt;/span&amp;gt;
    		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;title&amp;amp;gt;&amp;lt;/span&amp;gt;Unknown Domain: &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$host&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/title&amp;amp;gt;&amp;lt;/span&amp;gt;
    	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/head&amp;amp;gt;&amp;lt;/span&amp;gt;
    	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;body&amp;amp;gt;&amp;lt;/span&amp;gt;
    		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;div&amp;amp;gt;&amp;lt;/span&amp;gt;
    			&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;h1&amp;amp;gt;&amp;lt;/span&amp;gt;Unknown Domain: &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nv&amp;quot;&amp;gt;$host&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/h1&amp;amp;gt;&amp;lt;/span&amp;gt;
    		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/div&amp;amp;gt;&amp;lt;/span&amp;gt;
    	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/body&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/html&amp;amp;gt;&amp;lt;/span&amp;gt;
    
    &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;no_host&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;?&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;w&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/figure&amp;gt;

&amp;lt;p&amp;gt;Like I said. Simple!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;A JavaScript trim function&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/js-trim/index.html&quot;/&gt;
   &lt;updated&gt;2011-07-18T04:55:32+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/js-trim/js-trim&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;A simple enough &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;trim&amp;lt;/code&amp;gt; function for JavaScript:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;function trim(string) {
    return string.replace(/^\s*|\s*$/g, '')
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;!--break--&amp;gt;

&amp;lt;p&amp;gt;The regular expression translates as&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;^&amp;lt;/code&amp;gt; - At the beginning of the line&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;\s*&amp;lt;/code&amp;gt; - Take all the white space you can find, if there is any&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;|&amp;lt;/code&amp;gt; - OR&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;\s*&amp;lt;/code&amp;gt; - Take all the white space you can find, if there is any&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;$&amp;lt;/code&amp;gt; - At the end of the line&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;g&amp;lt;/code&amp;gt; parameter at the end ensures that all instances are replaced.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The replace function uses the regular expressions to replace the white space it found at the beginning or the end of the string with an empty string.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Easy enough!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Quick Guide To Creating A Website Quickly&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/quick_guide_to_creating_a_website_quickly/index.html&quot;/&gt;
   &lt;updated&gt;2011-07-11T21:31:53+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/quick_guide_to_creating_a_website_quickly/quick_guide_to_creating_a_website_quickly&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;The last two weeks I had the privilege of staying in a house on the beach near Mosselbay. This time of the year whales start coming into the bay, and, if you’re lucky, you can spot them breaching or displaying their flukes or fins. This inspired me to create &amp;lt;a href=&amp;quot;http://whalespotter.co.za&amp;quot;&amp;gt;WhaleSpotter&amp;lt;/a&amp;gt;, a site that uses Twitter to help people spot whales along South Africa’s south coast. It took me less than 2 hours to do it. Here’s how.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Know &amp;lt;em&amp;gt;exactly&amp;lt;/em&amp;gt; what you want to Do&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This speaks for it self. Spend a few minutes to lay out what you want, and how you want to achieve it. If you need to write it down, explain it to someone or whiteboard it, do it. This will save a lot of time later in the process, as you won’t track back or waste time with features or ideas that doesn’t fit.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Keep it Simple&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Keep the number of features down to a minimum. If you can fit everything on one page, do. This is quick and dirty, not long and elaborate. You can expand it later. Your aim now is to get something up and running.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Know and use your Tools&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Frameworks cut down a lot in development time. They provide functionality and structure so that you don’t have to work on it. I dev’ed my own MVC framework, &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;Backend&amp;lt;/a&amp;gt;, so I used that. It provides a nice templating system, along with basic configuration, caching and utility functions. Use what ever you’re comfortable with, as long as it reduces the work you have to do, not increase it.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Use Resources wisely&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Other resources can also cut down on time taken to get your site up. I used &amp;lt;a href=&amp;quot;http://images.google.com&amp;quot;&amp;gt;Google Images&amp;lt;/a&amp;gt; to get a logo. Look at &amp;lt;a href=&amp;quot;http://themeforest.net/&amp;quot;&amp;gt;Themeforest&amp;lt;/a&amp;gt; for a design that will work for your site. Copy and paste code from your own projects or open source projects on the web. The site was in part inspired by &amp;lt;a href=&amp;quot;http://replaceawordinafamousquotewithduck.com/&amp;quot;&amp;gt;http://replaceawordinafamousquotewithduck.com/&amp;lt;/a&amp;gt;, and I copied some of the twitter parsing code from the &amp;lt;a href=&amp;quot;https://github.com/duckduckgo/replaceawordinafamousquotewithduck&amp;quot;&amp;gt;GitHub repo&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###So&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Know where you’re going. Keep it simple. Know your tools and options. Outsource as much as possible.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Good Developers Think like a Startup&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/good_developers_think_like_a_startup/index.html&quot;/&gt;
   &lt;updated&gt;2011-05-05T08:25:54+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/good_developers_think_like_a_startup/good_developers_think_like_a_startup&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I have the privilege to be the Head of Development of &amp;lt;a href=&amp;quot;http://www.brandedinternet.co.za&amp;quot;&amp;gt;Branded Internet&amp;lt;/a&amp;gt;, a white label ISP in South Africa. I also like to read and think about how startups work, and what they do to make them successful. As I see it, the basic recipe  for a startup is:&amp;lt;/p&amp;gt;

&amp;lt;ol&amp;gt;
  &amp;lt;li&amp;gt;Find a niche market or problem&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Find a revolutionary / novel way to solve that problem&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Build the solution&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Market it&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;See the money roll in.&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;

&amp;lt;p&amp;gt;If you see the company you’re developing for as your client or target market, software development follows basically the same recipe.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;find-a-problem&amp;quot;&amp;gt;Find a problem&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;Usually people come to the developers of a company with a problem. &amp;lt;em&amp;gt;I need App X to do Y and Z&amp;lt;/em&amp;gt;. &amp;lt;em&amp;gt;App C doesn’t do D correctly&amp;lt;/em&amp;gt;. I’m not very good at spotting problems that are potentially money making, so I’m quite happy to be a developer where people come to me looking for solutions. That’s the first step sorted.&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;find-a-way-to-solve-the-problem&amp;quot;&amp;gt;Find a way to solve the problem&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;http://lorempixum.com/200/300/abstract/&amp;quot; style=&amp;quot;float: right;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Startups depend on the fact that they solve previously unsolved problems, or they solve problems in such a way that people want to throw money their way for the privilege to use the startup’s solution. I suspect that this may just be one of the reasons why developers at bigger companies don’t necessarily produce quality code: There’s no incentive to do it quickly, elegantly or intelligently. Just get it done. If it takes you three times longer than projected with a code base larger than the Kalahari, who cares. It’s done, and you got your salary at the end of the month.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If a startup thinks like that, it’s dead in the water.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Solving problems better is always better. Yes, there’s major time and money constraints on most developers, and elegance isn’t always achievable, but good developers should always be open to solve problems in a novel way. Don’t be a mill churning out code, be a creator of great code!&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;build-the-solution&amp;quot;&amp;gt;Build the Solution&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;Do what you do. Be a thinker, then a typist. And do it well.&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;market-it&amp;quot;&amp;gt;Market it&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;Having built the solution is not where it stops. For most developers, it’s where they wished it stopped, because, let’s face it, if we liked speaking to people, we wouldn’t have become developers. But unfortunately you as a developer need to take it further. You need to market what you’ve done. A product that no one knows or knows how to use doesn’t exist.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You need to tell your superior and your peers about the fact that the project is up and running.
You need to document the code and the use cases so that other developers (including your future self) knows what’s going on.
You need to train your clients (the users) who originally requested your help on using the project.
You need to get feedback from your clients on if this solves their problem, and go back to the code if it doesn’t.&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;reap-the-rewards&amp;quot;&amp;gt;Reap the Rewards&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;I find it immensely rewarding to be able to solve problems for people. Yes, the salary is great, but there’s times that I will literally code for free. Not just because I like solving problems, but because I know that I can make someone’s work day less frustrating. You get the gold and the golden glow.&amp;lt;/p&amp;gt;

&amp;lt;h3 id=&amp;quot;tldr&amp;quot;&amp;gt;tl;dr&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;By thinking or your rote work in terms of a startup, where you need to be agile and more than just a normal developer, going out of your comfort zone and speaking to people, your average work can become great work, and your worth will be measured in more than just a salary check.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Why Object Orientation is Great&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/why_oo_is_great/index.html&quot;/&gt;
   &lt;updated&gt;2011-02-08T07:00:21+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/why_oo_is_great/why_oo_is_great&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’m working on some statistics surrounding &amp;lt;a href=&amp;quot;http://www.brandedinternet.co.za&amp;quot;&amp;gt;BI’s&amp;lt;/a&amp;gt; API Documentation coverage: Just how much user documentation have we written?&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;When I started out, the number was abysmally low: 11% of the 1300 functions. Not good. But I didn’t feel too bad when I realized that because it’s written as an Object Orientated system, I can very quickly improve the coverage.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;As I went through the undocumented functions, it became clear that a lot of them are defined in some of our base classes. So, by documenting them in the base classes, I will immediately improve the documentation coverage for a whole bunch of classes. I tried it with one function, and lo and behold, the percentage jumped with 6 points!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So, what do we learn from this? Object orientation is powerful when you implement changes deep down in the object stack, as it propagates through the whole stack. It also reduces the work load (most of the time) as there’s no need to repeat yourself.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The downside to consider is that the documentation written is very general (as it should be in a base class), and will probably be overwritten in some of the sub classes.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;But that’s Object Orientation: Solve 80% of the problem with 20% of the code, and the other 20% of the problem with the other 80% of the code!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Getting Started with node.js&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/getting_started_with_node_js/index.html&quot;/&gt;
   &lt;updated&gt;2010-10-11T06:31:40+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/getting_started_with_node_js/getting_started_with_node_js&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Looking for a new challenge, I started a small project in node.js. Here’s a few simple tips on how to get going quickly.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;its-javascipt&amp;quot;&amp;gt;It’s JavaScipt&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Yeah, that’s obvious, but sometimes stating the obvious is necessary. Node.js is essentially server side JavaScript. This means that all your JS knowledge and tutorials and manuals will be usefull once you get stuck.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;its-event-driven&amp;quot;&amp;gt;It’s Event Driven&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Node.js is an event driven framework, which can take some getting used to, but it is very powerful in the long run. You can write straight forward bottom to top code, but then you’ll be missing out on the real power of node.js. An example:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;//Get the events module
var   events = require('events')
    , fs     = require('fs');

//Create a new event object
var file_emitter = new events.EventEmitter();

//Create a listener for our event object
var newFileListener = file_emitter.on('found', function(file) {
    //Do something to the found file
}

//Check for files in a folder
var files = fs.readdirSync('/some/folder');
files.forEach(function(file) {
	//Emit (Trigger) the &amp;quot;found&amp;quot; event on our event object
	file_emitter.emit('found', dest);
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;h2 id=&amp;quot;multiple-files&amp;quot;&amp;gt;Multiple Files&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Any good coder knows that putting your code in multiple files is a quick win for organized coded. Here’s how to do it in node.js:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;//In utils.js
exports.trim = trim;
function trim(string) {
	return string.replace(/^\s*|\s*$/g, '')
}

//In the file you want to use the trim function
var utils = require('./utils')
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;.js&amp;lt;/code&amp;gt; part of the file is automatically added/detected. This is to include a file in the same folder as the calling file, but you can easily just add the correct path traversals to get to other files. The important part in the file being included is setting the function name in the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;exports&amp;lt;/code&amp;gt; Object.&amp;lt;/p&amp;gt;

&amp;lt;h2 id=&amp;quot;file-io&amp;quot;&amp;gt;File I/O&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Files are all treated as streams in node.js. This means that you can start acting on the data in a file before node has even finished reading the file.&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;//Open a file as a Readable stream
stream = fs.ReadStream(file);
stream.setEncoding('ascii');
stream.on('data', function(data) {
    //Do something to the file's data mid stream
});
stream.on('close', function () {
    //Do something to the file once it's finished reading
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;Writing to a file is just as simple&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;stream = fs.createWriteStream(filename, { 'encoding': 'base64' });
stream.write(data);
stream.end();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;h2 id=&amp;quot;want-more&amp;quot;&amp;gt;Want More?&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;See &amp;lt;a href=&amp;quot;http://github.com/jrgns/parser_email&amp;quot;&amp;gt;parser_email on github&amp;lt;/a&amp;gt; for the full source of the examples given.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Some useful sites:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;
    &amp;lt;table&amp;gt;
      &amp;lt;tbody&amp;gt;
        &amp;lt;tr&amp;gt;
          &amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://nodejs.org/&amp;quot;&amp;gt;Official Site&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
          &amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://nodejs.org/api.html&amp;quot;&amp;gt;Documentation&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
          &amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://github.com/ry/node&amp;quot;&amp;gt;Source&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
      &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;
  &amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb&amp;quot;&amp;gt;Understanding node.js&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;http://howtonode.org/&amp;quot;&amp;gt;How to Node&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Email Parser for node.js&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/node_parser_email/index.html&quot;/&gt;
   &lt;updated&gt;2010-10-07T09:53:55+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/node_parser_email/node_parser_email&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I need to parse Emails in node.js and after looking around on the web, I didn’t find much. Oh, no, I’ll have to write it myself… :)&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The source is hosted on &amp;lt;a href=&amp;quot;http://github.com/jrgns/parser_email&amp;quot;&amp;gt;GitHub&amp;lt;/a&amp;gt; .&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Here’s an example:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;var   fs        = require('fs')
    , sys       = require('sys')
    , em_parse  = require('./parser_email')

stream = fs.ReadStream(file);
stream.setEncoding('ascii');
stream.on('data', function(data) {
	mail += data;
});
stream.on('close', function () {
	parser = em_parse.parser_email();
	parser.setContent(mail);
	parser.parseMail();
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Why I Code&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/why_i_code/index.html&quot;/&gt;
   &lt;updated&gt;2010-04-15T08:56:23+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/why_i_code/why_i_code&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;A a student I went to a career psychologist to explore my career needs and drives, and got told that I like solving problems in a creative way. As the son of an engineer and a very artsy mother, that kind of made sense. Seeing as I was already into computers and programming, I chose coding as my problem solving mechanism.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Through the years I learned that I loved, never mind liked, solving problems this way. I wrote a &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;framework&amp;lt;/a&amp;gt;, because I saw a lot of unstructured and repetitive code in my projects. I dev’ed &amp;lt;a href=&amp;quot;http://whatsupinmelville.co.za&amp;quot;&amp;gt;What’s up in Melville&amp;lt;/a&amp;gt; because I needed information about the area I lived in. I saw &amp;lt;a href=&amp;quot;http://news.ycombinator.com&amp;quot;&amp;gt;Hacker News&amp;lt;/a&amp;gt;, and wanted the same site, but for South Africa, so I dev’ed &amp;lt;a href=&amp;quot;http://zacoders.net&amp;quot;&amp;gt;ZA Coders&amp;lt;/a&amp;gt;. All (hopefully) creative solutions to problems I faced.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I am now Head of Development at &amp;lt;a href=&amp;quot;http://www.brandedinternet.co.za&amp;quot;&amp;gt;Branded Internet&amp;lt;/a&amp;gt;, and I’m still very passionate about solving problems through code. Any dev department at a company whose main aim is not to produce software, is to help the rest of the company to solve their problems through code. Finances needs to regularly generate a certain report, Dev scripts the code, and gives them the link. Support needs to information on an account, Dev scripts the code, and gives them the link.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Sometimes Dev departments will write code to help themselves, but most of the work will be done for other departments. So the Dev department needs to communicate, needs to interact, so that they know which problems to solve to help the other departments do their job.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Development departments exists to help other departments. In other words, it’s not about me.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Twitter API Request Entity too large / HTTP 413 error&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/twitter_api_request_entity_too_large_http_413_error/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-30T07:12:09+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/twitter_api_request_entity_too_large_http_413_error/twitter_api_request_entity_too_large_http_413_error&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’ve setup &amp;lt;a href=&amp;quot;http://zacoders.net&amp;quot;&amp;gt;zacoders.net&amp;lt;/a&amp;gt; that it will automatically tweet new RFC’s. A while back this functionality stopped working. Today I investigated a bit further, and here’s what I found.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;When posting an update, the Twitter API responded with a 413 HTTP error code, and the following text:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;Request Entity Too Large

The requested resource

/1/statuses/update.json

does not allow request data with POST requests,
or the amount of data provided in the request
exceeds the capacity limit.
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;I realized that the &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;backend&amp;lt;/a&amp;gt;’s OAuth utility sent through POST requests with the parameters included in the URI, just like a GET request:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;POST HTTP/1.1 http://api.twitter.com/1/statuses/update.json?parameters=here&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;What baffled me is that I only got this error when running it on my live server, not on my testing local server. I suspect it might be a difference in the Curl libraries, but I’m not sure.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;To fix it, I just updated the code to only add the parameters to the URI when it was a GET, and to POST the data when it was a POST, and voila, it’s working again.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;How to remove the www from your URL&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/remove_www_from_url/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-26T08:03:29+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/remove_www_from_url/remove_www_from_url&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;If you like simplicity, you might like to simplify your website’s URL. You can do this by adding the following in your &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;.htaccess&amp;lt;/code&amp;gt; file, or in the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;VirtualHost&amp;lt;/code&amp;gt; declaration on your Apache setup.&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.mysite.co.za$ [NC]
RewriteRule ^(.*)$ http://mysite.co.za/$1 [L,R=301]
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;The rewrite module for apache needs to be installed for this to work.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Remember that you can tell Google to list all links to your site with / without the www by setting that in the &amp;lt;a href=&amp;quot;http://www.google.com/webmasters/tools/&amp;quot;&amp;gt;Webmaster Tools&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;New look!&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/new_look/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-24T23:05:40+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/new_look/new_look&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;At long last I’ve been able to find the time to port my website from drupal to &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;backend&amp;lt;/a&amp;gt;. Backend is a PHP framework I wrote myself and open sourced to get it out there.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ve also redesigned the site, made it simpler and hopefully more usable. I’ll be adding more information as I go along.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;SQLite Viewer&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/sqllite_view/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:28:30+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/sqllite_view/sqllite_view&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’m playing around with &amp;lt;a href=&amp;quot;http://developers.google.com/gears/&amp;quot;&amp;gt;Google Gears&amp;lt;/a&amp;gt;, doing data imports, and generally playing around. I’m quite visiually oriented, so I need to SEE that the data has been added to a table. For my conventional PHP / MySQL apps, I usually use phpMyAdmin or the MySQL query browser, but for Gears developmen, which uses SQLite, I needed to use something else.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I wrote a small JavaScript / Gears app which enables you to view the contents of a SQLite database. All you need to use it, is to download the file, and unzip it into the folder where your web app sits. And no, you won’t be able to use it for a remote DB. You need at least FTP access to the website you want to look at, and it will only show you your local data.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You will also need to know the name of the database. At the moment I can see no simple way to supply the user with a listing of DB’s, so the app prompts the user for the DB name.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The app currently links to the scripts and styles on my host, which is fine for light use. If you plan to use this app extensively, please start hosting the files on your own host and update the HTML!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Update On Backend&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/Update on Backend/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:23:37+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/Update on Backend/Update on Backend&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Bakend: PHP framework, as it’s now called, now has it’s own website! Check it out at &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;http://backend-php.net&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Follow backend on Twitter at &amp;lt;a href=&amp;quot;http://twitter.com/backend_php&amp;quot;&amp;gt;@backend_php&amp;lt;/a&amp;gt;!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Backend 100 Revisions&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/backend_100_revisions/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:20:29+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/backend_100_revisions/backend_100_revisions&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’ve been working on &amp;lt;a href=&amp;quot;http://backend-php.net&amp;quot;&amp;gt;backend&amp;lt;/a&amp;gt;, a PHP framework the last couple of months, and it’s really starting to take shape. I’ve learned a lot about what one can do by coding smarter and the advantages open source code gives on.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;After getting somewhat disheartened a few weeks back, I decided to take a look at how &amp;lt;a href=&amp;quot;http://codeigniter.com/&amp;quot;&amp;gt;CodeIgnitir&amp;lt;/a&amp;gt; does things, and wow, it blew my mind. After spending some time with their code base, I had so many ideas I wanted to implement in backend and my thoughts around it was instantly rejuvinated. Problems that stopped me from progressing had new solutions, and the momentum I gathered from that helped to solve some problems that didn’t have any solutions directly at hand.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So, backend just hit it’s 100th revision, somewhat arbitrarily, as I reset the branch at some point, and don’t always follow the exact same commit methodology, but hey, it looks like a milestone, I’ll treat it as one.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;What has changed?&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;URL mapping has improved a lot (thanks to CodeIgnitir). &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;?q=controller/action/param1/param2&amp;lt;/code&amp;gt; now maps to &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;Controller::action(param1, param2)&amp;lt;/code&amp;gt; without much effort. This has also helped to work towards being a RESTful API.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The installation process is now very smooth and stable. The setting up of data sources need some work, but once that is done, getting the application up and running and fine tuning it is a breeze.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The beginning of a Links structure with named link lists can be managed. The primary use will be for primary and secondary links for a website.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ve managed to implement tags for content, as well as RSS feeds for content as a whole, or content in a tag. The ease with which I could do it really gives me hope that backend will make my coding life easier!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;All around polish and stability. Especially around the HTML templating  and rendering engine.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Where to from here?&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The permissions / security infrastructure still needs some work. I’ve managed to automatically install most of the default permissions, but there’s no useful management interface yet.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I want to start using backend on my personal site (this one) and on another site I’ve got in the works, called &amp;lt;a href=&amp;quot;http://zacoders.net&amp;quot;&amp;gt;zacoders.net&amp;lt;/a&amp;gt;. More on that later.&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;My take on single or multiple returns&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/my_take_on_single_or_multiple_returns/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:17:11+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/my_take_on_single_or_multiple_returns/my_take_on_single_or_multiple_returns&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;Originally posted on &amp;lt;a href=&amp;quot;http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement/1276951#1276951&amp;quot;&amp;gt;StackOverflow&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I force myself to use only one return statement, as it will in a sense generate code smell. Let me explain:&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?php
function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if ($param1 != $param2) {
        if ($param1 == ($param3 * 2)) {
            if ($param2 == ($param3 / 3)) {
                $toret = true;
            } else {
                $error = 'Error 3';
            }
        } else {
            $error = 'Error 2';
        }
    } else {
        $error = 'Error 1';
    }
    return $toret;
}
?&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;(The conditions are arbritary…)&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The more conditions, the larger the function gets, the more difficult it is to read. So if you’re attuned to the code smell, you’ll realise it, and want to refactor the code. Two possible solutions are:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Multiple returns&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Refactoring into separate functions&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Multiple Returns&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?php
function isCorrect($param1, $param2, $param3) {
    if ($param1 == $param2)       { $error = 'Error 1'; return false; }
    if ($param1 != ($param3 * 2)) { $error = 'Error 2'; return false; }
    if ($param2 != ($param3 / 3)) { $error = 'Error 3'; return false; }
    return true;
}
?&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Separate Functions&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?php
function isEqual($param1, $param2) {
    return $param1 == $param2;
}

function isDouble($param1, $param2) {
    return $param1 == ($param2 * 2);
}

function isThird($param1, $param2) {
    return $param1 == ($param2 / 3);
}

function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if (!isEqual($param1, $param2)
        &amp;amp;amp;&amp;amp;amp; isDouble($param1, $param3)
        &amp;amp;amp;&amp;amp;amp; isThird($param2, $param3)
    ) {
        $toret = true;
    }
    return $toret;
}
?&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;Granted, it is longer and a bit messy, but in the process of refactoring the function this way, we’ve&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;created a number of reusable functions,&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;made the function more human readable, and&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;
    &amp;lt;p&amp;gt;the focus of the functions is on why the values are correct.&amp;lt;/p&amp;gt;

  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Firefox requests a page twice?&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/firefox_requests_a_page_twice/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:13:43+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/firefox_requests_a_page_twice/firefox_requests_a_page_twice&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’m busy creating a site for a client who wants to know when certain internal links get clicked. Not a problem, I just insert a record into a table every time the links they want to know about get accesesd. Only problem is, when I check the table, I notice that every page impression gets logged twice.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Now, this happened before, where I also needed to implement some page tracking, and it ended up being an image or something with src=””, and Firefox interpreting it as the same location as the current page (as with form with action=””). Don’t know if that is according to standards, either way, it messes up my page tracking.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The simple solution is to find any images or HTML elements with source attributes that are empty. Only problem is I couldn’t find any this time. So, by taking out chunks of code, I eventually tracked it to srcover attributes in some of the images. Just as a side note, I don’t use srcover, the designers use them, and unfortunately I must make do with what the designers give me.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;So why does Firefox (I didn’t test on other browser) do this on srcover? Firebug shows that the images specified in srcover are downloaded, and the mouseovers work, so it’s not that the images are missing or anything.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ll investigate when I have some time, and report back…&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Update:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I found this page at &amp;lt;a href=&amp;quot;http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/PHP_Databases/Q_23101341.html&amp;quot;&amp;gt;Experts Exchange&amp;lt;/a&amp;gt;, but hey, they want me to pay to see it. No chance of that happening. If anyone is a member, and you don’t want money to share some wisdom, please do!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Update number two:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I fount &amp;lt;a href=&amp;quot;http://forums.mozillazine.org/viewtopic.php?p=3022038&amp;quot;&amp;gt;this page&amp;lt;/a&amp;gt; which only talks about the empty src tag, but it also quotes the HTML spec that says that empty src tags refer to the same page their in. So why does srcover still re-request my page?&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Update number final:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Ok, so it wasn’t Firefox’s fault, but the javascript that did the rollover images. When it preloades, it doesn’t check for empty src attributes, it just loads them. As it checks for both srcover and srcdown, which aren’t necessarily specified, it gets quite a lot of empty tags. I guess that Firefox uses a cached page for the rest of the requests.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The javascript library is called imagerollover.js by Adam Smith. I couldn’t find a working website, so I don’t know if I have the latest version, but I’ll upload my modified version…&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Parse Http Accept Header&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/parse_http_accept_header/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T16:10:35+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/parse_http_accept_header/parse_http_accept_header&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I want to generate CSS on the fly for a personal project. I’m doing this by redirect all requests for files that does not exist to index.php, and then, if the request is for a stylesheet, index.php generates it.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;To identify a request for a stylesheet, we need to parse the Accept header in the HTTP Request. I’ve grouped all the functions together in a Parser class.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This function retrieves the header, and then determines the mime type, precedence, and tokens for each type given. It’s then sorted according to &amp;lt;a href=&amp;quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&amp;quot;&amp;gt;RFC 2616&amp;lt;/a&amp;gt; specifications.&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?php
public static function accept_header($header = false) {
	$toret = null;
	$header = $header ? $header : (array_key_exists('HTTP_ACCEPT', $_SERVER) ? $_SERVER['HTTP_ACCEPT']: false);
	if ($header) {
		$types = explode(',', $header);
		$types = array_map('trim', $types);
		foreach ($types as $one_type) {
			$one_type = explode(';', $one_type);
			$type = array_shift($one_type);
			if ($type) {
				list($precedence, $tokens) = self::accept_header_options($one_type);
				list($main_type, $sub_type) = array_map('trim', explode('/', $type));
				$toret[] = array('main_type' =&amp;amp;gt; $main_type, 'sub_type' =&amp;amp;gt; $sub_type, 'precedence' =&amp;amp;gt; (float)$precedence, 'tokens' =&amp;amp;gt; $tokens);
			}
		}
		usort($toret, array('Parser', 'compare_media_ranges'));
	}
	return $toret;
}
?&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This helper function parses the options for each mime type, determining the precedence and tokens. It returns the precidence as a float, and an array of tokens.&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?php
public static function accept_header_options($type_options) {
	$precedence = 1;
	$tokens = array();
	if (is_string($type_options)) {
		$type_options = explode(';', $type_options);
	}
	$type_options = array_map('trim', $type_options);
	foreach ($type_options as $option) {
		$option = explode('=', $option);
		$option = array_map('trim', $option);
		if ($option[0] == 'q') {
			$precedence = $option[1];
		} else {
			$tokens[$option[0]] = $option[1];
		}
	}
	$tokens = count ($tokens) ? $tokens : false;
	return array($precedence, $tokens);
}
?&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This function is used to sort the array of mime types we parsed from the header. At the moment it doesn’t check any tokens, but this code can easily be added on line 6.
&amp;lt;?php
private static function compare_media_ranges($one, $two) {
	if ($one['main_type'] != '*' &amp;amp;&amp;amp; $two['main_type'] != '*') {
		if ($one['sub_type'] != '*' &amp;amp;&amp;amp; $two['sub_type'] != '*') {
			if ($one['precedence'] == $two['precedence']) {
				if (count ($one['tokens']) == count ($two['tokens'])) {
					return 0;
				} else if (count ($one['tokens']) &amp;lt; count ($two['tokens'])) {
					return 1;
				} else {
					return -1;
				}
			} else if ($one['precedence'] &amp;lt; $two['precedence']) {
				return 1;
			} else {
				return -1;
			}
		} else if ($one['sub_type'] == '*') {
			return 1;
		} else {
			return -1;
		}
	} else if ($one['main_type'] == '*') {
		return 1;
	} else {
		return -1;
	}
}
?&amp;gt;&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Backend-PHP Framework&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/backend_intro/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T08:46:32+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/backend_intro/backend_intro&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;div class=&amp;quot;notice&amp;quot;&amp;gt;
&amp;lt;h3&amp;gt;Update: 21/11/2011&amp;lt;/h3&amp;gt;
Backend has undergone a major rewrite. Get the latest info &amp;lt;a href=&amp;quot;/content/backend-core-a-restful-mvc-php-framework&amp;quot;&amp;gt;here&amp;lt;/a&amp;gt;, and get the code on &amp;lt;a href=&amp;quot;https://github.com/jrgns/backend-core&amp;quot;&amp;gt;GitHub&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;In the past few years I’ve been working on a PHP framework / backend. Sometimes out of frustration with copying and pasting code, but usually because I’m to lazy to write a lot of code, so decide to write a little bit of code to do a lot… And then I write some more code, to do a little bit more, and before you know it, it’s yet another PHP framework. I tried to get some public input on the &amp;lt;a href=&amp;quot;http://launchpad.net/yaphpfter&amp;quot;&amp;gt;project&amp;lt;/a&amp;gt; once before, but that went nowhere, and I left it there - until of course I had to do some work that required the same type of thing, and now I’m at it again.&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;What makes backend different from my previous &amp;lt;a href=&amp;quot;http://www.codinghorror.com/blog/archives/000576.html&amp;quot;&amp;gt;failed&amp;lt;/a&amp;gt; experiment? Well, the fact that this is now the 7th or 8th time that I’ve rehashed the concept, and that this time, I’ve actually put some thought and effort into it. No, it’s not perfect, and it won’t solve the world’s problems, but it better and simpler, and hopefully more useful.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;One concept that I definitely want to run with in backend, is the concept of backend as a web service, as opposed to a framework or a content / data management system. Backend provides a client, as in a browser or an application, with the requested data, in a format that the client can understand. Be it a human readable web page, JSON, XML or even PHP variables. This struck me as important after reading &amp;lt;a href=&amp;quot;http://tomayko.com/writings/rest-to-my-wife&amp;quot;&amp;gt;this&amp;lt;/a&amp;gt; by Ryan Tomayko:&amp;lt;/p&amp;gt;

&amp;lt;blockquote&amp;gt;
  &amp;lt;p&amp;gt;Wife: A web page is a resource?&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Ryan: Kind of. A web page is a
“representation” of a resource.
Resources are just concepts.
URLs—those things that you type into
the browser…&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Wife: I know what a URL is..&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Ryan: Oh, right. Those tell the
browser that there’s a concept
somewhere. A browser can then go ask
for a specific representation of the
concept. Specifically, the browser
asks for the web page representation
of the concept.&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Wife: What other kinds of
representations are there?&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Ryan: Actually, representations is one
of these things that doesn’t get used
a lot. In most cases, a resource has
only a single representation. But
we’re hoping that representations will
be used more in the future because
there’s a bunch of new formats popping
up all over the place.&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Wife: Like what?&amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;Ryan: Hmm. Well, there’s this concept
that people are calling “Web
Services”. It means a lot of different
things to a lot of different people
but the basic concept is that machines
could use the web just like people do.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;p&amp;gt;So it’s important for me to make it easy for web developers to easily provide data in different formats. Backend can already provide any client with data in 4, yes 4, different formats:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;HTML, or a human readable webpage&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://json.org/&amp;quot;&amp;gt;JSON&amp;lt;/a&amp;gt;, the new darling of AJAX fans&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://www.php.net/serialize&amp;quot;&amp;gt;(PHP) Serialized byte stream representations&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://www.php.net/var-export&amp;quot;&amp;gt;PHP variables&amp;lt;/a&amp;gt;, as created by var_export&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;This will hopefully increase backend’s usefulness as a web service. And yes, I know, XML is missing, but of those 4, HTML was necessary, although not necessarily easy, and the other three were extremely easy to implement, as they are all products of simple PHP functions. One day when someone uses backend and actually &amp;lt;strong&amp;gt;needs&amp;lt;/strong&amp;gt; XML, we can implement it. (Notice that I said &amp;lt;em&amp;gt;we&amp;lt;/em&amp;gt;, not &amp;lt;em&amp;gt;I&amp;lt;/em&amp;gt; - I rarely use XML, so I won’t know the requirements, so if I do it alone, it will probably be useless).&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;At the moment backend is on version 0.1.2.1 in my personal repo. All that means is that I’ve decided I’ve reached a point where I can actually release the code to the public, and made some improvements, fixes and changes. When will it be marked as version 1.0?&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;When we have the following:&amp;lt;/p&amp;gt;

&amp;lt;ol&amp;gt;
  &amp;lt;li&amp;gt;A fully fledged and integrated admin space
2, Easy and intuitive setup / install system&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Easy and intuitive update system&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;An intuitive plugin system&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Intuitive and function DB Objects&amp;amp;lt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;The ability to easily implement different data formats&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;The ability to use multiple and different data sources (MySQL, SQLite, flat files, etc.)&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Working and secure user access control&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Either a REST-full implementation, or a roadmap towards it&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Something that makes coding easier&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;

&amp;lt;p&amp;gt;That’s ten requirements for me to release backend v1.0…&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;What’s already done?&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Semi working DB Objects&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Output of different data formats using views&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Simple templating / caching system&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Simple user access control&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;CRUD, actually, just CRU actions. I haven’t gotten round to the Deletes yet.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;I’m using &amp;lt;a href=&amp;quot;http://jquery.com/&amp;quot;&amp;gt;jQuery&amp;lt;/a&amp;gt; as a JavaScript backend, and &amp;lt;a href=&amp;quot;http://www.blueprintcss.org/&amp;quot;&amp;gt;blueprint&amp;lt;/a&amp;gt; for my CSS needs. For now it’s under the &amp;lt;a href=&amp;quot;http://www.opensource.org/licenses/eclipse-1.0.php&amp;quot;&amp;gt;EPL&amp;lt;/a&amp;gt;, but I may switch to the MIT license at some point. I’m using MySQL exclusively at this point, but am hoping to add support for other DB’s / sources eventually.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I’ll be putting the code on &amp;lt;a href=&amp;quot;http://launchpad.net/backend&amp;quot;&amp;gt;Launchpad&amp;lt;/a&amp;gt; soon, so if you want to contribute, or comment, please do!&amp;lt;/p&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Importing a file into a Google Gears DB using PHP&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/import_to_google_gears/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T08:45:19+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/import_to_google_gears/import_to_google_gears&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;I’m playing around with &amp;lt;a href=&amp;quot;http://developers.google.com/gears/&amp;quot;&amp;gt;Google Gears&amp;lt;/a&amp;gt;, particularly the database part, just to see what it’s usefull for, and if I can use it in an app I’m working on. At some point I realised that I will need to import data at some point. Here’s how I did it:&amp;lt;/p&amp;gt;

&amp;lt;!--break--&amp;gt;

&amp;lt;p&amp;gt;By using an HTML uploading form, and PHP to process the upload, you can create a JSON object which can be used to import data into whatever Gears DB you have. Use whatever you use to put all of the data into one array. The source can be a DB or a file upload, come to think of it. Convert the data to JSON using json_encode, and assign it to a JavaScript variable:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;var data = &amp;lt;?php echo json_encode($data) ?&amp;gt;;&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;After that, check that the table exists, loop through the data, and insert!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The complete code below:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The test data to import:&amp;lt;/p&amp;gt;

&amp;lt;pre&amp;gt;
&amp;quot;one two&amp;quot;,2,1
&amp;quot;three four&amp;quot;,3.4,2
&amp;lt;/pre&amp;gt;

&amp;lt;p&amp;gt;And the test page, HTML and PHP together:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class=&amp;quot;cp&amp;quot;&amp;gt;&amp;amp;lt;?php
$data = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	$data = array();
	if (!empty($_FILES['to_import']['tmp_name']) &amp;amp;amp;&amp;amp;amp; is_readable($_FILES['to_import']['tmp_name'])) {
		$fp = fopen($_FILES['to_import']['tmp_name'], 'r');
		while (($row = fgetcsv($fp)) !== false) {
			$data[] = $row;
		}
		fclose($fp);
	}
	$data;
}
?&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;html&amp;amp;gt;&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;head&amp;amp;gt;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;title&amp;amp;gt;&amp;lt;/span&amp;gt;JSON / Gears import Test&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/title&amp;amp;gt;&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/head&amp;amp;gt;&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;body&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;onload=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;do_import()&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;form&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;method=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;post&amp;quot;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;action=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;&amp;quot;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;enctype=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;multipart/form-data&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;input&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;type=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;file&amp;quot;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;name=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;to_import&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;input&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;type=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;&amp;quot;submit&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/form&amp;amp;gt;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;script &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;na&amp;quot;&amp;gt;src=&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s&amp;quot;&amp;gt;'gears_init.js'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;script&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;kd&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;data&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;?&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;php&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;echo&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;json_encode&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;?&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;kd&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;do_import&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;()&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;kd&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;db&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;google&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;gears&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;factory&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;create&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'beta.database'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;db&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;open&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'database-test'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;db&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;execute&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'CREATE TABLE IF NOT EXISTS Import'&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt;
				&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;' (Phrase text, Amount float, Something int)'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;data&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;for&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;kd&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;data&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;++&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;db&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;execute&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'INSERT INTO Import Values(?, ?, ?)'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;data&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;]);&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

		&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;db&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;execute&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;'SELECT * FROM Import'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;);&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;while&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;isValidRow&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;())&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;alert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;' - '&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;s1&amp;quot;&amp;gt;' - '&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;mi&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;));&amp;lt;/span&amp;gt;
			&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;next&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;rs&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;nx&amp;quot;&amp;gt;close&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;();&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
		&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;lt;/span&amp;gt;
	&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/body&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;nt&amp;quot;&amp;gt;&amp;amp;lt;/html&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&lt;/content&gt;
 &lt;/entry&gt;
 
 &lt;entry&gt;
   &lt;title&gt;Redirect All Requests To Index.php Using .htaccess&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net/redirect_request_to_index/index.html&quot;/&gt;
   &lt;updated&gt;2010-03-18T08:42:15+00:00&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net/redirect_request_to_index/redirect_request_to_index&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;&amp;lt;p&amp;gt;In one of my pet projects, I redirect all requests to index.php, which then decides what to do with it:&amp;lt;!--break--&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Simple Example&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This snippet in your .htaccess will ensure that all requests for files and folders that does not exists will be redirected to index.php:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This enables the rewrite engine:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteEngine on
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This checks for existing folders (-d) and files (-f):&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;And this does the actual redirecting:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteRule . index.php [L]
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;###Extended Example&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;You can extend this to pass the requested path to the index.php file by modifying the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;RewriteRule&amp;lt;/code&amp;gt; to the following:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;^(.*)$&amp;lt;/code&amp;gt; part tells the rewrite module that we want to pass down the whole requested path as one parameter.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;QSA&amp;lt;/code&amp;gt; part tells the module to append any query strings to the request.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;The &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;?q=$1&amp;lt;/code&amp;gt; tells the module how to pass down the parameter. In this case, it’s passed down as the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;q&amp;lt;/code&amp;gt; parameter.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;You can extend this even further by using regular expressions. For example:&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;RewriteRule ^([^/]*)(.*)$ index.php?first=$1&amp;amp;amp;second=$2 [L,QSA]
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This will pass down the first part of the path as the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;first&amp;lt;/code&amp;gt; parameter, and the rest as the &amp;lt;code class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;second&amp;lt;/code&amp;gt;. So the following request&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;http://yourhost.com/some/path/somewhere
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;will result in&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;http://yourhost.com/index.php?first=some&amp;amp;amp;second=path/somewhere
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;This allows for some creative ways to do clean URLs.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;###Trouble Shooting&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If it’s not working, make sure that mod_rewrite is installed on Apache. On a unix system you can just do&amp;lt;/p&amp;gt;

&amp;lt;div class=&amp;quot;highlighter-rouge&amp;quot;&amp;gt;&amp;lt;pre class=&amp;quot;highlight&amp;quot;&amp;gt;&amp;lt;code&amp;gt;sudo a2enmod rewrite
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;to achieve that.&amp;lt;/p&amp;gt;
&lt;/content&gt;
 &lt;/entry&gt;
 

&lt;/feed&gt;
</content>
 </entry>
 
 <entry>
   <title>Blog Posts</title>
   <link href="http://jrgns.net/blog-index.html"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;div id=&quot;home&quot; class=&quot;row-fluid&quot;&gt;
  &lt;div class=&quot;offset1 span11&quot;&gt;
    &lt;h2&gt;&lt;i class=&quot;icon-pencil&quot;&gt;&lt;/i&gt; Blog Posts&lt;/h2&gt;
    &lt;ul&gt;
      
        &lt;li&gt;&lt;span&gt;12 Jan 2015 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2015/01/12/logstash-config-guide.html&quot;&gt;The Logstash Config Guide&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;03 Feb 2014 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2014/02/03/populate-form-with-referring-entity-symfony.html&quot;&gt;Populate a Symfony 2 Form with the referring entity&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;03 Jan 2014 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel.html&quot;&gt;MS-SQL Stored Procedures in Sequel: Getting the value of output variables&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;10 Oct 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/10/10/is-php-the-slums-of-the-programming-world.html&quot;&gt;PHP: The slums of the Programming World?&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;26 Sep 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/09/26/diy-dynamic-dns-using-cloudflare.html&quot;&gt;A DIY Dynamic DNS service using Cloudflare&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;17 Sep 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2.html&quot;&gt;Setting a default order for Doctrine 2 / Symfony 2&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;22 Jul 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/07/22/prepopulating-entity-in-symfony-2-form.html&quot;&gt;Pre-populating an Entity in a Symfony 2 Form&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;29 Apr 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/04/29/summary-of-symfony-2-authorization.html&quot;&gt;A Summary of Symfony 2 Authorization&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;28 Feb 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet.html&quot;&gt;I'm the most Organized Disorganized person you'll meet&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;08 Jan 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/01/08/php-array-merge-recursive-function-explained.html&quot;&gt;PHP's array_merge_recursive function explained&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;20 Dec 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2012/12/20/setting-up-the-swiftmailer-spooler.html&quot;&gt;Setting up the Swiftmailer Spooler&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;09 Jun 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/building-php-projects-with-jenkins/index.html&quot;&gt;Building PHP Projects with Jenkins&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;17 Mar 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/decorator-pattern-implemented-properly-in-php/index.html&quot;&gt;Decorator Pattern Implemented Properly In PHP&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;16 Mar 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/the-low-hanging-fruit-of-testing/index.html&quot;&gt;The Low Hanging Fruit Of Testing&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;24 Feb 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/json-encode-ing-private-and-protected-properties/index.html&quot;&gt;json-encode'ing Private and Protected Properties&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;28 Jan 2012 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/22seven-com-folly-or-genius/index.html&quot;&gt;22seven.com - Folly, or Genius?&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;16 Nov 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/setting-up-puppet-on-ubuntu-10.4/index.html&quot;&gt;Setting up Puppet on Ubuntu 10.4&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;05 Oct 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/php-community-in-south-africa-lack-thereof/index.html&quot;&gt;PHP Community in South Africa, lack thereof&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;28 Sep 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/why-johnny-died-or-how-i-finally-realised-why-singletons-and-global-variables-are-bad/index.html&quot;&gt;Why Johnny Died (or, How I Finally Realised Why Singletons And Global Variables Are Bad)&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;13 Sep 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/php-virtualhost/index.html&quot;&gt;A PHP Virtual Host&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Jul 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/js-trim/index.html&quot;&gt;A JavaScript trim function&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;11 Jul 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/quick_guide_to_creating_a_website_quickly/index.html&quot;&gt;Quick Guide To Creating A Website Quickly&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;05 May 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/good_developers_think_like_a_startup/index.html&quot;&gt;Good Developers Think like a Startup&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;08 Feb 2011 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/why_oo_is_great/index.html&quot;&gt;Why Object Orientation is Great&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;11 Oct 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/getting_started_with_node_js/index.html&quot;&gt;Getting Started with node.js&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;07 Oct 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/node_parser_email/index.html&quot;&gt;Email Parser for node.js&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;15 Apr 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/why_i_code/index.html&quot;&gt;Why I Code&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;30 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/twitter_api_request_entity_too_large_http_413_error/index.html&quot;&gt;Twitter API Request Entity too large / HTTP 413 error&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;26 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/remove_www_from_url/index.html&quot;&gt;How to remove the www from your URL&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;24 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/new_look/index.html&quot;&gt;New look!&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/sqllite_view/index.html&quot;&gt;SQLite Viewer&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/Update on Backend/index.html&quot;&gt;Update On Backend&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/backend_100_revisions/index.html&quot;&gt;Backend 100 Revisions&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/my_take_on_single_or_multiple_returns/index.html&quot;&gt;My take on single or multiple returns&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/firefox_requests_a_page_twice/index.html&quot;&gt;Firefox requests a page twice?&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/parse_http_accept_header/index.html&quot;&gt;Parse Http Accept Header&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/backend_intro/index.html&quot;&gt;Backend-PHP Framework&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/import_to_google_gears/index.html&quot;&gt;Importing a file into a Google Gears DB using PHP&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;18 Mar 2010 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/redirect_request_to_index/index.html&quot;&gt;Redirect All Requests To Index.php Using .htaccess&lt;/a&gt;&lt;/li&gt;
      
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Hire Me</title>
   <link href="http://jrgns.net/hire-me.html"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;div id=&quot;home&quot; class=&quot;row-fluid&quot;&gt;
  &lt;div class=&quot;offset1 span11&quot;&gt;
    &lt;h2&gt;&lt;i class=&quot;icon-fire&quot;&gt;&lt;/i&gt; Hire Me&lt;/h2&gt;
    &lt;p&gt;
      Become more productive by delegating your problem solving to me. I do consulting
      for clients who need an expert developer, integrator and problem solver.
    &lt;/p&gt;
    &lt;p&gt;
      My core skills are &lt;strong&gt;Systems and Web Development&lt;/strong&gt; in languages such as PHP and Ruby
    &lt;/p&gt;
    &lt;p&gt;
      Contact me for a quote or if you have a question:&lt;br&gt;
      &lt;i class=&quot;icon-envelope-alt&quot;&gt;&lt;/i&gt; &lt;a href=&quot;mailto:jrgns@jrgns.net&quot;&gt;jrgns@jrgns.net&lt;/a&gt;
    &lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>A blog about systems and the interwebs</title>
   <link href="http://jrgns.net/"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;div id=&quot;home&quot; class=&quot;row-fluid&quot;&gt;
  &lt;div class=&quot;offset1 span11&quot;&gt;
    &lt;p&gt;
      Be sure to check out &lt;a href='http://blog.eagerelk.com'&gt;EagerELK&lt;/a&gt; - My efforts to explore the &lt;span title=&quot;Elasticsearch, Logstash, Kibana&quot;&gt;ELK&lt;/span&gt; stack.
    &lt;/p&gt;
    &lt;h2&gt;&lt;i class=&quot;icon-comment&quot;&gt;&lt;/i&gt; Talks&lt;/h2&gt;
    &lt;p&gt;I spoke at&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.meetup.com/DeveloperUG//&quot;&gt;DUG&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/U2_should_have_used_Elasticsearch.pdf&quot;&gt;U2 should have used Elasticsearch&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.meetup.com/Jozi-Linux-User-Group-JLUG/&quot;&gt;JLUG&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/Moar_Logs.pdf&quot;&gt;Moar logs! Logging on Linux using the ELK Stack&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.meetup.com/Elasticsearch-South-Africa/&quot;&gt;Elasticsearch SA Meetup&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/Gentle_intro_to_Elasticsearch.pdf&quot;&gt;A gentle introduction into Elasticsearch&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.meetup.com/joziruby/&quot;&gt;Jozi.rb Meetup&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/logstash-jozi-rb&quot;&gt;Everything's Connected: Hacking the interwebs with Logstash&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.meetup.com/Elasticsearch-South-Africa/&quot;&gt;Elasticsearch SA Meetup&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/tutuka-elk&quot;&gt;Leveraging the ELK stack to ensure API uptime&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.rubyfuza.org/&quot;&gt;Rubyfuza 2015 (Lightening Talk)&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/logstash-hacking-the-interwebs&quot;&gt;Everything's Connected: Hacking the interwebs with Logstash&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://www.jsinsa.com/jsinsa/2014/index.htm&quot;&gt;JSinSA 2014&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/learning-from-coffeescript&quot;&gt;How CoffeeScript Improved My JavaScript Skills&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;&lt;a href=&quot;http://tech4africa.com/&quot;&gt;Tech 4 Africa 2013&lt;/a&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;a href=&quot;talks/phpslums/&quot;&gt;PHP - The slums of the programming world?&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;h2&gt;&lt;i class=&quot;icon-pencil&quot;&gt;&lt;/i&gt; Latest Blog Posts&lt;/h2&gt;
    &lt;ul id=&quot;blog-posts&quot; class=&quot;posts&quot;&gt;
      
        &lt;li&gt;&lt;span&gt;12 Jan 2015 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2015/01/12/logstash-config-guide.html&quot;&gt;The Logstash Config Guide&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;03 Feb 2014 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2014/02/03/populate-form-with-referring-entity-symfony.html&quot;&gt;Populate a Symfony 2 Form with the referring entity&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;03 Jan 2014 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2014/01/03/ms-sql-stored-procs-with-output-variables-in-sequel.html&quot;&gt;MS-SQL Stored Procedures in Sequel: Getting the value of output variables&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;10 Oct 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/10/10/is-php-the-slums-of-the-programming-world.html&quot;&gt;PHP: The slums of the Programming World?&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;26 Sep 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/09/26/diy-dynamic-dns-using-cloudflare.html&quot;&gt;A DIY Dynamic DNS service using Cloudflare&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;17 Sep 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/09/17/setting-a-default-order-for-doctrine-symfony-2.html&quot;&gt;Setting a default order for Doctrine 2 / Symfony 2&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;22 Jul 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/07/22/prepopulating-entity-in-symfony-2-form.html&quot;&gt;Pre-populating an Entity in a Symfony 2 Form&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;29 Apr 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/04/29/summary-of-symfony-2-authorization.html&quot;&gt;A Summary of Symfony 2 Authorization&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;28 Feb 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/02/28/im-the-most-organized-disorganized-person-youll-meet.html&quot;&gt;I'm the most Organized Disorganized person you'll meet&lt;/a&gt;&lt;/li&gt;
      
        &lt;li&gt;&lt;span&gt;08 Jan 2013 &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;&lt;/span&gt; &lt;a href=&quot;/blog/2013/01/08/php-array-merge-recursive-function-explained.html&quot;&gt;PHP's array_merge_recursive function explained&lt;/a&gt;&lt;/li&gt;
      
    &lt;/ul&gt;
    &lt;p&gt;&lt;a href=&quot;blog-index.html&quot;&gt;More...&lt;/a&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Resources</title>
   <link href="http://jrgns.net/resources.html"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;h2&gt;&lt;i class=&quot;icon-book&quot;&gt;&lt;/i&gt; Resources&lt;/h2&gt;

&lt;p class=&quot;lead&quot;&gt;These are some of the books I've read that helped me improve my skills. It might help you as well.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0735619670/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0735619670&amp;linkCode=as2&amp;tag=jrgnsnet-20&amp;linkId=IZJNDTHPXE66XXHK&quot;&gt;Code Complete&lt;/a&gt;&lt;img src=&quot;http://ir-na.amazon-adsystem.com/e/ir?t=jrgnsnet-20&amp;l=as2&amp;o=1&amp;a=0735619670&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;&quot; /&gt;&lt;/h3&gt;
&lt;p&gt;The definitive guide to creating great code. A must read for any developer serious about his craft.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0321721330/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321721330&amp;linkCode=as2&amp;tag=jrgnsnet-20&amp;linkId=5FFFDJYRVUAFOBQJ&quot;&gt;Practical Object-Oriented Design in Ruby: An Agile Primer&lt;/a&gt;&lt;img src=&quot;http://ir-na.amazon-adsystem.com/e/ir?t=jrgnsnet-20&amp;l=as2&amp;o=1&amp;a=0321721330&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;&quot; /&gt;
&lt;/h3&gt;
&lt;p&gt;The best kind of design is one that gets out of your way. Sandi Metz has a great way of describing such a design.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0973862181/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0973862181&amp;linkCode=as2&amp;tag=jrgnsnet-20&amp;linkId=EPE2IYZQW3EZ7VYQ&quot;&gt;PHP/Architect's Guide to Enterprise PHP Development&lt;/a&gt;&lt;img src=&quot;http://ir-na.amazon-adsystem.com/e/ir?t=jrgnsnet-20&amp;l=as2&amp;o=1&amp;a=0973862181&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;&quot; /&gt;&lt;/h3&gt;
&lt;p&gt;A well structured coder CAN produce quality PHP code. This book includes good advice that will help you get there.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0470526912/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0470526912&amp;linkCode=as2&amp;tag=jrgnsnet-20&amp;linkId=42AM4LKLMGXN7LGG&quot;&gt;JavaScript Bible&lt;/a&gt;&lt;img src=&quot;http://ir-na.amazon-adsystem.com/e/ir?t=jrgnsnet-20&amp;l=as2&amp;o=1&amp;a=0470526912&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;&quot; /&gt;&lt;/h3&gt;
&lt;p&gt;This tome takes you way beyond coding with frameworks such as JQuery, and teaches you how to write proper JavaScript.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/144930351X/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=144930351X&amp;linkCode=as2&amp;tag=jrgnsnet-20&amp;linkId=AFS3LKF53XHLUVPO&quot;&gt;JavaScript Web Applications&lt;/a&gt;&lt;img src=&quot;http://ir-na.amazon-adsystem.com/e/ir?t=jrgnsnet-20&amp;l=as2&amp;o=1&amp;a=144930351X&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;&quot; /&gt;&lt;/h3&gt;
&lt;p&gt;Go beyond using JavaScript to just pretty up pages and make things move. Create all out web pages using this as your guide.&lt;/p&gt;

&lt;p&gt;Feel free to suggest more resources / books in the comments!&lt;/p&gt;

&lt;p class=&quot;muted&quot; style=&quot;text-align: center;&quot;&gt;Yes, these are affiliate links&lt;/p&gt;

&lt;div id=&quot;disqus_thread&quot;&gt;&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'jrgns'; // required: replace example with your forum shortname

    // The following are highly recommended additional parameters. Remove the slashes in front to use.
    var disqus_identifier = '';
    var disqus_url = 'http://jrgns.net/resources.html';

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;
&lt;noscript&gt;Please enable JavaScript to view the &lt;a href=&quot;http://disqus.com/?ref_noscript&quot;&gt;comments powered by Disqus.&lt;/a&gt;&lt;/noscript&gt;
&lt;a href=&quot;http://disqus.com&quot; class=&quot;dsq-brlink&quot;&gt;blog comments powered by &lt;span class=&quot;logo-disqus&quot;&gt;Disqus&lt;/span&gt;&lt;/a&gt;
</content>
 </entry>
 
 <entry>
   <title></title>
   <link href="http://jrgns.net/sitemap.xml"/>
   <id>http://jrgns.net</id>
   <content type="html">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;feed xmlns=&quot;http://www.w3.org/2005/Atom&quot;&gt;

 &lt;title&gt;Jurgens du Toit&lt;/title&gt;
 &lt;link href=&quot;http://jrgns.net/sitemap.xml&quot; rel=&quot;self&quot;/&gt;
 &lt;link href=&quot;http://jrgns.net/&quot;/&gt;
 &lt;updated&gt;{{ site.time | date_to_xmlschema }}&lt;/updated&gt;
 &lt;id&gt;http://jrgns.net/&lt;/id&gt;
 &lt;author&gt;
   &lt;name&gt;Jurgens du Toit&lt;/name&gt;
   &lt;email&gt;jrgns@jrgns.net&lt;/email&gt;
 &lt;/author&gt;

 {% for post in site.posts %}
 &lt;entry&gt;
   &lt;title&gt;{{ post.title }}&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net{{ post.url }}&quot;/&gt;
   &lt;updated&gt;{{ post.date | date_to_xmlschema }}&lt;/updated&gt;
   &lt;id&gt;http://jrgns.net{{ post.id }}&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;{{ post.content | xml_escape }}&lt;/content&gt;
 &lt;/entry&gt;
 {% endfor %}
 {% for page in site.pages %}
 &lt;entry&gt;
   &lt;title&gt;{{ page.title }}&lt;/title&gt;
   &lt;link href=&quot;http://jrgns.net{{ page.url }}&quot;/&gt;
   &lt;id&gt;http://jrgns.net{{ page.id }}&lt;/id&gt;
   &lt;content type=&quot;html&quot;&gt;{{ page.content | xml_escape }}&lt;/content&gt;
 &lt;/entry&gt;
 {% endfor %}
&lt;/feed&gt;
</content>
 </entry>
 
 <entry>
   <title></title>
   <link href="http://jrgns.net/assets/css/style.css"/>
   <id>http://jrgns.net</id>
   <content type="html">@import &quot;jekyll-theme-primer&quot;;
</content>
 </entry>
 
 <entry>
   <title>How CoffeeScript Improved My JavaScript Skills</title>
   <link href="http://jrgns.net/talks/learning-from-coffeescript/notes.html"/>
   <id>http://jrgns.net</id>
   <content type="html"># How CoffeeScript Improved My JavaScript Skills

## Intro

* I write JavaScript for fun. I've played around with Node and JQuery and MooTools and just plain ol' vanilla JavaScript, but I can't call myself a professional JavaScript Coder.
* While working with [Dashing](https://github.com/shopify/dashing) I realised that I haven't worked with CoffeeScript yet. Challenge Accepted!
* I took an existing module I wrote in JavaScript, and rewrote it in CoffeeScript
* It might be comparing apples to oranges, as I didn't set out from the beginning to make this a JS vs CS project. Either way I'll try to be fair. Feel free to call me out if you think I'm missing something or if I'm being prejudiced.
* CoffeeScript Coders? Because you want to or have to?

## What I Learnt

Or, a quick lesson in how *NOT* to code in JS

## I Suck at JavaScript Prototypes

* When you're not doing a lot of JavaScript coding it's easy to forget that JavaScript isn't a &quot;normal&quot; OO language - It's approach to OO is prototypical
* When you have a flat object hierarchy, it's very easy to write code like this, and not realise that it's not actually &quot;correct&quot;:
* You can use that as an object, and even create it with `new`:
* But any inheritance will be borked as the properties and methods aren't added to the prototype.

## CoffeeScript generated JS

* The prototype is used properly, and you can then easily extend this object into something more specific.

## Build Processes are Awesome

* Plain JS doesn't need a build process...
* Flat file with all my classes, utilities - It's a mess
* But why deny yourself an awesome tool?
* CoffeeScript requires at least one build step
* So once the work of setting it up is done, get some more goodies

* I had one flat file with all my classes, utilities and methods in it. It's a mess. Instead of making the time to understand utilities such as Grunt and Gulp I just mucked on.
* CoffeeScript requires at least one build step: compilation. Since I had to do compilation, I started looking into other build tasks allowing me to use multiple files, and voila, my project was better organized.

## Source maps? Source maps!

### Without Source Maps

* The code is unrecognizable
* Is it your fault or the compilers?
* Are the changes I'm making fixing or breaking things?

### With Sourcemaps!

* Recognizable code
* Direct link between what's happening in the browser and your CoffeeScript
* Supported in Chrome and Firefox, FireBUG support is coming

## A few meta-functions go a long way

## Simpler is Better? The Tradeoff

### CoffeeScript...

* Hides a lot of boilerplate
* Less code (read information) to take in
* Easier to look past the code and at the abstraction

### But?

* Do you want the extra complexity?
* and the extra boilerplate?
* what about it being only a subset of JS?
</content>
 </entry>
 
 <entry>
   <title>Markdown Demo</title>
   <link href="http://jrgns.net/talks/plugin/markdown/example.html"/>
   <id>http://jrgns.net</id>
   <content type="html"># Markdown Demo



## External 1.1

Content 1.1

Note: This will only appear in the speaker notes window.


## External 1.2

Content 1.2



## External 2

Content 2.1



## External 3.1

Content 3.1


## External 3.2

Content 3.2
</content>
 </entry>
 
 <entry>
   <title>StaticElastic: An Elasticsearch and Backbone SPA</title>
   <link href="http://jrgns.net/talks/static-elastic/notes.html"/>
   <id>http://jrgns.net</id>
   <content type="html"># StaticElastic: An Elasticsearch and Backbone SPA

* Jurgens du Toit / [@jrgns](http://twitter.com/jrgns)
* [EagerELK](http://blog.eagerelk.com)


# Elasticsearch

![Elasticsearch search trend](http://jrgns.net/talks/static-elastic/img/elasticsearch_trends.png)

* Started out as a search engine / interface to Lucene
* Started evolving into other use cases
* NoSQL?
* Elasticsearch (the company) -&gt; Elastic
* Currently Version 1.6, active development

-----------------------------------------

# Elastic / ELK / Found

* Developed by Elastic (valued at &gt; $700 mil)
* The rest of the ELK stack
* Support Contracts
* Plugins
  - Marvel
  - Shield
  - Watcher
* Talk about the company - community involvement, etc.

-----------------------------------------

### Vitals

![The statistics](http://jrgns.net/talks/static-elastic/img/vitalstatistix.jpg)

* REST interface to a schema-free JSON document store
* Plugin Architecture
* Near Real Time reads
* Search
* Aggregations
* Basic CRUD

-----------------------------------------

### Architecture&lt;/h3&gt;

![Architecture](http://jrgns.net/talks/static-elastic/img/architecture.jpeg)

* Runs over Lucene and provides distribution and an API
* Meant to run in a Cluster
* Shards and Replicas provides redundancy
* CAP - Consistency, Availability, Partition tolerance
* Indices and Types
* Mappings

## Backbone

* One of the first MVP libraries / frameworks
* Lightweight
* Easy to parse
* Serves as a prototype of how to implement an SPA using ES as a backend

## SPA: Why Backbone and ES

![Rev it up!](http://jrgns.net/talks/static-elastic/img/fastandfurious.jpg)

* HTTP, REST and CORS out of the box
* Can't serve files like CouchDB, but hey
* Versioning
* Relations
* Routing
* Silos

* Oh, yes, search!
  - highlighting
  - spanning
  - fuzzy search
  - more of the same
  - relational
  - geo

## Why NOT Elasticsearch

![It's gone!](http://jrgns.net/talks/static-elastic/img/needle-in-a-haystack.jpg&quot;&gt;&lt;b)

[They're working on it](https://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html)

* Aphyr June 2014 - 1.1, April 2015 - 1.5
* Sometimes CP, sometimes AP

You can lose documents if

* The network partitions into two intersecting components
* Or into two discrete components
* Or if even a single primary is isolated
* If a primary pauses (e.g. due to disk IO or garbage collection)
* If multiple nodes crash around the same time

* Advice on preventing splitbrain / number of nodes / masters
* Advice on having a master DB replicating into search DB
* Are logs that important?
* Be careful with production data!

* Check the page on their data-loss &amp; consistency issues / fixes. Great praise from Aphyr

* Be sure that you know your types / mappings before going into prod. Otherwise reindex and alias

## StaticElastic

* Load documents
* Search / highlighting
* Fetch document
* Significant terms in the section
* Update
* Update conflict

-----------------------------------------

```javascript
// curl http://localhost:9200/static-elastic/guardian/_search
{
  &quot;took&quot; : 4,
  &quot;timed_out&quot; : false,
  &quot;_shards&quot; : {
    &quot;total&quot; : 1,
    &quot;successful&quot; : 1,
    &quot;failed&quot; : 0
  },
  &quot;hits&quot; : {
    &quot;total&quot; : 3938,
    &quot;max_score&quot; : 1.0,
    &quot;hits&quot; : [ {
      &quot;_index&quot; : &quot;static-elastic&quot;,
      &quot;_type&quot; : &quot;guardian&quot;,
      &quot;_id&quot; : &quot;money-2015-jun-29-digital-banking-mondo-hopes-to-become-the-google-or-facebook-of-the-sector&quot;,
      &quot;_score&quot; : 1.0,
      &quot;_source&quot;:{&quot;title&quot;:&quot;Digital banking:
      //...
```                

-----------------------------------------

```javascript
// curl http://localhost:9200/static-elastic/guardian/business-marketforceslive-2015-jun-29-ocado-jumps-more-than-2-on-hopes-of-international-deal
{
  &quot;_index&quot; : &quot;static-elastic&quot;,
  &quot;_type&quot; : &quot;guardian&quot;,
  &quot;_id&quot; : &quot;business-marketforceslive-2015-jun-29-ocado-jumps-more-than-2-on-hopes-of-international-deal&quot;,
  &quot;_version&quot; : 1,
  &quot;found&quot; : true,
  &quot;fields&quot; : {
    &quot;section&quot; : [ &quot;Business&quot; ],
    &quot;title&quot; : [ &quot;Ocado jumps more than 2% on hopes of international deal&quot; ]
  }
}
```          

-----------------------------------------

```javascript
{
  &quot;took&quot; : 3,
  &quot;timed_out&quot; : false,
  &quot;_shards&quot; : {
    &quot;total&quot; : 1,
    &quot;successful&quot; : 1,
    &quot;failed&quot; : 0
  },
  &quot;hits&quot; : {
    &quot;total&quot; : 3938,
    &quot;max_score&quot; : 0.0,
    &quot;hits&quot; : [ ]
  },
  &quot;aggregations&quot; : {
    &quot;keywords&quot; : {
      &quot;buckets&quot; : [ {
        &quot;key&quot; : &quot;Business&quot;,
        &quot;doc_count&quot; : 1298
      }, {
        &quot;key&quot; : &quot;Books&quot;,
        &quot;doc_count&quot; : 967
      }, {
      //...
```          

-----------------------------------------

```javascript
// Backbone.Model.Page.sync
sync: function(method, model, options) {
  // Setup CORS
  options || (options = {});
  if (!options.crossDomain) { options.crossDomain = true; }

  // Do &quot;partial&quot; updates and fetch the _source field
  if (method === 'update' || method === 'create') {
    options.data = JSON.stringify({ &quot;doc&quot;: model });
    options.type = 'POST';
    options.url  = model.url() + '/_' + method + \
      '?fields=_source&amp;version=' + this.attributes._version;
  }

  return Backbone.Model.prototype.sync.call(
    this, method, model, options
  );
}
```          

-----------------------------------------

```javascript
// Backbone.Model.Page.parse (1)
parse: function(result) {
  if (result.get) {
    // This was from a create or an update
    result._source = result.get._source;
    delete result.get;
  }
  // Use the attributes in the `_source` field for the models attribs
  var model = _.extend(
    this.defaults, result._source ? result._source : {}
  );

  // Set the meta fields
  _.each(this.meta_fields, function(field) {
    if (result[field]) { model[field] = result[field]; }
  });
  //...
```          

-----------------------------------------

```javascript
// Backbone.Model.Page.parse (2)
parse: function(result) {
  //...
  // Check the highlighting
  if (result.highlight) {
    model.highlight = result.highlight;
  }
  //...
```    

```html
&amp;lt;!-- Collections Template --&amp;gt;
&lt;% pages.each(function(page) { %&gt;
  &lt;li&gt;
    &lt;a href=&quot;/&lt;%= page.attributes._id %&gt;&quot;&gt;
      &lt;% if (page.attributes.highlight) { %&gt;
        &lt;%= page.attributes.highlight.title %&gt;
      &lt;% } else { %&gt;
        &lt;%= page.attributes.title %&gt;
      &lt;% } %&gt;
    &lt;/a&gt;
  &lt;/li&gt;
&lt;% }) %&gt;
```          

-----------------------------------------

```javascript
save: function(key, val, options) {
  if (typeof key === 'object') {
    key._version = this.attributes._version;
  }
  return Backbone.Model.prototype.save.call(this, key, val, options);
},

toJSON: function(options) {
  var data = _.clone(this.attributes);
  // Don't send the meta fields to the server when POST / PUT ing
  _.each(this.meta_fields, function(field) {
    if (data[field]) {
      delete data[field];
    }
  });
  return data;
}
```          

-----------------------------------------

```javascript
// Backbone.View.Pages
loadResults: function(evt) {
  var options = {
    remove: false, processData: this.search === '',
    data: { from: this.from }
  };
  if (this.search !== '') {
    options.data.query = { term: { title: this.search } };
    options.data.highlight = {
      pre_tags: [ '&lt;strong&gt;' ], post_tags: [ '&lt;/strong&gt;' ],
      fields: { 'title': {} }
    };
    options.type = 'POST';
    options.data = JSON.stringify(options.data);
  }
  Pages.fetch(options);
},
```          

## Resources

![Resources](http://jrgns.net/talks/static-elastic/img/resources.jpg)
        &lt;aside class=&quot;notes&quot; data-markdown&gt;
* Definitive Guide
* Support Contracts / Training
* Discourse
* Meetup - This month - Beginners guide to ES
* How to get started
* Angular Library
* Ansible plays

![Some examples](http://jrgns.net/talks/static-elastic/img/output.gif)

## Questions

## Thanx!

* http://jrgns.net
* http://EagerELK.com
* http://LogstashConfigGuide.com
</content>
 </entry>
 
</feed>
