Using Symfony Dependency Injection in Drupal 7: Software Engineering in Drupal

Posted by alexmoreno on Sun, 20/04/2014 - 14:42

I still remember in a previous job discussing with a partner about doing things the proper way, using coding standards, commenting what you are doing, ... giving your code some love in definitive.

I'm still amazed of his answer, basically he was refusing to doing things the right way (the only way) because using his way he was a lot quicker... Well, probably, but on the meantime modifying some of the crap we had there (not just him, I have to say) could take us like 4 to 10 times more time.

That's basically because you needed to understand what was going on that code... and I promise you, when you have a single function of around 3000 lines, no comments, things happening without too much logic, no standards, dozens of lines commented... that is not easy at all, even for the owners of that code. That's why you use Coding Standards, code reviews, Pull Requests and all that stuff in serious environments of Software Engineering.

Anyway, developing using the Object Oriented paradigm is quite a lot more organized than doing it using simply .modules and .inc files in Drupal. It does not matter how organized you are, at the end you'll end with lots of files and functions in a nightmare to understand for third developers. And, when you are working in Enterprise environments, with lots of people sharing and creating code, things like coding standards and doing things the proper way becomes a very serious thing.

Solution? As I said, using Object Oriented programming paradigm. In Drupal is easy enough since Drupal 7 allows you to add directly classes included in .php, .inc/* files. Simply do:

files[] = lib/MyClass.php

Well, that's easy enough... but there is a better more sophisticated way of doint it: Symfony Dependency Injection.

There are some good advantages of doing this that way. First and maybe most important, you are starting to be ready for Drupal 8. Second one, you objects can use Lazy loading. That's a great thing, basically means that your objects will be using the Proxy Pattern, which allows your code to load things only when they are going to be needed.

That's a good trick to improve your Drupal site performance from your own code (a big big percentage of performance problems are derivated from bad coding practices).

Want more advantages? Did I say that you make your code ready to Drupal 8? Well, that's just the begining. Starting to use Symfony components like Drupal Symfony inject open us a world of thousands of bundles ready to use from Symfony, and just using them through Composer. Win win :-).

We will need basically two modules, Drupal Symfony inject which a college is developing here, in Capgemini, and Composer Manager as it is a dependancy:

It is important you install them using drush, so the vendors folder will be created for you (with all the dependencies that the module has):

drush pm-enable drupal_symfony_inject --y

Once installed, DSI makes you available three new hooks:

  • _namespace_register()
  • _symfony_yaml_config()
  • _symfony_yaml_config_params()

The first one, _namespace_register, allows you to register your new classes like that:

Now we will need to add the config.yaml, where we will declare the classes we will be using, parameters, etc...

Now you need to define your classes in the yaml file. Create the file in config/yaml/config.yaml and declare there the classes you'll be using:

And finally, the parameters:

That's it, Drupal is ready to use the Symfony Dependency Injection component. Lets move to create a new class, for example, CruiseHunter:

That's one of the Abstract classes I use in CruiseHunter from which I inherit to fetch the different contents the Cruise crawler uses. It is a lot more organized, it declares a common mechanism to fetch information from the crawler, etc...

Well, now that we have the class, we need to be able to import it and use it. And here is where the Dependency Injection appears:

Once you have all in place, you have to rebuild the symfony components you have just built:

drush rsc

If you see some error, you made a mistake, probably in your yaml. If you see something like this:

Symfony DI container compiled and cached successfully !!!

Congratulations, you are ready to use your new Symfony components :-).

Related articles: