Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved loading of fixtures to a service #152

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 13 additions & 38 deletions Command/LoadDataFixturesDoctrineCommand.php
Expand Up @@ -14,16 +14,13 @@

namespace Doctrine\Bundle\FixturesBundle\Command;

use Doctrine\Bundle\DoctrineBundle\Command\DoctrineCommand;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\DBAL\Sharding\PoolingShardConnection;
use InvalidArgumentException;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader as DataFixturesLoader;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Doctrine\Bundle\DoctrineBundle\Command\DoctrineCommand;
use Doctrine\DBAL\Sharding\PoolingShardConnection;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;

/**
* Load data fixtures from bundles.
Expand All @@ -43,7 +40,6 @@ protected function configure()
->addOption('em', null, InputOption::VALUE_REQUIRED, 'The entity manager to use for this command.')
->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command.')
->addOption('purge-with-truncate', null, InputOption::VALUE_NONE, 'Purge data by using a database-level TRUNCATE statement')
->addOption('multiple-transactions', null, InputOption::VALUE_NONE, 'Use one transaction per fixture file instead of a single transaction for all')
->setHelp(<<<EOT
The <info>doctrine:fixtures:load</info> command loads data fixtures from your bundles:

Expand Down Expand Up @@ -85,37 +81,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
$em->getConnection()->connect($input->getOption('shard'));
}

$dirOrFile = $input->getOption('fixtures');
if ($dirOrFile) {
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
} else {
$paths = array();
foreach ($this->getApplication()->getKernel()->getBundles() as $bundle) {
$paths[] = $bundle->getPath().'/DataFixtures/ORM';
}
}

$loader = new DataFixturesLoader($this->getContainer());
foreach ($paths as $path) {
if (is_dir($path)) {
$loader->loadFromDirectory($path);
} elseif (is_file($path)) {
$loader->loadFromFile($path);
}
}
$fixtures = $loader->getFixtures();
if (!$fixtures) {
throw new InvalidArgumentException(
sprintf('Could not find any fixtures to load in: %s', "\n\n- ".implode("\n- ", $paths))
);
}
$purger = new ORMPurger($em);
$purger->setPurgeMode($input->getOption('purge-with-truncate') ? ORMPurger::PURGE_MODE_TRUNCATE : ORMPurger::PURGE_MODE_DELETE);
$executor = new ORMExecutor($em, $purger);
$executor->setLogger(function ($message) use ($output) {
$logger = function ($message) use ($output) {
$output->writeln(sprintf(' <comment>></comment> <info>%s</info>', $message));
});
$executor->execute($fixtures, $input->getOption('append'),$input->getOption('multiple-transactions'));
};

$loader = $this->getContainer()->get('doctrine_fixtures.database_populator');
$loader->setDirOrFile($input->getOption('fixtures'));
$loader->setPurgeWithTruncate($input->getOption('purge-with-truncate'));
$loader->setAppend($input->getOption('append'));
$loader->load($em, new ORMExecutor($em), $logger);
}

/**
Expand Down
32 changes: 32 additions & 0 deletions DependencyInjection/DoctrineFixturesExtension.php
@@ -0,0 +1,32 @@
<?php

/*
* This file is part of the Doctrine Fixtures Bundle
*
* The code was originally distributed inside the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
* (c) Doctrine Project
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Doctrine\Bundle\FixturesBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

class DoctrineFixturesExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}
110 changes: 110 additions & 0 deletions Loader/DatabasePopulator.php
@@ -0,0 +1,110 @@
<?php

/*
* This file is part of the Doctrine Fixtures Bundle
*
* The code was originally distributed inside the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
* (c) Doctrine Project
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Doctrine\Bundle\FixturesBundle\Loader;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;

class DatabasePopulator
{
/**
* @var FixtureLoader
*/
protected $fixtureLoader;

/**
* @var ORMPurger
*/
protected $purger;

/**
* @var mixed
*/
protected $dirOrFile;

/**
* @var bool
*/
protected $purgeWithTruncate = false;

/**
* @var bool
*/
protected $append = false;

/**
* @param FixtureLoader $fixtureLoader
* @param ORMPurger $purger
*/
public function __construct(FixtureLoader $fixtureLoader, ORMPurger $purger)
{
$this->fixtureLoader = $fixtureLoader;
$this->purger = $purger;
}

/**
* @param mixed $dirOrFile
*/
public function setDirOrFile($dirOrFile)
{
$this->dirOrFile = $dirOrFile;
}

/**
* @param boolean $purgeWithTruncate
*/
public function setPurgeWithTruncate($purgeWithTruncate)
{
$this->purgeWithTruncate = $purgeWithTruncate;
}

/**
* @param boolean $append
*/
public function setAppend($append)
{
$this->append = $append;
}

/**
* @param EntityManagerInterface $em
* @param ORMExecutor $executor
* @param null|\Psr\Log\LoggerInterface|\Closure $logger
*/
public function load(EntityManagerInterface $em, ORMExecutor $executor, $logger = null)
{
$fixtures = $this->fixtureLoader->getFixtures($this->dirOrFile);
if (!$fixtures) {
throw new \InvalidArgumentException(
sprintf(
'Could not find any fixtures to load in: %s',
"\n\n- ".implode("\n- ", $this->fixtureLoader->getPaths($this->dirOrFile))
)
);
}
$this->purger->setEntityManager($em);
if ($this->purgeWithTruncate) {
$this->purger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE);
}
$executor->setPurger($this->purger);
if ($logger) {
$executor->setLogger($logger);
}
$executor->execute($fixtures, $this->append);
}
}
81 changes: 81 additions & 0 deletions Loader/FixtureLoader.php
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of the Doctrine Fixtures Bundle
*
* The code was originally distributed inside the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
* (c) Doctrine Project
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Doctrine\Bundle\FixturesBundle\Loader;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;

class FixtureLoader
{
/**
* @var ContainerAwareLoader
*/
protected $containerAwareLoader;

/**
* @var KernelInterface
*/
protected $kernel;

/**
* @param ContainerAwareLoader $containerAwareLoader
* @param KernelInterface $kernel
*/
public function __construct(ContainerAwareLoader $containerAwareLoader, KernelInterface $kernel)
{
$this->containerAwareLoader = $containerAwareLoader;
$this->kernel = $kernel;
}

/**
* @param mixed $dirOrFile
*
* @return array
*/
public function getFixtures($dirOrFile)
{
foreach ($this->getPaths($dirOrFile) as $path) {
if (is_dir($path)) {
$this->containerAwareLoader->loadFromDirectory($path);
} elseif (is_file($path)) {
$this->containerAwareLoader->loadFromFile($path);
}
}

return $this->containerAwareLoader->getFixtures();
}

/**
* @param mixed $dirOrFile
*
* @return string[]
*/
public function getPaths($dirOrFile)
{
if ($dirOrFile) {
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
} else {
$paths = array();
foreach ($this->kernel->getBundles() as $bundle) {
$paths[] = $bundle->getPath().'/DataFixtures/ORM';
}
}

return $paths;
}
}
22 changes: 22 additions & 0 deletions Resources/config/services.xml
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="doctrine_fixtures.database_populator" class="Doctrine\Bundle\FixturesBundle\Loader\DatabasePopulator">
<argument type="service" id="doctrine_fixtures.fixture_loader" />
<argument type="service" id="doctrine_fixtures.orm_purger" />
</service>
<service id="doctrine_fixtures.fixture_loader" class="Doctrine\Bundle\FixturesBundle\Loader\FixtureLoader">
<argument type="service" id="doctrine_fixtures.container_aware_loader" />
<argument type="service" id="kernel" />
</service>
<service id="doctrine_fixtures.container_aware_loader" class="Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader">
<argument type="service" id="service_container" />
</service>
<service id="doctrine_fixtures.orm_purger" class="Doctrine\Common\DataFixtures\Purger\ORMPurger" />
</services>

</container>
50 changes: 50 additions & 0 deletions Tests/Loader/DatabasePopulatorTest.php
@@ -0,0 +1,50 @@
<?php

namespace Doctrine\Bundle\FixtureBundle\Tests\Loader;

use Doctrine\Bundle\FixturesBundle\Loader\DatabasePopulator;

class DatabasePopulatorTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Could not find any fixtures to load in:
*/
public function throws_exception_if_no_fixtures_was_found()
{
$ormPurgerMock = $this->getMockBuilder('Doctrine\Common\DataFixtures\Purger\ORMPurger')
->disableOriginalConstructor()->getMock();
$emMock = $this->getMock('Doctrine\ORM\EntityManagerInterface');
$executorMock = $this->getMockBuilder('Doctrine\Common\DataFixtures\Executor\ORMExecutor')
->disableOriginalConstructor()->getMock();

$fixtureLoaderMock = $this->getMockBuilder('Doctrine\Bundle\FixturesBundle\Loader\FixtureLoader')
->disableOriginalConstructor()->getMock();
$fixtureLoaderMock->expects($this->once())->method('getFixtures')->willReturn(array());
$fixtureLoaderMock->expects($this->once())->method('getPaths')->willReturn(array());

$databasePopulator = new DatabasePopulator($fixtureLoaderMock, $ormPurgerMock);
$databasePopulator->load($emMock, $executorMock);
}

/**
* @test
*/
public function should_execute()
{
$ormPurgerMock = $this->getMockBuilder('Doctrine\Common\DataFixtures\Purger\ORMPurger')
->disableOriginalConstructor()->getMock();
$emMock = $this->getMock('Doctrine\ORM\EntityManagerInterface');
$executorMock = $this->getMockBuilder('Doctrine\Common\DataFixtures\Executor\ORMExecutor')
->disableOriginalConstructor()->getMock();
$executorMock->expects($this->once())->method('execute');

$fixtureLoaderMock = $this->getMockBuilder('Doctrine\Bundle\FixturesBundle\Loader\FixtureLoader')
->disableOriginalConstructor()->getMock();
$fixtureLoaderMock->expects($this->once())->method('getFixtures')->willReturn(array('Foo'));

$databasePopulator = new DatabasePopulator($fixtureLoaderMock, $ormPurgerMock);
$databasePopulator->load($emMock, $executorMock);
}
}