Codeship CI + Symfony 2 + PHPUnit

We've just moved from CircleCI (which was excellent) to Codeship, because we couldn't afford the Github fees any more. It definitely wasn't as easy as CircleCI, and the UI isn't as tidy. But Codeship works pretty well so far. The Setup Commands for a Symfony app go something like this...

phpenv local 5.4
export SYMFONY_ENV=test
unzip -p app/Resources/Tests/ | mysql -u $MYSQL_USER -p$MYSQL_PASSWORD test
echo "xdebug.max_nesting_level = 250" >> $HOME/.phpenv/versions/5.4/etc/php.ini
echo "memory_limit = 512M" >> $HOME/.phpenv/versions/5.4/etc/php.ini
cp app/config/parameters.yml.dist app/config/parameters.yml
sed -i "s/database_user:.*/database_user: $MYSQL_USER/;s/database_password:.*/database_password: $MYSQL_PASSWORD/" app/config/parameters_test.yml

composer install --prefer-source --no-interaction
app/console doctrine:migrations:migrate --env=test --no-interaction

Nominal Actual

It seems that the Australia government is beginning to end it's confusing practice of funding training providers directly and is beginning to use easily understood metrics such as ASCH (Actual Student Contact Hours) instead. This is a huge improvement over previous indicators such as Student Contact Hours which were simply not actual enough and much too easy to fudge.

In fact, the improvement is so great that I suggest the government enforce the practice of putting "actual" in front of every adjective it deals with.

For those who insist that things like "actual" hours is too restrictive, the government has also provided another metric. Which is my personal favourite. We now have Nominal ASCH (or Nominal Actual Student Contact Hours)1

1. Actual thing


So I'm going to Morocco today. In a few hours. I didn't get to bed super early, as often happens with flying around the world times. But I set my alarm for 6am and felt happy with things. At about 5am I woke up to a strange smell in my room. My room is very small. A bit bigger than a queen sized bed. And I sleep in a loft bed. So I'm not always sure exactly what's happening on the ground. I thought that the dog I am minding had dropped such a bad one that it had woken me up. So I opened the window, sleepily. The smell did not diminish. After some time, I decided it must be vomit. I waited a little longer just to be sure. Eventually, I climbed down out from bed. I found a rather deep pool of wee had collected in the lower end of my room. I'd estimate about 10 litres. I'm not sure how this is possible. It is puzzling. But I mopped it up nonetheless.

Planet-huggin’ Dunnies

I've just finished building a composting toilet. A few people have asked me if it's hygienic. You know, it's home-made toilet and just through together on the weekends. From now on I'm not going to go through a conversation about how composting toilets are great and are usually really safe. I'm just going to show them our commercial water recycling system. It's an Ozzi Kleen. Cost a lot of money. Uses a lot of electricity. In theory, it converts kitchen/toilet waste water into lovely clean water. In practice, it jams a lot and dumps a lot of random shit (literally) into our nice native garden.

Just now, for instance, the system alarm went off. The buzzer is about 500 dB of whine (right above poor little Nina's bed), letting us know the water recycling is somehow unhappy. I often have to go check on the system and give it some encouragement. Today was a little worse than usual. All the compartments were full of liquefied shit. And it was blocking most of the passages, and wasn't getting pumped out of the final tank. This is both good and bad. You don't really want to pump 100 of litres of shit onto your garden. But then, you kind of have no alternative. The trick is, once you have mixed your shit with 1000s of litres of previously clean water what do you do when the system to process that water fails. Every month or so.

Well, after some investigation I decided I'd just have to try and pump the shit out onto the garden. Nina won't be back for another week, so I figured it shouldn't be too bad. So I filled up the final tank with water to dilute the shit enough to get through the pump. Then I got the pump going. Then the pumped got blocked again. So I turned off the whole system at the switch AND the circuit board. Because I'm not an idiot. Then I detached the pump from the outflow hoses to reduce the resistance. Then I turned the power back on at the circuit board and then the switch. I got sprayed square in the face by a shit-load of mildly diluted shit-water. I watched for a while, as shit-water sprayed about 4 metres up in the air, over the whole garden. Then I switched the system of again. Closed the cover on the recycling system to stop the electricals from getting all shitted up. And turned it backed on again. It sprayed for a while. Then it felt better.

The garden has got shit sprayed all over it, and also had shit-water evenly pumped across it by our carefully laid irrigation hoses. There is not a square foot of the garden which isn't a serious health hazard. And people should probably avoid being near me for a while as well.

Next time people suggest my dry composting toilet is a health hazard because it wasn't installed by professionals, I'm going to ask them to read this post and then come back to me.

Mud brick toilet

Buying Films

The other day I tried to by a film with iTunes. I tried buy movies for money every few months to see if it's possible yet. I know other people do it, but it's nevert worked for me. Usually some about having the wrong operating system or the wrong media player or the wrong codec. This time I spent $6.99 for some GI Joe film. I tried to download it on my poor old 3G dongle and probably spent another $10 on download quota. I was using an Apple TV which I friend gave us, so I thought we could watch it on the TV proper instead of mushed onto my bedroom.

After 3 hours it was downloaded and I got ready to watch it. It spent a long time trying to play. Eventually it said "You need a TV which is HDCP compatible" or some other nonsense. The TV is almost 3 years old, so fair enough I should have to buy a new one if I am keen to pay for films instead of pirating them. However, I didn't have time to pop down to the TV shop and buy a new TV so instead I just watched some pirated movie, which had been downloaded on a proper internet connection some time previously.

Every time I try to pay for popular culture I end up coming to the same conclusion. It's sufficiently difficult for edge cases that I wouldn't bother. And for some reason, I'm usually and edge case. Either Linux issues, Mac issues, slow computer issues, slow internet issues or issues with medieval TVs from 2010. I have many experiences now of paying for films and music, but never actually getting to watch or listen to it. Or listening to it for a while, but then being told I can't anymore because I got a new computer.

This is definitely not to imply we entitled to consume popular culture for free until it becomes easy to pay for it. I don't think we are entitled to anything. However, consuming popular culture for free is incredible easy, reliable, consistent, fast, flexible and cheap. The sanctioned alternatives are none of those things. And I don't actually have any ethical issues with illegal bit copying. I prefer paying for things, because I quite like about trade. I'm happy to give talented rich people more money if they find it affirming to receive more money. But in the scheme of things, it doesn't seem enormously important.

If paying for things was only slightly more difficult than getting those things for free, I think I would try paying for them. And one day soon it will probably happen.

Chosen with Twitter Bootstrap

Combining Chosen and Bootstrap needs some tweaks to get the widgets to match.

.chzn-container-single .chzn-single {
  padding: 3px 6px;

.chzn-container-single .chzn-single div b {
  background-position-y: 6px;

.chzn-container-active.chzn-with-drop .chzn-single div b {
  background-position-y: 6px;

.chzn-container-single .chzn-single abbr {
  height: 15px;
  background-position-y: 5px;

.chzn-container-single .chzn-single abbr:hover {
  background-position-y: 5px;

.control-group .controls {
  min-height: 40px;

Setting up CircleCI with Symfony 2.3

I've just set up my latest Symfony project on CircleCI and it's working really well. CircleCI is very good, and the staff are amazingly helpful (even though I haven't given them any money yet). I spent a morning trying to set up Travis, without any luck. Seems to be some issue with private repos owned by organisations.

If you're trying to do your parameters the new Symfony 2.3 way, it takes a little extra work. And if your tests need the database, it takes a tiny bit more.


    version: 5.4.21
    - composer install --prefer-source --no-interaction
    - cp app/config/ app/config/parameters_test.yml
    - app/console doctrine:database:drop --env=test --no-interaction --force
    - app/console doctrine:database:create --env=test --no-interaction
    - app/console doctrine:migrations:migrate --env=test --no-interaction


  database_name: circle_test
  database_user: ubuntu
  database_password: null

Using environment variables didn't work that well for me, because I've got a local testing environment as well. So keeping two versions (local and CircleCI) of the testing parameters file seemed to work better. I'll still probably use environment variables for production, although that would be something else that didn't get tested.

Integrating Hero Framework accounts with Vanilla Forum using jsConnect

This is something of a hack, but it is pretty quick and easy. I've never used Smarty before, but it's pretty flexible (and slightly evil).

I put this in a Hero template called authenticate.thtml and mapped it to /authenticate. I installed the jsConnect module for Vanilla, set the secret and it was basically done. Seems to work for regular and embedded forums.

{assign var=secret value='985d2f9eb57a8b55db3c04c20272bce9308764b0'}
{assign var=client_id value=$smarty.get.client_id}
{assign var=callback value=$smarty.get.callback}

{if $logged_in}
  {assign var=member value=['uniqueid'=>$,'name'=>$member.first_name|cat:' '|cat:$member.last_name, 'email'=>$, 'roles'=>'member']}
  {assign var=empty value=ksort($member)}

  {$member['signature'] = $member|@http_build_query|cat:$secret|@sha1}

  {$member['client_id'] = $client_id}
  {assign var=member value=['name'=>'', 'photourl'=>'']}


Adam & Steve

It was Adam and Eve, not Adam and Steve

You don't hear this one so often these days, but for a while it felt like the theological backbone of a lot of Christian anti-homosexual sentiment. It always annoyed me. Rhyming two words together is awesome and funny, but it does not constitute a defence of totalitarian heteronormativity.

Build your house on the sand

It turns out you can build your house on the sand after all. I'm not sure what the consequences of discovering this are for my faith.

Loose sand will provide allowable bearing pressures up to 100 kPa. This conforms with the minimum requirement for bearing pressures of 100 kPa pursuant to AS 1684 Section 2 and AS 2870 Clause 6.5.2(a).

Template Errors with Hero CMS

Just had an issue with Smarty choking in Hero CMS. It said it couldn't find the frontpage.thml template. After trawling through Hero, CodeIgniter and Smart code I finally found out that there needs to be a writeable/template_compile directory or Smarty initialization will silently fail (until you need it).