Gittern — Making git like music for PHP’s ears

In Sweden we have a saying: One time is no time, two times is a habit. We’re hugely excited say that by that reckoning, we now have an open source habit at E-butik.se! Over the last months some of us here have been hinting at a cool new library we’ve been working on from time to time. The time has finally come to unveil it to the world! Gittern is a PHP library for reading from and writing to Git repositories. Without using the git binary.

We’ve got support for many things common in Git repositories. There’s your blobs, trees and commits of course, which can be stored as loose objects or in packfiles. We eat packed refs for breakfast. We also have support for using the Git index, which is a real treat if you’d like to make changes to a repo over multiple HTTP requests.

Now, it wouldn’t be much like music for PHP’s ears if the code wasn’t good, and if we’re allowed to say so ourselves, the code is pretty dang good. The code is nicely decoupled and dependency injected, which means that if you’d like to you can switch out a lot of our implementations for your own. Perhaps you’d like to cache your Git objects in Redis? Go ahead. Separate indexes for separate branches? Very much doable (indeed, we’re doing it internally).

As if all of this wasn’t enough, we’ve sweetened the pot just a little bit more. You know Gaufrette, the awesome filesystem abstraction library from the fine folks at KnpLabs? We’ve got adapters for it. That means super-easy access to Git as if it’s just another kind of filesystem!

We know that we’re not first into the field with this one. Similar libraries exist for other languages (like grit for Ruby, and dulwich for Python), and indeed for PHP too, but we’d like to think that our dependency injected and decoupled approach brings something new at least to the PHP table.

Gittern is licensed under the MIT License, and the code is available at GitHub: e-butik / Gittern. To install, however, we’d recommend using Composer, since that’ll handle all of your dependencies. Gittern is available at Packagist as e-butik/gittern.

By the way, if you think that stuff like this is cool, we’d like to remind you that we get paid for working on stuff just like this. If getting paid to work on cool things like this sounds interesting to you, you should definitely shoot us an e-mail.

Quick tip: Symfony2 rewrite rules

Another quick tip for the (to our knowledge) best rewrite rules for Symfony2 with different web servers:

Apache

This one is included in the Symfony2 Standard Edition, but if we’re compiling a list, it still bears mentioning.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>

Lighttpd (> 1.4.24)

url.rewrite-if-not-file = (
 "^/(?!app_[dev|test]+\.php/)[^\?]*(\?.*)?$" => "/app.php$1"
)

Nginx

# strip app.php/ prefix if it is present
rewrite ^/app\.php/?(.*)$ /$1 permanent;

location / {
    index app.php;
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /app.php/$1 last;
}

Quick MongoDB tip: Copying databases

How do you copy a database between two MongoDB servers? One way is to use mongodump and mongorestore to dump the database into files which you then transfer and restore, and that works fine.

A better way however is to use the db.copyDatabase command. This removes the need for creating any temporary files.

The only downside is that your destination server needs to be able to connect to the source server, but that’s nothing that a little SSH tunneling can’t take care of.

Read more about it on the Copy Database Commands page of the MongoDB docs.

Quick Symfony2 tip: Overriding arguments when using a parent service

Parent services are great. However, sometimes you want to be able to override the arguments to the parent service, not just append to them.

After a bit of digging, it turns out there’s essentially two ways of doing that. Either you can do it in your bundle extension class, by getting the definition, and just calling replaceArgument. However, having to get your definitions and making changes to them in your extension class gets old really quickly.

What you can do instead is to follow a specific naming convention for the keys of your arguments, index_n, where n is the argument number to override. Using this convention, instead of the regular numerically indexed keys, will replace the argument, instead of simply appending it.

YAML example

some_child_service:
  class: %some_child_service.class%
  parent: some_parent_service
  arguments:
    index_0: "Some overridden argument"

XML example

<service class="%some_child_service.class%" parent="some_parent_service">
  <argument key="index_0">Some overridden argument</argument>
</service>

CoffeeScript is your machete in the JavaScript jungle

We started a new Javascript intensive project a few weeks ago. We’ve previously had the experience that these applications has a tendency to become quite hard to work with. Javascript can accomplish pretty neat things on the client-side. It has actually become a bit fun to code Javascript with libraries like jQuery. And from a developer’s point of view, you get some nice layers of structure with libraries like Knockout. But the actual code is still a hassle. Here CoffeScript can fill a role, that will ease your day as a developer.

You can find CoffeeScript at GitHub (of course). It has a good long one-page-documentation there with examples. Another source of information is The Little Book on CoffeeScript (oh, it’s on GitHub as well, imagine that).

It was a bit of a learning-curve to get going with CoffeeScript. I found myself frequently looking at the compiled/generated Javascript code, so that I could really verify that it was outputed as I wanted (ie, how I would have written it previously in Javascript). And it was a nag when it didnt, so it took quite a bit longer to get the code running as it should. But after a while when I got more used to the CoffeeScript way of doing things, I found myself looking less and less on the Javascript code and just relying on that CoffeeScript would get it right. Also as the project grew larger in files (classes… yeah, you can have nice classes with inheritance etc. in CoffeeScript), the readability of the CoffeeScript code really started to show. And I could focus more on writing clean code.

What made things a bit trickier was the fact that I had Knockout in the mix as well.

So, if you are shuddering at the thought of taking on “big” projects in Javascript. Give CoffeeScript a try, and see if it can help you. It did for us :)

Conditional validation using the Symfony2 Validation Component

Today we ran in to an issue (or more like an unimplemented enhancement request), where we wanted to do conditional validation.

In our use case, we had a checkbox, which is basically an enable/disable switch. We also had three text inputs, parameters to the feature enabled by the checkbox.

In this case, we wanted the validation of the inputs to depend on whether the switch was enabled.

There are a few ways to do this. You could write your own validator specifically for this purpose. You could write a callback validator, that validates the object. Both these approaches have a big drawback. Even though what all we needed was a conditional NotBlank validator, who knows what we might wish to do in the future with it? We wanted to keep the flexibility of the validation component.

It turns out that’s entirely possible, albeit a bit tricky. To illustrate, let’s imagine a petition. Your form is for entering supporters for a petition. Let’s say that you optionally allow the supporter to enter which city they live in, and that you optionally show that city on a public petition page. Something like this POPO:

<?php

class PetitionSupporter
{
  protected $name;

  protected $city;

  protected $is_city_public;

  // Setters, getters etc. are omitted for brevity
}

Now, of course it wouldn’t be much of a petition if you didn’t require names of the supporters. As for the city, like we’ve said, it’s optional. However, it makes no sense to have the city public unless something is entered.

This can be accomplished using the callback validator, getting the graph walker from the execution context, and validating a separate validation group.

<?php

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContext;

/**
 * @Assert\Callback(methods={"validateCityExistance"})
 */
class PetitionSupporter
{
  /** @Assert\NotBlank */
  protected $name;

  /** @Assert\NotBlank(groups="public_city_group") */
  protected $city;

  /** @Assert\Type(type="bool") */
  protected $is_city_public;

  public function validateCityExistance(ExecutionContext $ec)
  {
    if ($this->is_city_public) 
    {
      $ec->getGraphWalker()->walkReference($this, 'public_city_group', $ec->getPropertyPath(), true);
    }
  }

  // Setters, getters etc. are omitted for brevity
}

This way, the non-grouped assertions are always validated, and the assertions in the public_city_group group are validated if is_city_public is true.

Of course, you can have more complex validation rules, and you could also have multiple conditional groups depending on one or more of the instance variables.

Symfony Developer Meetup in Stockholm

If you’re a Swedish Symfony developer, you might have noticed that there’s something in the air. On November 17th the Swedish (or at least the one’s near Stockholm) Symfony developer community will gather for the first of our monthly meetups.

Not only is E-butik sponsoring the event with food and beer, we’re also supplying the main presenter. Your’s truly. I will speak about MongoDB (especially the Doctrine MongoDB ODM) and how we’re using it.

If you’re in the Stockholm area, and interested in Symfony, you should definitely go.

For more information, visit the Symfony-se Google Group.

Symfony’s Serializer Component

Symfony Serializer, Symfony2 Component, is a PHP library that can serialize custom objects to and from its object-form and whatever custom format you’d want (json or xml for instance), through the help of Normalizer and Encoder classes.

It is a common use-case to present various objects in other formats, the serializer component provides a good way to manage that. Be it returning a json-representation of some class in an ajax-request or an xml-representation in a REST web service, you can have a common ground to rely on in the serializer-component.

Usage

  • The job of a Normalizer is to transform an object (a database entity for instance) to a representation in PHP array form.
  • The job of an Encoder is to encode a PHP array to a desired format. The component includes a JsonEncoder- and a XmlEncoder-class.
  • The Serializer is the glue and logic that manages all this.

Pass in an array of normalizers and an array of format-name/encoder-pairs in the constructor.

use Symfony\Component\Serializer\Serializer,
    Symfony\Component\Serializer\Encoder\JsonEncoder,
    Symfony\Component\Serializer\Encoder\XmlEncoder;

$serializer = new Serializer(array(
    new FooNormalizer,
    new BarNormalizer
  ), array(
    'ajax_json' => new JsonEncoder(),
    'api_xml' => new XmlEncoder()
  ));

The normalizers above can understand and transform Foo and Bar objects.

When you have this, you can get either an xml or a json-representation of the above objects, depending on what format you ask for.

Lets say $foo is a single object instance, while $bars is a collection of entities, and $some_array is just a normal array, which has no need of a normalizer. It will still be json encoded though.

The BarNormalizer class could look something like this

namespace Acme\DemoBundle\Normalizer;

use Symfony\Component\Serializer\Normalizer\SerializerAwareNormalizer;
use Acme\DemoBundle\Entity\Bar;

class BarNormalizer extends SerializerAwareNormalizer
{
  function normalize($object, $format = null)
  {
    return array(
      'name' => $object->getName(), 
    );
  }

  function denormalize($data, $class, $format = null) {}

  function supportsNormalization($data, $format = null)
  {
    return $data instanceof Bar;
  }

  function supportsDenormalization($data, $type, $format = null) 
  {
    return false;
  }
}

It’s interesting to note that due to the $format parameter, you can have multiple serializers for the same class without collision, if you need different representations for different purposes.

Once all of your normalizers and encoders are in place, using the serializer is simple.

$json = $serializer
  ->serialize(array(
    'foo' => $foo,
    'bars' => array_values($bars->toArray()),
    'baz' => $some_array
  ), 'ajax_json');

In conclusion, using the serializer component you get full flexibility to handle serialization in a simple manner, while still retaining a good separation of concerns.

P.S. In certain use cases, you might also be interested in JMSSerializerBundle, which uses annotations to specify how a given class is serialized.

Get a better punch on JavaScript with Knockout

We love the MVC1 pattern. It’s a great tool to write clean code, and when using a framework like Symfony2, MVC is effortless. However, one part of the code likes very much to resist any effort of using MVC. The javascripts in the views. There you can easily find your code in a huge mess, when the page in question is more complex. Luckily, Knockout comes to the rescue!

Knockout follows the MVVM2 pattern. It is about 1 year old, and like many cases of best practices, this design pattern provides a neat solution to certain kinds of problems. It fits very well into our way of doing things, and it might fit well into your project as well! Of course you can find it on GitHub, as everything these days.

We have found out that creating pages that follows the Observer pattern have some distinct advantages in UIs in general, and admin UIs in particular. HTML elements are registered as observers and recieve notifications on changes in an underlying data model, and can respond to those changes arbitrarily, typically to update the visual elements in the view.

Knockout isn’t a fool-proof cure for the risk of messy code. It is entirely up to you how you structure your code, as always. But at least with the help of Knockout you can avoid the many lines of Javascript code that typically is needed to update the UI, when various data variables and objects are manipulated. Knockout is just another good library to have in your toolbox, that can work as a good complement to e.g. jQuery.

If you want to learn the basics of Knockout, follow the awesome online tutorial examples on the Knockout website. Also check out Steve Sanderson’s blog-post regarding the new version, which has some very good improvements that will make it easier to have a good structure in your javascript code. Another good page is Ryan Niemeyer’s blog that is dedicated to the Knockout library.