FOSUserBundle – compatibility break

Well, four days ago Stof authored a braking-change in FOSUserBundle; after updating vendors, you may encounter errors like "an encoder is not configured for Your\User\Entity" exception. This is basically because "algorithm" field from User entity was wiped out, and moved to FOSAdvancedEncoderBundle.

If you've encountered this, you basically have two options:

1) stick to 1.1.0 branch of FOSUserBundle by modifying your deps:

[FOSUserBundle]
    git=git://github.com/FriendsOfSymfony/FOSUserBundle.git
    target=bundles/FOS/UserBundle
    version=1.1.0

of course, if you don't want to ever upgrade to symfony 2.1 )

2) upgrade to master FOSUserBundle:

do

bin/vendors update

update doctrine schema (this will delete "algorithm" column):

app/console doctrine:schema:update --force

modify "encoders" section in security.yml:

 
  encoders:
    FOS\UserBundle\Model\UserInterface:
      algorithm: sha512
      encode_as_base64: false
      iterations: 1
 

encode_as_base64: false and iterations: 1 will add compatibility with you current encoded passwords from 1.1.0 version of FOSUserBundle.

Have fun!

Direct links to controller without global routing rules in sf2

I suppose anyone is aware about path() twig function; it takes route name and returns URL. This is cool, but what if you use @Route annotation in Controller and need to link there without modifying routing.yml?

Here some magic comes in place - symfony internally generates name for each route imported via @Route annotation; the route is constructed in the following way:

(bundle name, converted to underscore, without 'bundle' suffix)
+ '_' +
(controller name, without 'controller' suffix, lowercase)
+ '_' +
(full controller method name, lowercase)

for example, if you have an Company\Hrm\GuiBundle, and some SimpleAuthController with method authorizeAction, like this:

 
/.../
class SimpleAuthController extends Controller
{
  /**
  * @Route("/auth")
  */
  public function authorizeAction()
  {
     /.../
  }
}
 

then

{{ path('company_hrm_gui_simpleauth_authorizeaction') }}

will return "/auth" link.

PS: And please, use it only for development and testing, this is a hardcode ;)

Setting PHPUnit for symfony projects on Ubuntu

Just a copy& paste guide:

 
#install pear, phpunit
sudo apt-get install php-pear phpunit
 
#upgrade pear - this is necessary
sudo pear upgrade PEAR
 
#install phpunit
sudo pear config-set auto_discover 1
sudo pear install pear.phpunit.de/PHPUnit
 

All done! Now you can run symfony tests:

 
cd vendor/symfony
php vendors.php
phpunit -c phpunit.xml.dist tests/
 

AppKernel and DependencyInjection container in Symfony 2 tests

It's fairly simple to use app kernel and DI container in symfony tests, just require AppKernel.php:

 
require_once __DIR__.'/../../../../../../app/AppKernel.php';
 

and then boot your app in setUp method:

 
 
    private $container;
 
    public function setUp()
    {
        $this->app = new \AppKernel('test', true);
        $this->app->boot();
        $this->container = $this->app->getContainer();
    }
 

then, use a container where needed:

 
    public function testFoo()
    {
        $this->container->get('logger')->debug('Foo');
    }
 

Netbeans single variable type hinting

In some code blocks (especially in symfony DI related) it's impossible to guess what class the object has, but it's possible to use single-line annotation before assignment:

 
$object = $this->get('doctrine')
      ->getRepository('MyBundleName:Object')
      ->findOneById($id);
/* @var $object \My\Bundle\Name\Entity\Object */
 

with this netbeans will be able to auto-complete $object-> calls.

Please note that this annotation should be places after variable defintion as above!

You can also use shorter path:

 
/* @var $object Object */
 

if you have

 
use My\Bundle\Name\Entity\Object
 

defined in top of your file.

Doctrine/Symfony2 multiple database connections and Entity Managers

dbal:
    default_connection:       default
    connections:
        default:
            dbname:           database1
            user:             root
            password:         password
            host:             localhost
        other:
            dbname:           database2
            user:             root
            password:         password
            host:             localhost
orm:
    default_entity_manager:   default
    entity_managers:
        default:
            connection:       default
            mappings:
                MyFirstBundle: ~
        other:
            connection:       client
            mappings:
                MySecondBundle: ~

after that, you'll be able to access the other database conneciton via:

 
$this->getDoctrine()->getEntityManager('other')
 

and

 
$this->getDoctrine()->getRepository('Bundle:Entity', 'other')