Blogs

Development phrase of the day

If we do things that way, we are going from Spagetti Code to Lasagna Code.

Howto use Lazy Loading in Symfony2 (and Drupal 7 / 8)

Lazy Loading is a software design pattern which basically allows our classes and objects to be a lot lighter. Faster code, faster applications, less memory used in runtime. The great Martin Fowler says about Lazy Loading:

An object that doesn't contain all of the data you need but knows how to get it.

http://martinfowler.com/eaaCatalog/lazyLoad.html

The key is that your "real" objects are not going to be instantiated unless they are going to be used. How that can be achieved? Easy, with what it is called a Virtual Proxy. As in every project, you can always code your own implementation, but the key about design patterns and software engineering is to reuse as much as possible. And regarding Lazy Loading, Symfony 2 has a nice implementation called Proxy Manager Bridge, which does exactly that in Symfony 2.

Recently we discovered that our implementation of Lazy Loading was not working properly in Drupal 7. We were using a custom module which we created in Capgemini, Drupal Symfony Inject, to inject our own implementations of Symfony 2 classes in Drupal. The module works great, but for some reason the Lazy Loading was not working, the objects were always having the real implementation of the object itself instead of the proxy (for more info, check the documentation in Symfony 2 about Lazy Services).

The solution is relatively easy (not as much as finding it), and I commited a patch for that, so Drupal Symfony Inject should not have that problem anymore: https://drupal.org/node/2287081.

A different question is, how to use Lazy Loading in our projects when we are not using Symfony 2 framework but its components. One of the errors which we were doing in the Drupal Symfony Inject module was that we were not loading the Proxy Manager Bridge, which makes the integration of Proxy Manager, your code and some other Symfony 2 components.

At that point we were quite lost, not many people has done before that integration between Drupal and Symfony 2 Lazy Loading, so we had very few people to ask, even inside Capgemini itself, and even fewer documentation to consult. Fortunatelly there are some interesting pieces of code in every well designed software. I am talking about test units: https://github.com/symfony/ProxyManagerBridge/blob/master/Tests/LazyProx...

The most interesting part in lines 34 and 37:

$builder->setProxyInstantiator(new RuntimeInstantiator());

That part is essential, it will instantiate the Proxy Manager and substitute your Object with an instance of that Proxy.

We just need to do one last step, indicate that our object will use Lazy Loading:

$builder->getDefinition('your_class')->setLazy(true);

From this point, the next time you load your object:

$builder->get('your_class')

if you ask for the class of this object it will identify itself as a Lazy Proxy:

\ProxyManager\Proxy\LazyLoadingInterface

 That state will remain until you ask the object to return something, basically when you use one of its methods:

$your_object->doSomething();

Now that object will say that he is the real class, something like that:

\ProxyManagerBridgeFooClass

 

More information:

Profiling PHP and Drupal with XDebug (In OSX)

Problems with a rogue app you built (maybe not you)?

Just some links which I found useful in order to debug/profiling your app:

Run it in you Mac with OSX:

Sometimes you need your profiler to be executed everytime. You can do that with this:

xdebug.profiler_enable=On

This is my whole xdebug.ini:

; Enable xdebug extension module

zend_extension=/usr/lib64/php/modules/xdebug.so

xdebug.remote_enable=1

xdebug.remote_host=192.168.33.1

xdebug.remote_port=9000

xdebug.remote_mode=req

xdebug.remote_connect_back=0

xdebug.profiler_enable=On

xdebug.profiler_output_dir=/www/profiling_data

xdebug.profiler_enable_trigger=1

 

Other general links:

 

Composer and Symfony2 in Drupal 7

categorias: 

Developer definition

Programmer: an organism that turns caffeine and pizza into software :-D

categorias: 

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

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:

First steps migrating to Drupal 8: drush

There we go. First steps in upgrading (or should I say migrating?) to Drupal 8. Drush is an incredible valuable tool, so this will be basically my first step.

Install the last version of drush, at least Drush 7 which includes support for Drupal8. If you already have drush and don't want to play with current versions, you can download drush 7 via git, and place it in /usr/local/drush-7, for example. Then, create a symlink like that:

ln -s /usr/local/drush/drush /usr/local/bin/drush7

This will create a second version to play safely. Now you also need to install composer:

curl -sS https://getcomposer.org/installer | php

and then, run install inside the new drush folder.

More information about next steps can be found here (basically information about Migrate module, which I will need to study in order to achieve the next steps):

The last steps will be... starting to develop in Drupal 8 :-):

 

Migrating to Drupal 7 (and Drupal 8)

Well, that's it. ProgramadoresWeb is now in Drupal 7. I have been also experimenting in D8, as probably in a very few time I'll be upgrading to D8.

Why migrating to D8? Basically this site is quite simple, there are not too much modules installed and I can afford to migrate some of them or help to migrate them into D8. Of course the main reason is less altruistic: knowledge :-)

categorias: 

Changing Short project name in a Drupal.org project

Typical problem, you have just gained your full project permissions role in Drupal.org, and you make your first mess... you have promoted your so loved first project without changing the Short project name.

Well, you have a problem, but not too big. Drupal.org will not allow you to rename your Short project name, so you will have to create a new one if you don't want to have an ugly url like that: https://drupal.org/project/2062343

Fortunately git can help. You will simply have to:

  • Create a new project, sandbox or not,
  • Go to the "Version control tab" and get the url of your new git project, something like: [email protected]:project/2062343.git
  • Go to the folder of your old sandbox, the project in which you cannot change the Short name, and change the remote for this folder. For my url example, the command will be: git remote set-url origin [email protected]:project/2062343.git
  • Nearly finished. You probably have to merge, as you will have to make your first commit in the new project: git pull
  • And finally, git push origin master will get the job done.
  • Remember to create a new branch, like 6.x-1.x and commit to that one to create a new official, downlodable release of your module. Congratulations :-).

 

Next time, take it easy cowboy ;-).

 

More information:

 

Drupal form api select elements returning integers instead of string

I always have the same problem when using select forms, and I always forget the solution.

Instead of returning an array, like: return $competitions; you have to return a drupal_map_assoc, like this: return drupal_map_assoc($competitions);

Otherwise, when selecting the form in hook_submit you will get a number, instead of a human readable string.

categorias: