Doctrine Symfony2 – EntityManager Closed – Always enclose flush inside a try catch block and log exceptions

Hi,

This is not a tutorial but a good practice advice, about flush of objects in Doctrine with Symfony2.
A few days ago, we have encountered a strange error: “Entity Manager Closed”.

After several minutes of research, we found the problem.

We were trying to save a NULL value inside a NOT NULL field in our database, making the flush of objects failing.
When flush fails, it creates an exception like this:

 Doctrine\ORM\Exception "The EntityManager is closed".

When this error occurs, then entityManager is voluntarily closed, and following “flush” will not work.

The good practice is to systematically enclose all flush, inside a try catch block, and log the exception message and trace.
Let’s see an example.

    try {
        $em->flush();
    } catch (\Exception $e) {
        $msg = '### Message ### \n'.$e->getMessage().'\n### Trace ### \n'.$e->getTraceAsString();
        $this->container->get('logger')->critical($msg);
        // Here put you logic now you now that the flush has failed and all subsequent flush will fail as well
    }

This is a good practice that you’ll have to use in your further codes.

Doctrine Symfony2 – EntityManager Closed – Always enclose flush inside a try catch block and log exceptions

Why type casting of values is important in php?

What is the difference between:

$var = (string) "a";
//And
$var = "a";

I sometimes come into debate with some developers, on the need to cast php variables values.

There are no clear documentations on this subject, so this is my interpretation.

1. Can php cast variables?
First of all, you have to know that php can not cast variables, but only values.

2. Is php an interpreted or compiled language?
Php is a on the fly compiled language, and not interpreted like many developers tell it.

It then becomes important to learn how are saved variables inside your computer.

3. How do variables are saved inside our computers?

  • When a variable is declared, in reality, we’re asking to the computer, the permission to create some space in the RAM (Random Access Memory), for this variable.
    (One space for the variable name called address, one space for its value).
  • Without RAM, our program will be unable to memorize our variables.

  • Depending on the type of declared variable, thus, a more or less memory space is allocated for the value (remember that php can’t cast a variable, just its value).

4. Then, what benefits to cast values?

  • Save time for variables assignment in memory (although negligible with our latest machines).
  • Better code clarity and readability, let me explain.

  • $varA = 'a';
    $varB = 0;
    var_dump($varA == $varB); //equals true, this is not what we expected
    

    Php first analyzes variables values and then casts them. for this comparison, it will convert ‘a’ string into integer. This will result to 0.

    One solution would be to first check the $varB type before comparison like this:

    $varA = 'a';
    $varB = 0;
    if (is_string($varB)) {
       var_dump($varA == $varB);
    }
    

    But, the best practice is to cast the values, upstream.

    $varA = (string) 'a';
    $varB = (string) 0;
    var_dump($var1 == $varB); //equals false, what we expected
    

    I see you coming!!! Of course, we could also write:

    $varA = 'a';
    $varB = '0';
    

    But in my opinion, it’s less readable.

    Everyone has its method. The main important is to test variables before using them.
    There are many other examples, but it is not the purpose of this post, if you have your opinion, you are invited to share it.

    Why type casting of values is important in php?

    Php-Mysql-Api a powerful plug-n-play Php api for Mysql database tested with codeception

    Hi everyone,

    This is my last php project and I want to share it with all of you.
    It is a simple but powerful object that gives you a php api for mysql database.

    With php-mysql-api, you will be able in 60 seconds chrono, to:
    – Access your database datas with a RESTful syntax
    – Limit access to specific ips
    – POST, GET, PUT and DELETE datas.

    It is fully tested with CodeCeption.

    The repository is here: https://github.com/edouardkombo/php-mysql-api

    I really hope it will save you a lot of time.

    Php-Mysql-Api a powerful plug-n-play Php api for Mysql database tested with codeception

    Symfony2: two fields comparison with custom validation constraints

    I’ve already written a post on how to create a custom validation constraint here (https://creativcoders.wordpress.com/2014/07/15/symfony2-tutorial-create-custom-constraint-validation-and-use-it-with-fosuserbundle/), but what if you need to validate two fields or more in your entity?

    Well, I have an entity called “Card” that stores credit cards informations and i need to check the card validity by checking the expiration month and expiration year.
    The proper way to do this is to create a custom validation constraint that we will append in our “card” entity.
    This is how the entity looks:

    <?php
    
    namespace EdouardKombo\StripePaymentBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * Card
     *
     * @ORM\Table(name="headoo_stripe_credit_card")
     * @ORM\Entity
     */
    class Card
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="number", type="integer")
         * @Assert\NotBlank(message="card.number.blank")
         * @Assert\Length(min="16", max="16", minMessage="card.number.length", maxMessage="card.number.length", exactMessage="card.number.length")
         * @Assert\Range(min="1000000000000000", max="9999999999999999", minMessage="card.number.range", maxMessage="card.number.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.number.invalid")
         */
        private $number;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="expirationMonth", type="integer")
         * @Assert\NotBlank(message="card.expiration.month.blank")
         * @Assert\Length(min="2", max="2", minMessage="card.expiration.month.length", maxMessage="card.expiration.month.length", exactMessage="card.expiration.month.length")
         * @Assert\Range(min="1", max="12", minMessage="card.expiration.month.range", maxMessage="card.expiration.month.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.expiration.month.invalid")
         */
        private $expirationMonth;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="expirationYear", type="integer")
         * @Assert\NotBlank(message="card.expiration.year.blank")
         * @Assert\Length(min="2", max="2", minMessage="card.expiration.year.length", maxMessage="card.expiration.year.length", exactMessage="card.expiration.year.length")
         * @Assert\Range(min="0", max="99", minMessage="card.expiration.year.range", maxMessage="card.expiration.month.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.expiration.year.invalid")
         */
        private $expirationYear;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="cvc", type="integer")
         * @Assert\NotBlank(message="card.cvc.blank")
         * @Assert\Length(min="3", max="4", minMessage="card.cvc.short", maxMessage="card.cvc.long", exactMessage="card.cvc.long")
         * @Assert\Range(min="1", max="9999", minMessage="card.cvc.range", maxMessage="card.cvc.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.cvc.invalid") 
         */
        private $cvc;  
    
    
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Set number
         *
         * @param integer $number
         * @return Card
         */
        public function setNumber($number)
        {
            $this->number = $number;
    
            return $this;
        }
    
        /**
         * Get number
         *
         * @return integer 
         */
        public function getNumber()
        {
            return $this->number;
        }   
    
        /**
         * Set expirationMonth
         *
         * @param integer $expirationMonth
         * @return Card
         */
        public function setExpirationMonth($expirationMonth)
        {
            $this->expirationMonth = $expirationMonth;
    
            return $this;
        }
    
        /**
         * Get expirationMonth
         *
         * @return integer 
         */
        public function getExpirationMonth()
        {
            return $this->expirationMonth;
        }
    
        /**
         * Set expirationYear
         *
         * @param integer $expirationYear
         * @return Card
         */
        public function setExpirationYear($expirationYear)
        {
            $this->expirationYear = $expirationYear;
    
            return $this;
        }
    
        /**
         * Get expirationYear
         *
         * @return integer 
         */
        public function getExpirationYear()
        {
            return $this->expirationYear;
        }
    
        /**
         * Set cvc
         *
         * @param integer $cvc
         * @return Card
         */
        public function setCvc($cvc)
        {
            $this->cvc = $cvc;
    
            return $this;
        }
    
        /**
         * Get cvc
         *
         * @return integer 
         */
        public function getCvc()
        {
            return $this->cvc;
        }   
    }
    

    Ok so to validate the expirationMonth and expirationYear properties with custom validation constraints, we will create one constraint, called “CardHasExpired”.

    • Create these files in your bundle main directory: “Validator/Constraints/CardHasExpired.php” and “Validator/Constraints/CardHasExpiredValidator.php”

    This is how will look the CardHasExpired.php field:

    <?php
    
    namespace EdouardKombo\StripePaymentBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    
    /**
     * @Annotation
     */
    class CardHasExpired extends Constraint
    {
        /**
         *
         * @var string
         */
        public $message = 'Your card has expired.';
        
        /**
         * 
         * @return string
         */
        public function validatedBy()
        {
            return 'card_has_expired';
        }
    
        /**
         * Get class constraints and properties
         * 
         * @return array
         */
        public function getTargets()
        {
            return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
        }    
    }
    

    Now, we can open the CardHasExpiredValidator.php file and we can call the properties we want from our card entity.
    This way we can validate multiple properties.

    Here, i just need to check that the expiration month and year are not outdated.
    This how our CardHasExpiredValidator.php file will look like.

    <?php
    
    namespace EdouardKombo\StripePaymentBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\ConstraintValidator;
    
    class CardHasExpiredValidator extends ConstraintValidator
    {
    
        /**
         * Method to validate
         * 
         * @param string                                  $value      Property value    
         * @param \Symfony\Component\Validator\Constraint $constraint All properties
         * 
         * @return boolean
         */
        public function validate($value, Constraint $constraint)
        {
            $date               = getdate();
            $year               = (string) $date['year'];
            $month              = (string) $date['mon'];
            
            $yearLastDigits     = substr($year, 2);
            $monthLastDigits    = $month;
            $otherFieldValue    = $this->context->getRoot()->get('expirationMonth')->getData();
            
            if (!empty($otherFieldValue) && ($value <= $yearLastDigits) && 
                    ($otherFieldValue <= $monthLastDigits)) {
                $this->context->addViolation(
                    $constraint->message,
                    array('%string%' => $value)
                );            
                return false;            
            }
            
            return true;
        }
    }
    

    Now, we have to create a service that will load our constraints.

    <?php
        edouard_kombo_stripe_payment.card.validator.card_has_expired:
            class: EdouardKombo\StripePaymentBundle\Validator\Constraints\CardHasExpiredValidator
            tags:
                - { name: validator.constraint_validator, alias: card_has_expired } 
    

    And finally, we can use our constraint directly in our card entity, and assign it to $expirationYear property.

    <?php
    
    namespace EdouardKombo\StripePaymentBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Validator\Constraints as Assert;
    use EdouardKombo\StripePaymentBundle\Validator\Constraints\CardHasExpired;
    
    
    /**
     * Card
     *
     * @ORM\Table(name="headoo_stripe_credit_card")
     * @ORM\Entity
     */
    class Card
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="number", type="integer")
         * @Assert\NotBlank(message="card.number.blank")
         * @Assert\Length(min="16", max="16", minMessage="card.number.length", maxMessage="card.number.length", exactMessage="card.number.length")
         * @Assert\Range(min="1000000000000000", max="9999999999999999", minMessage="card.number.range", maxMessage="card.number.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.number.invalid")
         */
        private $number;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="expirationMonth", type="integer")
         * @Assert\NotBlank(message="card.expiration.month.blank")
         * @Assert\Length(min="2", max="2", minMessage="card.expiration.month.length", maxMessage="card.expiration.month.length", exactMessage="card.expiration.month.length")
         * @Assert\Range(min="1", max="12", minMessage="card.expiration.month.range", maxMessage="card.expiration.month.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.expiration.month.invalid")
         */
        private $expirationMonth;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="expirationYear", type="integer")
         * @Assert\NotBlank(message="card.expiration.year.blank")
         * @Assert\Length(min="2", max="2", minMessage="card.expiration.year.length", maxMessage="card.expiration.year.length", exactMessage="card.expiration.year.length")
         * @Assert\Range(min="0", max="99", minMessage="card.expiration.year.range", maxMessage="card.expiration.month.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.expiration.year.invalid")
         * @CardHasExpired(message="card.expiration.expired")
         */
        private $expirationYear;
    
        /**
         * @var integer
         *
         * @ORM\Column(name="cvc", type="integer")
         * @Assert\NotBlank(message="card.cvc.blank")
         * @Assert\Length(min="3", max="4", minMessage="card.cvc.short", maxMessage="card.cvc.long", exactMessage="card.cvc.long")
         * @Assert\Range(min="1", max="9999", minMessage="card.cvc.range", maxMessage="card.cvc.range")
         * @Assert\Regex(pattern="^(([0-9]*)|(([0-9]*).([0-9]*)))$^", match=true, message="card.cvc.invalid") 
         */
        private $cvc;  
    
    
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Set number
         *
         * @param integer $number
         * @return Card
         */
        public function setNumber($number)
        {
            $this->number = $number;
    
            return $this;
        }
    
        /**
         * Get number
         *
         * @return integer 
         */
        public function getNumber()
        {
            return $this->number;
        }   
    
        /**
         * Set expirationMonth
         *
         * @param integer $expirationMonth
         * @return Card
         */
        public function setExpirationMonth($expirationMonth)
        {
            $this->expirationMonth = $expirationMonth;
    
            return $this;
        }
    
        /**
         * Get expirationMonth
         *
         * @return integer 
         */
        public function getExpirationMonth()
        {
            return $this->expirationMonth;
        }
    
        /**
         * Set expirationYear
         *
         * @param integer $expirationYear
         * @return Card
         */
        public function setExpirationYear($expirationYear)
        {
            $this->expirationYear = $expirationYear;
    
            return $this;
        }
    
        /**
         * Get expirationYear
         *
         * @return integer 
         */
        public function getExpirationYear()
        {
            return $this->expirationYear;
        }
    
        /**
         * Set cvc
         *
         * @param integer $cvc
         * @return Card
         */
        public function setCvc($cvc)
        {
            $this->cvc = $cvc;
    
            return $this;
        }
    
        /**
         * Get cvc
         *
         * @return integer 
         */
        public function getCvc()
        {
            return $this->cvc;
        }   
    }
    

    Congratulations, you’ve done it, you’re a champion.

    Symfony2: two fields comparison with custom validation constraints

    Symfony2 tutorial: Create custom constraint validation and use it with FOSUserBundle

    Today, we will learn how to create a custom validation constraint with Symfony2 and how to use it with FOSUserBundle.
    Let’s start.

    We have a user registration form in which we want the username to be automatically validated.
    Create your formType and your controller classically, we will focus on constraints.

    Let’s name our new constraint: “ContainsUser”.
    Create a “ContainsUser.php” file in Validator/Contraints directory at your bundle root.

    This file should look like this:

    <?php
    
    namespace VendorName\UserBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    
    /**
     * @Annotation
     */
    class ContainsUser extends Constraint
    {
        public $message = 'The user "%string%" already exists.';
        
        
        public function validatedBy()
        {
            return 'contains_user';
        }
    
        public function getTargets()
        {
            return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
        }    
    }
    
    • ContainsUser will be our constraint.
    • ValidatedBy() function returns an alias that will help defines a service.
    • In getTargets() function, we specify the targets linked to our constraint (properties and/or classes).

    Ok, now we have defined our constraint, we need to create the constraintValidator, it is the file containing the validation logic we want.
    Create a “ContainsUserValidator.php” file, always in Validator/Constraints directory.

    The file should like this:

    <?php
    
    namespace VendorName\UserBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\ConstraintValidator;
    
    class ContainsUserValidator extends ConstraintValidator
    {
        protected $em;
        
        public function __construct(\Doctrine\ORM\EntityManager $em)
        {
            $this->em = $em;
        }
        
        public function validate($value, Constraint $constraint)
        {
            $repository     = $this->em->getRepository('HeadooUserBundle:User');
            $user           = $repository->findOneByUsername($value);
            
            if ($user) {
                $this->context->addViolation(
                    $constraint->message,
                    array('%string%' => $value)
                );
            }
        }
    }
    

    We only loaded a Doctrine Orm dependency and, in the “validate” method, simply checked if the user already exists and generate a context violation.

    In order to make it work, we must create a service that injects specified dependencies, just like that:

        vendorname.user.validator.contains_user:
            class: VendorName\UserBundle\Validator\Constraints\ContainsUserValidator
            arguments:
                - @doctrine.orm.entity_manager        
            tags:
                - { name: validator.constraint_validator, alias: contains_user }  
    

    Note that the alias must match the validateBy function return value in our constraint class.

    Ok, we have now a constraint with a working validator.
    The last thing to do is to call the constraint in FOSUserBundle validation file.
    You must override the FOSUserBundle “validation.xml” file in your “Resources/config” directory.

    We just need to add our constraint for the username property, so we only keep in this file, the username property constraints.

    This is how our constraint must looks like:

    <constraint name="VendorName\UserBundle\Validator\Constraints\ContainsUser">
        <option name="message">fos_user.username.already_used</option>
        <option name="groups">
            <value>Registration</value>
            <value>Profile</value>
        </option>                
    </constraint>
    

    if you want to keep the message specified in the constraint class, just delete the name=’message’ option.

    The complete file must look like this.

    <?xml version="1.0" ?>
    <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
            http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">  
        
        <class name="FOS\UserBundle\Model\User">
    
            <property name="username">
                <constraint name="NotBlank">
                    <option name="message">fos_user.username.blank</option>
                    <option name="groups">
                        <value>Registration</value>
                        <value>Profile</value>
                    </option>
                </constraint>
                <constraint name="Headoo\UserBundle\Validator\Constraints\ContainsUser">
                    <option name="message">fos_user.username.already_used</option>
                    <option name="groups">
                        <value>Registration</value>
                        <value>Profile</value>
                    </option>                
                </constraint>                      
                <constraint name="Length">
                    <option name="min">2</option>
                    <option name="minMessage">fos_user.username.short</option>
                    <option name="max">255</option>
                    <option name="maxMessage">fos_user.username.long</option>
                    <option name="groups">
                        <value>Registration</value>
                        <value>Profile</value>
                    </option>
                </constraint>
            </property>
        </class>
    
    </constraint-mapping>
    

    And that’s it, you have a fully functional customed constraint validation.

    Have fun !

    Symfony2 tutorial: Create custom constraint validation and use it with FOSUserBundle

    Symfony2 tutorial: Log a user manually by creating your own listener

    I had to develop a user registration form with specific roles. The problem was that the form was too big and needed to be simplified.
    I then decided to create my own bundle for multi-step registrations, and I needed to log a user manually after form registration, and I want to share what I’ve learned with you.

    This is how you can perform it.
    First of all, you have to know some symfony base principles:
    – Current user informations are stored in the security context token, and, can be retrieved from here.
    – The security context token listens to security interactiveLogin event that requires user object and token.

    So, to log manually a user, we have to:
    – create a user object and generate a token (we will use UsernamePasswordToken for that).
    – Listen to interactiveLogin event and sends him the token with the current request
    – Dispatch InteractiveLogin event to the security context.

    Right, now let’s go!

    Instead of creating a controller, we’ll create a listener “LoginListener” in a Listener directory.
    This is how our code will looks like.

    <?php
    
    /**
     * Main docblock
     *
     * PHP version 5
     *
     * @category  Listener
     * @package   MultiStepFormsBundle
     * @author    Edouard Kombo <edouard.kombo@gmail.com>
     * @license   http://www.opensource.org/licenses/mit-license.php MIT License
     * @version   GIT: 1.0.0
     * @link      https://creativcoders.wordpress.com
     * @since     0.0.0
     */
    namespace VendorName\UserBundle\Listener;
    
    use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
    use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
    use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
    use Symfony\Component\Security\Core\SecurityContext;
    
    /**
     * Listen to interactive login event and log in a user manually
     *
     * @category Listener
     * @package  MultiStepFormsBundle
     * @author   Edouard Kombo <edouard.kombo@gmail.com>
     * @license  http://www.opensource.org/licenses/mit-license.php MIT License
     * @link     https://creativcoders.wordpress.com
     */
    class LoginListener
    {
        /** 
         * @var \Symfony\Component\Security\Core\SecurityContext 
         */
        protected $securityContext;
            
        /**
         *
         * @var string $username
         */
        protected $username;
        
        /**
         *
         * @var object $em
         */
        protected $em;
        
        /**
         *
         * @var string $firewall
         */
        protected $firewall; 
        
        /**
         *
         * @var string $userEntity
         */
        protected $userEntity;     
        
        /**
         *
         * @var object $container
         */
        protected $container;    
        
        /**
         * Constructor
         * 
         * @param \Doctrine\ORM\EntityManager $em              Doctrine orm
         * @param object                      $container       Container Object
         * @param SecurityContext             $securityContext Security Management
         * 
         * @return \EdouardKombo\MultiStepFormsBundle\Listener\LoginListener
         */
        public function __construct(\Doctrine\ORM\EntityManager $em, $container, 
                SecurityContext $securityContext)
        {
            $this->em               = (object) $em; 
            $this->container        = (object) $container;
            $this->securityContext  = (object) $securityContext;
            
            return $this;
        }
        
        /**
         * Set the username
         * 
         * @param string $username Username of the current user
         * 
         * @return \EdouardKombo\MultiStepFormsBundle\Listener\LoginListener
         */
        public function setUsername($username)
        {
            $this->username = (string) $username;
            return $this;
        }
        
        /**
         * Set the firewall
         * 
         * @param string $firewall Actual security firewall
         * 
         * @return \EdouardKombo\MultiStepFormsBundle\Listener\LoginListener
         */
        public function setFirewall($firewall)
        {
            $this->firewall = (string) $firewall;
            return $this;
        }
        
        /**
         * Define the user entity
         * 
         * @param string $userEntity Project User entity
         * 
         * @return \EdouardKombo\MultiStepFormsBundle\Listener\LoginListener
         */
        public function setUserEntity($userEntity)
        {
            $this->userEntity = (string) $userEntity;
            return $this;
        }    
        
        /**
         * Login a user and dispatch the event.
         * 
         * @return object
         * @throws UsernameNotFoundException
         */
        public function secureInteractiveLogin()
        {
            if (!$this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
                
                $repository  = $this->em->getRepository($this->userEntity);       
                $user        = $repository->findOneByUsername($this->username);
    
                $request     = $this->container->get('request');
                    
                if (!$user) {
                    throw new UsernameNotFoundException("User not found");
    
                } else {
                    //We need the name of the firewall
                    $token = new UsernamePasswordToken($user, null, $this->firewall, 
                        $user->getRoles());
    
                    $this->securityContext->setToken($token);
    
                    //Now, login the user
                    $event = new InteractiveLoginEvent($request, $token);
                    return $this->container->get("event_dispatcher")->dispatch(
                        "security.interactive_login", 
                        $event
                    );
                }            
            } else {
                $user = $event->getAuthenticationToken()->getUser();
            }
            
            return $user;
        }    
    }
    

    Last step is to create a service to inject dependencies on object construct.

    //Change depending on your needs
    services:
        multistep_forms.login_listener:
            class: %multistep_forms.login_listener.class%
            arguments:
                - @doctrine.orm.entity_manager
                - @service_container
                - @security.context
    
    Symfony2 tutorial: Log a user manually by creating your own listener

    Symfony2 differences between doctrine:schema:update and doctrine:migrations

    When you have to create or update your database schema from entities, you are used to type these commands:

    php app/console doctrine:schema:update --dump-sql
    php app/console doctrine:schema:update --force
    

    Doctrine offers another extension called Migrations that helps you:
    – Save your different database schemas during the life of your project
    – Move tables and databases with their content, what a simple doctrine:schema:update can’t do.
    – Generate accessible migrations queries from the difference between your entities and your database schema.
    – Include your own migration queries.

    To use doctrine migrations, you will often use these commands:

    php app/console doctrine:migrations:diff #Generate migrations queries
    php app/console doctrine:migrations:migrate #Refresh your database schema from migrations queries
    

    Finally, for rapid schema updates, use doctrine:schema:update, but, for complex modifications in your database, prefer doctrine:migrations.

    Symfony2 differences between doctrine:schema:update and doctrine:migrations

    How to install and configure FOSUserBundle with Symfony 2.5.*

    When it comes to start multiple projects, configuring all the necessary vendors become an automatism.
    Here is a guideline to help you configure new symfony projects with FOSUserBundle.

     
    First, target FOSUserBundle dependency in your composer.json

    "require": {
        "friendsofsymfony/user-bundle": "2.0.*@dev"
    }
    

     
    Install all your dependencies

    php composer.phar update
    

     
    Then, generate a new bundle we will name userBundle

    php bin/console generate:bundle
    

     
    In the userBundle.php generated file, extend FOSUserBundle like this

    class UserBundle extends Bundle
     {
        public function getParent()
        {
          return 'FOSUserBundle';
        }
     }
    

     
    We can now configure FOSUserBundle in our security.yml in “app/config”.
    We will change default encoder

    encoders:
      FOS\UserBundle\Model\UserInterface: sha512
    

     
    We change the default provider

    providers:       
        fos_userbundle:
            id: fos_user.user_provider.username
    

     
    We then the new firewall of our application

    main:
      pattern: ^/
         form_login:
             provider: fos_userbundle
             csrf_provider: form.csrf_provider
         logout:       true
         anonymous:    true
    

     
    Once the firewall is configured, we have to secure our application urls

    - { path: ^/(_(profiler|wdt)|css|images|js)/, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin, role: ROLE_ADMIN }
    

      
    Ok, right, we have configured the basic security options and created a userBundle that extends FOSUserBundle.
    But Symfony doesn’t actually know who is FOSUserBundle, and, our firewall doesn’t know where to find the user entity.

     
    We have to call FOSUserBundle in the appKernel.

    $bundles = array(
             new FOS\UserBundle\FOSUserBundle(),
     );
    

     
    Generate an empty User entity.

    php bin/console doctrine:generate:entity --entity=VendorUserBundle:User
    

     
    in the User entity, extend FOSUserBundle and turn id attribute from private to protected.

    <?php
    
    namespace Vendor\UserBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use FOS\UserBundle\Entity\User as BaseUser;
    
    /**
     * User
     *
     * @ORM\Table()
     * @ORM\Entity
     */
    class User extends BaseUser
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
    
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
    }
    

     
    Ok, now we must specify FOSUserBundle where to find the user entity in app/config/config.yml, and activate framework locale by uncommenting it.

    fos_user:
      db_driver: orm
      firewall_name: main
      user_class: Vendor\UserBundle\Entity\User
    
    framework:
        translator:      { fallback: "%locale%" }
    

     
    To finish, just add FOSUserBundle routes in our app/config/routing.yml file…

    fos_user_security:
       resource: "@FOSUserBundle/Resources/config/routing/security.xml"
     
     fos_user_profile:
       resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
       prefix: /profile
     
     fos_user_register:
       resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
       prefix: /register
     
     fos_user_resetting:
       resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
       prefix: /resetting
     
     fos_user_change_password:
        resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
        prefix: /profile
    

     
    And finally, upgrade your database schema

    php bin/console doctrine:schema:update --dump-sql
    php bin/console doctrine:schema:update --force
    

    You have a ready to use FOSUserBundle installation.

    How to install and configure FOSUserBundle with Symfony 2.5.*

    Symfony2 // [Symfony\Component\DependencyInjection\Exception\InvalidArgumentException] unable to parse file…

    When reorganizing my bundles, I decided to load my services from my bundle dependency injection.
    My bundle name is “UserBundle” and my vendor name “xxx”.

    So, I created an extension file from my bundle called “xxxUserExtension.php” in “UserBundle/DependencyInjection/”

    This was my content file:

    <?php
    
    namespace xxx\UserBundle\DependencyInjection;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\Loader;
    
    /**
     * This is the class that loads and manages your bundle configuration
     *
     * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
     */
    class xxxUserExtension extends Extension
    {
        /**
         * {@inheritDoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {
            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);
    
            $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('user.yml');
            $loader->load('forms.yml');        
            $loader->load('validation.xml');       
        }
    }
    

    And of course, I’ve got this error:

        [Symfony\Component\DependencyInjection\Exception\InvalidArgumentException]
        Unable to parse file "C:\wamp\www\xxx\src\Headoo\UserBundle\DependencyInjection/../Resources/config\user.yml".
    

    Maybe you want to know the cause, right?

    This error simply occured because I was loading an yml file with an xmlFileLoader. Also, i was loading an xml file, we never have to load two different file types with a single file type loader.

    Look here:

            $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('user.yml');
            $loader->load('forms.yml');
            $loader->load('validation.xml'); 
    

    So to solve this error, you have to use only one extension for your services and choose the correct loader.
    This is the correct file:

    <?php
    
    namespace xxx\UserBundle\DependencyInjection;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\Loader;
    
    /**
     * This is the class that loads and manages your bundle configuration
     *
     * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
     */
    class xxxUserExtension extends Extension
    {
        /**
         * {@inheritDoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {
            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);
    
            $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('user.yml');
            $loader->load('forms.yml');               
        }
    }
    

    Hope, this helped.

    Symfony2 // [Symfony\Component\DependencyInjection\Exception\InvalidArgumentException] unable to parse file…