Monday, October 31, 2011

Set up an AuthenticationSuccessHandler in Symfony2

Symfony2 allows you to simply make treatments after a login attempt success. As simple as you just have to define a service, called "security.authentication.success_handler" and make it to implement AuthenticationSuccessHandlerInterface...

In this example, I want logged new user to be redirected to a "Terms and conditions" accept form. I have to check the boolean property termsAndConditionsOk of the User entity to know if redirection applies.
AuthenticationSuccessHandlerInterface defines 1 method :
<?php

/*
 * This file is part of the Symfony framework.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Symfony\Component\Security\Http\Authentication;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Interface for a custom authentication success handler
 *
 * If you want to customize the success handling process, instead of
 * overwriting the respective listener globally, you can set a custom success
 * handler which implements this interface.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface AuthenticationSuccessHandlerInterface
{
    /**
     * This is called when an interactive authentication attempt succeeds. This
     * is called by authentication listeners inheriting from
     * AbstractAuthenticationListener.
     *
     * @param Request        $request
     * @param TokenInterface $token
     *
     * @return Response the response to return
     */
    function onAuthenticationSuccess(Request $request, TokenInterface $token);
}

Definition of the service in a services.yml config file (i use YAML) :

Tuesday, October 4, 2011

Deal with a nullable relation field in an Entity with Doctrine2

Entity generation from an existing database is a long way to go... Last issue : set a relation field to NULL => the generated setter expects an Entity Object as a parameter

MyEntity is an entity including a field myRelatedEntity referencing an entity MyRelatedEntity. Basic generation produces this setter :
class MyEntity
{

    ...

    /**
     * Set myRelatedEntity
     *
     * @param Xxx\YourBundle\Entity\MyRelatedEntity $myRelatedEntity
     */
    public function setMyRelatedEntity(MyRelatedEntity $myRelatedEntity)
    {
        $this->myRelatedEntity = $myRelatedEntity;
    }

    ...

}
This setter doesn't allow to set NULL value. Instead you get this kinf of error :
Catchable fatal error: Argument 1 passed to setMyRelatedEntity() must be an instance of \Xxx\YourBundle\Entity\MyRelatedEntity, null given
This indicates you have to modify the setter to accept null value :
class MyEntity
{

    ...

    /**
     * Set myRelatedEntity
     *
     * @param mixed $myRelatedEntity Entity MyRelatedEntity or NULL
     */
    public function setMyRelatedEntity(MyRelatedEntity $myRelatedEntity = null)
    {
        $this->myRelatedEntity = $myRelatedEntity;
    }

    ...

}

Configuration trick for multiple entity managers in Symfony2

First time I tried to define multiple entity managers in config.yml, i got some errors...


I didn't strictly followed symfony cookbook but based my configuration on the reference about Doctrine configuration. So I let "auto_mapping" parameter with false value, and I got following error :

InvalidConfigurationException: Unrecognized options "auto_mapping" under "doctrine.orm"

So if you want to implement many entity managers, don't forget to erase "auto_mapping" param in your config files (config.yml and derived ones if needed).
doctrine: 
    orm: 
        auto_mapping: false 
        default_entity_manager:   em1 
        entity_managers: 
            em1: 
                connection:       conn1 
                mappings: 
                    XxxYourBundle: ~ 
            em2: 
                connection:       conn2 
                mappings: 
                    XxxYourBundle2: ~