0
votes

I'm using symfony 3.4.1 with doctrine/doctrine-fixtures-bundle": "2.4.1

I'm trying to run fixtures, but I have this message when I'm trying to inject the UserPasswordEncoderInterface to encode my password. https://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html#accessing-services-from-the-fixtures

Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Too few arguments to function AppBundle\DataFixtures\DataFixtures::__construct(), 0 passed in /srv/api-platform/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Loader.php on line 210 and exactly 1 expected in /srv/api-platform/src/AppBundle/DataFixtures/ORM/DataFixtures.php:20 Stack trace:

0 /srv/api-platform/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Loader.php(210):

AppBundle\DataFixtures\DataFixtures->__construct()

1 /srv/api-platform/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Loader.php(390):

Doctrine\Common\DataFixtures\Loader->createFixture('AppBundle\DataF...')

2 /srv/api-platform/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Loader.php(82):

Doctrine\Common\DataFixtures\Loader->loadFromIterator(Object(RecursiveIteratorIterator))

3 /srv/api-platform/vendor/doctrine/doctrine-fixtures-bundle/Command/LoadDataFixturesDoctrineCommand.php(102):

Doctrine\Commo in /srv/api-platform/src/AppBundle/DataFixtures/ORM/DataFixtures.php on line 20

My Fixtures:

<?php

namespace AppBundle\DataFixtures;

use AppBundle\Entity\TechnicalCenter;
use AppBundle\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class DataFixtures extends Fixture
{
    /** @var UserPasswordEncoderInterface $encoder */
    private $encoder;

    /**
     * DataFixtures constructor.
     * @param UserPasswordEncoderInterface $encoder
     */
    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;
    }

    /**
     * Load data fixtures with the passed EntityManager
     *
     * @param ObjectManager $manager
     */
    public function load(ObjectManager $manager)
    {
        $technicalCenter = new TechnicalCenter();
        $technicalCenter->setName('Austerlitz');
        $manager->persist($technicalCenter);

        $admin = new User();
        $admin->setUsername('admin');
        $admin->setPassword($this->encoder->encodePassword($admin, 'admin'));
        $admin->setRoles(array('ROLE_ADMIN'));
        $admin->setTechnicalCenter($technicalCenter);
        $manager->persist($admin);

        $manager->flush();
    }
}

My security.yml

security:
    encoders:
        AppBundle\Entity\User: bcrypt
1
Are you using the standard services configuration, ie your services.yml file is in the standard place for Symfony 3.4?Ollie in PGH
If not (or even if it is) did you try registering your fixture as a service and injecting the encoder?Ollie in PGH

1 Answers

4
votes

In fixtures I inject directly the ContainerInterface by implement it and using the "setContainer" function, for exemple:

<?php

namespace CoreBundle\DataFixtures\ORM;

use CoreBundle\Entity\Admin;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class LoadAdminData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface {

    /**
     * @var ContainerInterface
     */
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        $admin = new Admin();
        $admin->setUsername('Test');
        $plainPass = 'admin';
        $encoder = $this->container->get('security.password_encoder');
        $encodedPass = $encoder->encodePassword($admin, $plainPass);
        $admin->setPassword($encodedPass);
        $admin->setEmail('[email protected]');

        $manager->persist($admin);
        $manager->flush();
    }
    public function getOrder()
    {
        // the order in which fixtures will be loaded
        // the lower the number, the sooner that this fixture is loaded
        return 1;
    }
}