diff --git a/README.md b/README.md index 23ab914..cb502b9 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ This is installable via [Composer](https://getcomposer.org/) as [sp/fixture-dump ### Basic Usage ### -Examples: - ```php $manager = ...; // entity or document manager $registry = new \Sp\FixtureDumper\Converter\Handler\HandlerRegistry(); @@ -30,16 +28,31 @@ $ymlGenerator = new \Sp\FixtureDumper\Generator\Alice\YamlFixtureGenerator(); // for creating array files which can be loaded with the alice fixtures library $arrayGenerator = new \Sp\FixtureDumper\Generator\Alice\ArrayFixtureGenerator(); -$generatorMap = new \PhpCollection\Map(array('class' => $generator, 'yml' => $ymlGenerator, 'array' => $arrayGenerator); -$dumper = new \Sp\FixtureDumper\ORMDumper($manager, $registry, $generatorMap)); +$generatorMap = new \PhpCollection\Map(array('class' => $generator, 'yml' => $ymlGenerator, 'array' => $arrayGenerator)); +$dumper = new \Sp\FixtureDumper\ORMDumper($manager, $registry, $generatorMap); // or -$dumper = new \Sp\FixtureDumper\MongoDBDumper($manager, $registry, $generatorMap)); +$dumper = new \Sp\FixtureDumper\MongoDBDumper($manager, $registry, $generatorMap); // $dumper->setDumpMultipleFiles(false); // the second argument specifies the generator type you want to use $dumper->dump('/your/workspace/src/Acme/DemoBundle/DataFixtures/ORM', 'array'); ``` +### Exclusion Strategy ### + +You can implement the interface `ExclusionStrategyInterface` to define the strategy to select the entities to dump. + +```php +// ... +$dumper = new \Sp\FixtureDumper\ORMDumper($manager, $registry, $generatorMap); + +// The entity Post and Comment won't be dumped +$exclusion = new ArrayExclusionStrategy(['Post', 'Acme\DemoBundle\Entity\Comment']); +$dumper->setExclusionStrategy($exclusion); + +$dumper->dump(...); +``` + #### Options `AbstractDumper#dump` accepts a third `$options` argument that is an array diff --git a/src/Sp/FixtureDumper/AbstractDumper.php b/src/Sp/FixtureDumper/AbstractDumper.php index c7edbea..4ffa73c 100644 --- a/src/Sp/FixtureDumper/AbstractDumper.php +++ b/src/Sp/FixtureDumper/AbstractDumper.php @@ -12,6 +12,7 @@ namespace Sp\FixtureDumper; use Doctrine\Common\Persistence\ObjectManager; +use Sp\FixtureDumper\ExclusionStrategy\ExclusionStrategyInterface; use Sp\FixtureDumper\Generator\AbstractGenerator; use Symfony\Component\Filesystem\Filesystem; use PhpCollection\MapInterface; @@ -41,6 +42,11 @@ abstract class AbstractDumper */ protected $handlerRegistry; + /** + * @var \Sp\FixtureDumper\ExclusionStrategy\ExclusionStrategyInterface + */ + protected $exclusionStrategy; + /** * @var bool */ @@ -70,12 +76,22 @@ public function __construct(ObjectManager $objectManager, HandlerRegistryInterfa */ public function dump($path, $format, array $options = array()) { - $metadata = $this->getDumpOrder($this->getAllMetadata()); + $exclusionStrategy = $this->getExclusionStrategy(); + $metadata = $this->getAllMetadata(); + + if (null !== $exclusionStrategy) { + $metadata = array_filter($metadata, function($class) use ($exclusionStrategy) { + return ! $exclusionStrategy->shouldSkipClass($class); + }); + } + + $metadata = $this->getDumpOrder($metadata); $generator = $this->generators->get($format)->get(); $generator->setNavigator(new DefaultNavigator($this->handlerRegistry, $format)); $generator->setManager($this->objectManager); $fixtures = array(); + foreach ($metadata as $data) { $fixture = $generator->generate($data, null, $options); if ($this->dumpMultipleFiles) { @@ -111,6 +127,22 @@ public function shouldDumpMultipleFiles() return $this->dumpMultipleFiles; } + /** + * @param \Sp\FixtureDumper\ExclusionStrategy\ExclusionStrategyInterface $exclusionStrategy + */ + public function setExclusionStrategy(ExclusionStrategyInterface $exclusionStrategy) + { + $this->exclusionStrategy = $exclusionStrategy; + } + + /** + * @return \Sp\FixtureDumper\ExclusionStrategy\ExclusionStrategyInterface + */ + public function getExclusionStrategy() + { + return $this->exclusionStrategy; + } + /** * @param Generator\AbstractGenerator $generator * @param string $fixture @@ -135,5 +167,4 @@ protected function getAllMetadata() } abstract protected function getDumpOrder(array $classes); - } diff --git a/src/Sp/FixtureDumper/ExclusionStrategy/ArrayExclusionStrategy.php b/src/Sp/FixtureDumper/ExclusionStrategy/ArrayExclusionStrategy.php new file mode 100644 index 0000000..5875c68 --- /dev/null +++ b/src/Sp/FixtureDumper/ExclusionStrategy/ArrayExclusionStrategy.php @@ -0,0 +1,29 @@ + + */ +class ArrayExclusionStrategy implements ExclusionStrategyInterface +{ + /** @var array */ + private $skipClassesNames; + + public function __construct(array $skipClassesNames) + { + $this->skipClassesNames = $skipClassesNames; + } + + /** + * {@inheritdoc} + */ + public function shouldSkipClass(ClassMetadata $metadata) + { + return in_array(ClassUtils::getClassName($metadata->getName()), $this->skipClassesNames) || + in_array($metadata->getName(), $this->skipClassesNames); + } +} diff --git a/src/Sp/FixtureDumper/ExclusionStrategy/ExclusionStrategyInterface.php b/src/Sp/FixtureDumper/ExclusionStrategy/ExclusionStrategyInterface.php new file mode 100644 index 0000000..3fe7c4a --- /dev/null +++ b/src/Sp/FixtureDumper/ExclusionStrategy/ExclusionStrategyInterface.php @@ -0,0 +1,24 @@ + + */ +interface ExclusionStrategyInterface +{ + + /** + * Indicates if this class should be skipped and do not generate fixtures for this class + * + * @param ClassMetadata $metadata + * + * @return boolean true if this class should be skipped + */ + public function shouldSkipClass(ClassMetadata $metadata); +} diff --git a/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ArrayExclusionStrategyTest.php b/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ArrayExclusionStrategyTest.php new file mode 100644 index 0000000..0b684ac --- /dev/null +++ b/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ArrayExclusionStrategyTest.php @@ -0,0 +1,34 @@ + + */ +class ArrayExclusionStrategyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider dataProviderArrayExclusionStrategy + */ + public function testShouldSkipClassName($excludedClasses, $classMetadata, $shouldSkip) + { + $exclusionStrategy = new ArrayExclusionStrategy($excludedClasses); + + $this->assertEquals($exclusionStrategy->shouldSkipClass($classMetadata), $shouldSkip); + } + + public function dataProviderArrayExclusionStrategy() + { + $postClass = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata'); + $postClass->expects($this->any())->method('getName')->will($this->returnValue('Acme\Demo\Entity\Post')); + + return array( + array(array('Post'), $postClass, true), + array(array('Acme\Demo\Entity\Post'), $postClass, true), + array(array('Acme\Demo\Entity\PostBlog'), $postClass, false), + array(array('', 'aPost', 'Posti'), $postClass, false), + ); + } +} diff --git a/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ExclusionStrategyTest.php b/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ExclusionStrategyTest.php new file mode 100644 index 0000000..784a1fe --- /dev/null +++ b/tests/Sp/FixtureDumper/Tests/ExclusionStrategy/ExclusionStrategyTest.php @@ -0,0 +1,87 @@ + + */ +class ExclusionStrategyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $handlerRegistry; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $manager; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $generator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $metadata; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $dumper; + + protected function setUp() + { + $this->metadata = array( + $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata'), + $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata'), + ); + $this->manager = $this->getMock('Doctrine\Common\Persistence\ObjectManager'); + $this->generator = $this + ->getMockBuilder('Sp\FixtureDumper\Generator\AbstractGenerator') + ->disableOriginalConstructor() + ->setMethods(array('generate', 'setNavigator')) + ->getMockForAbstractClass(); + $this->handlerRegistry = $this->getMock('Sp\FixtureDumper\Converter\Handler\HandlerRegistryInterface'); + $this->dumper = $this + ->getMockForAbstractClass( + 'Sp\FixtureDumper\AbstractDumper', + array( + $this->manager, + $this->handlerRegistry, + new Map(array('php' => $this->generator)), + ), + '', + true, + true, + true, + array('writeFixture', 'getAllMetadata', 'getDumpOrder', 'getExclusionStrategy') + ); + + $this->dumper->expects($this->once())->method('getAllMetadata')->will($this->returnValue($this->metadata)); + $this->dumper->expects($this->once())->method('getDumpOrder')->will($this->returnValue($this->metadata)); + } + + public function testCollaborationExclusionStrategy() + { + $this->exclusionStrategy = $this + ->getMock('Sp\FixtureDumper\ExclusionStrategy\ExclusionStrategyInterface'); + + $this->dumper->setExclusionStrategy($this->exclusionStrategy); + + $this->dumper + ->expects($this->once()) + ->method('getExclusionStrategy') + ->will($this->returnValue($this->exclusionStrategy)); + + $this->exclusionStrategy + ->expects($this->exactly(2)) + ->method('shouldSkipClass'); + + $this->dumper->dump('/foo', 'php'); + } +}