Phing: skeleton files

25/01/2010

I use various build scripts and environments while developing, but many parts of the project stay the same.

One thing that always changes on a new build though, is configuration.

The easisest way to manage configuration is having all of the properties of an application saved in a file, and then have your build script apply those settings to any skeleton file found within the project. You might call this in typo3 terms, marker replacement.

Since my ExportProperties task has been included in Phing 2.4, it’s now a lot easier to do this using Phing, ExportProperties, Copy task and the ExpandProperties filter

<?xml version="1.0" encoding="UTF-8"?>
<project name="example" basedir="." default="skel">
    <!-- This is where we store the configured properties -->
    <property name="paths.config.phingProperties" value="${paths.config}/phing.properties" />
 
    <!-- Check if we already have properties -->
    <available file="${paths.config.phingProperties}" property="hasPhingProperties" />
 
    <target name="config">
        <if>
         <equals arg1="${hasPhingProperties}" arg2="true" />
         <then>
           <echo message="Reconfigure application..." />
         </then>
         <else>
           <echo message="Configure application ..." />
         </else>
        </if>
 
        <propertyprompt propertyName="db.host" defaultValue="localhost" promptText="Mysql Server Host" />
        <propertyprompt propertyName="db.username" promptText="Mysql Username" />
        <propertyprompt propertyName="db.password" promptText="Mysql Password" />
        <propertyprompt propertyName="db.name" defaultValue="${db.username}" promptText="Mysql Database name" />
 
        <!-- Export the properties -->
        <exportproperties targetFile="${paths.config.phingProperties}" />
    </target>
 
    <target name="loadProperties">
        <if>
         <equals arg1="${hasPhingProperties}" arg2="true" />
         <then>
 
         </then>
         <else>
            <echo message="Missing config file ..." />
            <phingcall target="config" />
         </else>
        </if>
 
        <property file="${paths.config.phingProperties}"  />
    </target>
 
    <!-- Copies every file ending in .skel found in the current directory and all subdirectories to the same filename excluding .skel
    Also replaces property markers with actual values -->
    <target name="skel" depends="loadProperties">
        <echo msg="Skel files..." />
 
        <copy todir="" overwrite="true">
            <mapper type="glob" from="*.skel" to="*"/>
            <filterchain>
                <expandproperties />
            </filterchain>
 
            <fileset dir=".">
                <include name="**/*.skel" />
            </fileset>
        </copy>
    </target>
</project>

And then in config/env.ini.skel:

[production]
; Doctrine settings
resources.doctrine.connection_string = "mysql://${db.username}:${db.password}@${db.host}/${db.name};unix_socket=/var/run/mysqld/mysqld.sock"
3 Comments

The path from being able to program, to learning how to program

9/12/2009

Is the most obscure path you’ve ever taken. It goes from knowing something, to realising you don’t, to learning about the something you knew.

This little tale is inspired from my first two years as a programmer and it briefly explains some of the hops and bumps I hit while learning I don’t actually know what I thought I knew.

Read the rest of this article »

1 Comment

Data source abstraction

7/12/2009

In most cases, models within an application tend to be just classes extending a base class which acts as an abstraction layer to a database engine, like mysql.

I recently found myself in a situation where this way of thinking made almost no sense.

I was building the most basic user registration / authentication system:

  • User registers
  • User authenticates successfully
  • User data gets stored in session

I then realised that the first and thirds steps are exactly the same step, but with a different backend so I started thinking about it …

Why are models a bridge between PHP and MySQL (or any other language / database server)?

Wouldn’t it be nicer, more powerful to have writer / reader objects, that can interact with a multitude of engines that can store data? Like cookies, sessions, databases, xml, soap, etc?

Data source abstraction

No Comments

Delivering static content from a CDN: Rackspace Cloud Files tutorial

29/11/2009

Static content is a key contributor to your site’s load speed. The more static content you deliver from your own server and domain, the longer it takes for a browser to download all the content.

Among other factors, one key issue with delivering static content from your own domain, is that a browser has a limited number of connections it can open to one domain (which used to be / is 2 connections per domain).

Consider this: your site has 18 images, and 2 css files, that’s 20 static files delivered over a limit of 2 concurrent connections, so the 3rd and 4th files have to wait for the first two to finish downloading, before they are downloaded. Now this might not be an immediate issue, as with today’s connection speeds, you can easily download 20 files totalling under 500k pretty much instantly right? Not really. That’s when the 2 concurrent downloads limit comes into play.

Do the following test: install firebug (if you don’t already have it) and open up the “Net” panel. Hard refresh your page (that’s CMD + SHIFT + R for Mac users and CTRL + SHIFT + R for Windows users) and watch how your static files are slowly being downloaded over your very fast connection.

This is where a CDN (content delivery network) comes into play. A CDN could be simply described as remote storage. Some of the advantages of using a CDN are:

  • it overcomes the 2 connection limit, because it provides a different domain name
  • it’s fast, as it’s purpose is solely to deliver content
  • it can be regionalised, your files will be served from a server physically close to your visitor

The downside of a CDN is extra cost, but they are usually very cheap, Rackspace are charging $0.15 per GB of storage and $0.22 per GB of bandwidth used.

Setting up a CDN and using it is very easy, it usually takes less than an hour before you’re delivering content from it.

On Extraordinaire.Me, I’m using Rackspace Cloud Files.

The steps you’d have to take for setting up a CDN are:

  • Create an account
  • Upload the files through a web interface
  • Change your css

It is that simple, below is a short tutorial on how to do this with Rackspace Cloud Files. Read the rest of this article »

2 Comments

Phing: How to export properties to file

28/11/2009

I’ve been very annoyed that I have to define properties in 2 different places. Given the following scenario:

  • config target gets called, does a bunch of property prompts
  • writeConfig target gets called, writes properties to file

You’d have to have a template file with the properties already defined, then you’d have to copy that file to a config file with the filter expand properties.

But that sucks, I only want to call propertyprompts and have those properties saved to files, so I wrote a custom task exactly for that.

You can grab this custom task from Snipplr This task has been included in Phing with version 2.4.0.

To use it:

<ExportProperties targetFile=”phing.properties” />

Enjoy!

No Comments

TYPO3: Generate URL to page from id

28/11/2009

First thing:

$url = $GLOBALS[‘TSFE’]->cObj->getTypoLink_URL($pageId);

Also:

I can’t believe how many fundamental things in TYPO3 are not documented, or on Google.

No Comments

DOMElement object to HTML

28/11/2009

Here is a quick way to get HTML from a DOMElement in PHP

function getHtmlFromDomElement($element) {
    $doc = new DOMDocument();
    foreach($element->childNodes as $child)
    {
        $doc->appendChild($doc->importNode($child, true));
    }
    return $doc->saveHTML();
}
1 Comment

Intro

27/11/2009

Hi!

I realised I post too much nonsense on my blog and I also realised Tumblr is a tumblarity contest for emo kids.

Therefore, I decided to go back to wordpress and I also decided I will only post programming related articles, this one being the last non-programming related article.

As you can see I wiped all of the content not related to programming, I’m starting fresh.

So, why don’t you subscribe to my feed, and I will be sure to let you know when the first article on programming is done, it won’t be long now.

I’ll see you soon!

Andrei Serdeliuc, web programmer.

2 Comments