Listeners in symfony2: Login listener for Cart merging

I have developed a cart system in symfony2, and one thing that I wanted to do is storing items in the cart while you are logged out in session (or cookies, as you like) and when the user logs in, merge the existing cart user may have, with the session one. How to do that is yet to be decided (in business logic terms) but the skeleton on how to do that is what I’m going to explain:

First of all, Symfony2 has a nice event system that launches events in lots of points in the application. One of those is when a user logs in.
So in my Cart bundle, I have to define a service that will be listening to this event. First of all, I did that in src/Namespace/CartBundle/Resources/config/services.yml
(note that you have to load this configuration in Bundle’s DependencyInjection, which symfony already does if you create the bundle with the command line tool).

I configured the service as follows:


    # name of the service (a namespace, dot and the name separated by underscores)

        # this will be the Listener class, saved in a Listener Directory for better readability,
        # but can be stored anywhere.
        # naming conventions say that the classname should be suffixed with Listener
        class: Namespace\CartBundle\Listener\LoginListener

        # this is optional - you can give the listener other services as parameters. I needed
        # doctrine, session, service_container (to get user) and my own service called cart.session which
        # handles storing the cart in session and retrieving it.
        arguments: [ @doctrine, @session, @service_container, @cart.session ]

        #  this three parameters are required.
        # - The name is for this service to know that will be listening events.
        # - The event name is in this case the security component
        # - The method is the name of the method that we will implement in LoginListener class
            - { name: kernel.event_listener, event: security.interactive_login, method: onLogin }

Once we have our service defined, we have to implement it. As we defined, we create the class in Namespace/CartBundle/Listener/LoginListener.php


namespace Namespace\CartBundle\Listener;

use Namespace\CartBundle\Entity\Cart;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Bundle\DoctrineBundle\Registry as Doctrine;
use Symfony\Component\HttpFoundation\Session;

class LoginListener
    protected $doctrine;
    protected $session;
    protected $sessionCart;
    protected $container;

    public function __construct(Doctrine $doctrine, Session $session, $container, $sessionCart )
        $this->doctrine = $doctrine;
        $this->session = $session;
        $this->sessionCart = $sessionCart;
        $this->container = $container;


    public function onLogin(InteractiveLoginEvent $event)
        $em = $this->doctrine->getEntityManager();
        $user = $this->container->get('security.context')->getToken()->getUser();
        //your stuff here...

Now the onLogin method will be called every time a user logs in. So we can do whatever we want, in my case the cart merging.

Twig debug in Symfony 2

Recently I started using Symfony2 with the twig template engine. After the initial phase of adaptation, it’s being very useful to write templates faster, but everything has a downside: I was able to debug php with xDebug in templates, and now I lost that with twig.

So, next thing that comes to mind is the classical var_dump(), which in Twig is symply dump(). But it’s an extension, it does not come activated by default.

As we see in Symfony Documentation, you have to enable the Twig_Extension_Debug as a service in config.yml (or config_dev.yml, of course):

        class:        Twig_Extension_Debug
             - { name: 'twig.extension' }

So, after we do that, you can do a var_dump (Twig uses php’s var_dump internally with the function dump() as follows:

{{ debug(var) }}

and the variable “var” will be dumped. If you call dump() without parameters, Twig will dump all template available variables.

According to documentation, you can enclose the statement between “pre” so output looks more friendly.

{{ debug(var) }}

But, First thing I got was an error. When I tried to dump an array of objects, Twig was crashing and all I saw was a blank page. Note that my each of my objects in the array, had a collection of other objects, which also had a reference to the parent object (Manytoone bidirectional association). I don’t remember why I thought of that, but after a while I tried to remove the inverse side of the association, so the collecion of objects had no reference back.
Doing that, Twig was able to display again the dump of the object, so my guess was that with bidirectional associations, Twig’s dump is not working.

Knowing that now I am more careful using it, but in any other cases I found it working as expected, so at least is a way to see what resources you have available in a Twig template!

(if you know how to overcome this bidirectional association problem, let me know!)

Helpers in Zend Framework: Action Helpers

Usually we need some pieces of code to share between controllers, for translations, dealing with json, urls, etc.

In order to accomplish that, we need to create an Action helper. First thing is deciding where we will put our helpers, and for this example I will be using


But any location that makes sense to you will be fine.

Then we need to tell the helper broker ( where our helpers will be. I’m doing it in bootstrap.php, but can be done in the front controller.

     * Initialize helpers path
    protected function _initHelper(){
        APPLICATION_PATH .'/controllers/helpers');

Then we proceed to create the helper itself. I needed a helper to deal with ftp files (downloading, uploading…) because I need this in many controllers of my application. So I will create a Ftp helper:


class Zend_Controller_Action_Helper_Ftp extends
    function connect()

If you take a look to the addpath() function we used in bootstrap, it accepts a second parameter “prefix” that its used to change the prefix “Zend_Controller_Action_Helper” to a custom one. I used the default here, but feel free to name them as you like.

Now we can use our helper within a controller, so add a call to our helper in any action:


Now call your action from the browser, and you should see the message “connected!”. Now you can start extracting code that you will use in many places in your controllers and put it in your helpers!

Zend Framework 1.11 and Doctrine 2.2.x integration

Quickly integrate Doctrine 2.2.x (used 2.2.1) into Zend Framework 1.11:

I will assume you have a working installation of Zend Framework. If not, go to Zend Framework “getting started” and create a project, then continue here.

  1. Download Doctrine ( and copy contents of Doctrine folder into


    Copy contents of Doctrine’s bin folder into ZF bin folder. (doctrine, doctrine.bat and doctrine.php)

  2. Edit the Bootsraping file:

    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
         * generate registry
         * @return Zend_Registry
        protected function _initRegistry(){
            $registry = Zend_Registry::getInstance();
            return $registry;
         * Register namespace Default_
         * @return Zend_Application_Module_Autoloader
        protected function _initAutoload()
            $autoloader = new Zend_Application_Module_Autoloader(array(
                'namespace' => 'Default_',
                'basePath'  => dirname(__FILE__),
            return $autoloader;
         * Initialize Doctrine
         * @return Doctrine_Manager
        public function _initDoctrine() {
            // include and register Doctrine's class loader
            $classLoader = new \Doctrine\Common\ClassLoader(
                APPLICATION_PATH . '/../library/'
            // create the Doctrine configuration
            $config = new \Doctrine\ORM\Configuration();
            // setting the cache ( to ArrayCache. Take a look at
            // the Doctrine manual for different options ! )
            $cache = new \Doctrine\Common\Cache\ArrayCache;
            // choosing the driver for our database schema
            // we'll use annotations
            $driver = $config->newDefaultAnnotationDriver(
                APPLICATION_PATH . '/models'
            // set the proxy dir and set some options
            $config->setProxyDir(APPLICATION_PATH . '/models/Proxies');
            // now create the entity manager and use the connection
            // settings we defined in our application.ini
            $connectionSettings = $this->getOption('doctrine');
            $conn = array(
                'driver'    => $connectionSettings['conn']['driv'],
                'user'      => $connectionSettings['conn']['user'],
                'password'  => $connectionSettings['conn']['pass'],
                'dbname'    => $connectionSettings['conn']['dbname'],
                'host'      => $connectionSettings['conn']['host']
            $entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);
            // push the entity manager into our registry for later use
            $registry = Zend_Registry::getInstance();
            $registry->entitymanager = $entityManager;
            return $entityManager;
  3. Edit application/configs/application.ini and add the database configuration (MySQL database in this case, will be different if you are using another option): = ''
    doctrine.conn.user = 'root'
    doctrine.conn.pass = ''
    doctrine.conn.driv = 'pdo_mysql'
    doctrine.conn.dbname = 'databasename'
    doctrine.path.models = APPLICATION_PATH "/models"
  4. Edit doctrine.php and put this contents:

    define('APPLICATION_ENV', 'development');
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
    set_include_path(implode(PATH_SEPARATOR, array(
        realpath(APPLICATION_PATH . '/../library'),
    // Doctrine and Symfony Classes
    require_once 'Doctrine/Common/ClassLoader.php';
    $classLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPLICATION_PATH . '/../library');
    $classLoader = new \Doctrine\Common\ClassLoader('Symfony', APPLICATION_PATH . '/../library/Doctrine');
    $classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models');
    // Zend Components
    require_once 'Zend/Application.php';
    // Create application
    $application = new Zend_Application(
        APPLICATION_PATH . '/configs/application.ini'
    // bootstrap doctrine
    $em = $application->getBootstrap()->getResource('doctrine');
    // generate the Doctrine HelperSet
    $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
        'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
        'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
  5. Now you can execute Doctrine’s from CLI and test that the correct version appears and that is functional:

    php doctrine.php 
  6. Now let’s create database tables from entities. Let’s create an entity, then execute doctrine command to create database table: Create application/models/User.php
     * @Entity
     * @Table(name="users")
    class Default_Model_User
         * @Id @Column(type="integer")
         * @GeneratedValue(strategy="AUTO")
        private $id;
        /** @Column(type="string") */
        private $name;
        public function setName($string) {
            $this->name = $string;
            return true;

    Then, execute the command from CLI:

    php doctrine.php orm:schema-tool:create

    This should have created the table users with the two columns configured in our model’s annotations.

    If you want to see the SQL executed to accomplish this, execute:

    php doctrine.php orm:schema-tool:create –dump-sql

    To learn more about doctrine cli interface, refer to

  7. Now we can execute some code in a controller to test that we can persist data using doctrine:

    Edit a controller and add:

    First, in the controller we need to get Doctrine’s Entity Manager, we can avoid repeationg this code initializing the controller like:

    public function init()
            /* Initialize action controller here */
            $registry = Zend_Registry::getInstance();
            $this->_em = $registry->entitymanager;

    Then, creating an action (will use indexAction from IndexController to show it:

    public function indexAction()
    $testEntity = new Default_Model_User;
    $testEntity->setName('Hector Pinol');

    So now call this action from a browser and we should have a row in DB with name “Hector Pinol” !

    Note that No data is actually persisted until we call “flush” method. Doctrine runs all “persisted” objects as a transaction when we call this method.

Programmatically handle reindex process in Magento

Recently I had a problem when importing large amounts of data into products (about 9000) in Magento. It took a lot of time, and it was because the indexes were configured to update on save, so each save was launching the reindex process, and what we wanted was only a reindex when the import process was completed.

So the solution was to change “update on save” to “manual”. First of all, I took a look into shell/indexer.php to see what magento does with indexes, and then refer to app/code/core/Mage/Index/*

In shell/indexer.php we can see that it gets the singleton instance of indexer with a protected function, _getIndexer

     * Get Indexer instance
     * @return Mage_Index_Model_Indexer
    protected function _getIndexer()
        return Mage::getSingleton('index/indexer');

Then, we can see two models in Indexer module that are interesting for us now, Model/Indexer.php and Model/Process.php.

Having The indexer model instantiated, we can get a collection with all the processes and then loop through them changing their modes.
We will only need getProcessesCollection() from Mage_Index_Model_Indexer, and reindexEverything() from Mage_Index_Model_Process.

Also, as we want to leave things as they were, we will store the processes modes to restore them later:
So, this is what we will need to do:

         $processes = array();
         $indexer = Mage::getSingleton('index/indexer');
         foreach ($indexer->getProcessesCollection() as $process) {
             //store current process mode
             $processes[$process->getIndexerCode()] = $process->getMode();
             //set it to manual, if not manual yet.
             if($process->getMode() != Mage_Index_Model_Process::MODE_MANUAL){
         //save transaction (I was using transactions, do your stuff, call another method, etc...)

         //reindex all and set indexes as they were
         foreach ($indexer->getProcessesCollection() as $process) {

And that’s it! you will notice that the transaction (or whatever you were doing between setting indexes to manual and then restablishing them) is now a lot faster, and I mean A LOT!

Magento 1.6 sample data error sales/quote_shipping_rate

I’ve noticed that there are a lot of searches and posts around asking for a problem when installing Magento 1.6.x with sample data provided by magento.

It appears that the error is:

a:5:{i:0;s:163:"Error in file: "/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.9.16-0.9.17.php" - Can't retrieve entity config: sales/quote_shipping_rate";i:1;s:888:"#0 /app/code/core/Mage/Core/Model/Resource/Setup.php(645): Mage::exception('Mage_Core', 'Error in file: ...')
#1 /app/code/core/Mage/Core/Model/Resource/Setup.php(437): Mage_Core_Model_Resource_Setup->_modifyResourceDb('upgrade', '0.9.14', '')
#2 /app/code/core/Mage/Core/Model/Resource/Setup.php(320): Mage_Core_Model_Resource_Setup->_upgradeResourceDb('0.9.14', '')
#3 /app/code/core/Mage/Core/Model/Resource/Setup.php(235): Mage_Core_Model_Resource_Setup->applyUpdates()
#4 /app/code/core/Mage/Core/Model/App.php(412): Mage_Core_Model_Resource_Setup::applyAllUpdates()
#5 /app/code/core/Mage/Core/Model/App.php(338): Mage_Core_Model_App->_initModules()
#6 /app/Mage.php(640): Mage_Core_Model_App->run(Array)
#7 /index.php(80): Mage::run('', 'store')
#8 {main}";s:3:"url";s:36:"/index.php/install/wizard/installDb/";s:11:"script_name";s:10:"/index.php";s:4:"skin";s:7:"default";}

This happens when using old sample data. The confusion comes by downloading the wrong version from Magento site (which can get a bit confusing when following the instructions).

So, delete all tables in the database you are using, download an execute the correct 1.6 Magento sample data script (available here: make sure to choose the right one) and then execute the magento install again. Also, change the media folder to the one available in the 1.6 package, if you previously copied it from the wrong 1.2 one.

And that’s it, you are good to go now with Magento 1.6, with sample data ready to play with!

Xdebug remote debugger

Xdebug remote debugger will enable you to debug code executed in a remote machine. It is a common development setup to work from a Windows, Linux or Mac workstation and having your webserver in a remote Linux machine with apache, that can be a virtual machine in your own workstation, or in another physical remote machine.
With Xdebug you will be able from your IDE to watch call stack, variables, change variable values in run time, add breakpoints, etc. More information and less hassle than using echoes, prints or Mage::log (when working with Magento) for the same purpose.

To install and enable Xdebug remote debugger you have to Continue reading

Magento: Custom configuration tab in system section in admin panel

Magento has a very powerful admin configuration system. It allows you to create config forms to be able to configure your custom modules from admin panel, also to enable users to modify it.

We are focusing now in creating a new tab in system section.
To start, you have to create system.xml file in app/code/local///etc/system.xml

For our example we will be using the module “MyModule”

To create a Tab:

        <tab_name translate="label" module="mymodule">
            <label>MyModule Configuration</label>

Note that “tab_name” is a name of your choice, and we will Continue reading