From f375c4643bc1cb94a9efaefd49a49dababce65d9 Mon Sep 17 00:00:00 2001 From: Julius Beckmann Date: Mon, 27 Oct 2014 23:56:15 +0100 Subject: [PATCH] Made references of sets and files global for commands. Added `--drop` for load:sets command. Removed the ORM detach call for the entities. --- Command/LoadFilesCommand.php | 8 +++++++- Command/LoadSetsCommand.php | 21 ++++++++++++++++++--- Fixtures/FixtureManager.php | 7 ++----- Fixtures/FixtureManagerInterface.php | 5 ++++- README.md | 26 ++++++++++++++++++++++++-- Tests/Command/LoadFilesCommandTest.php | 4 ++-- Tests/Command/LoadSetsCommandTest.php | 7 ++++--- 7 files changed, 61 insertions(+), 17 deletions(-) diff --git a/Command/LoadFilesCommand.php b/Command/LoadFilesCommand.php index 55905ae..b610fe2 100644 --- a/Command/LoadFilesCommand.php +++ b/Command/LoadFilesCommand.php @@ -73,6 +73,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $schemaTool->createSchema(); } + // Store all loaded references in this array, so they can be used by other FixtureSets. + $references = array(); + foreach ($files as $file) { $output->write("Loading file '$file' ... "); @@ -83,7 +86,10 @@ protected function execute(InputInterface $input, OutputInterface $output) $set->setLocale($input->getOption('locale')); $set->setSeed($input->getOption('seed')); - $entities = $manager->load($set); + $entities = $manager->load($set, $references); + + // Only reusing loaded entities. Internal references are ignored because of intended private state. + $references = array_merge($references, $entities); $output->writeln("loaded " . count($entities) . " entities ... done."); } diff --git a/Command/LoadSetsCommand.php b/Command/LoadSetsCommand.php index 72027b4..7e0b160 100644 --- a/Command/LoadSetsCommand.php +++ b/Command/LoadSetsCommand.php @@ -32,7 +32,8 @@ protected function configure() ->setName('h4cc_alice_fixtures:load:sets') ->setDescription('Load fixture sets using alice and faker.') ->addArgument('sets', InputArgument::IS_ARRAY, 'List of path to fixture sets to import.') - ->addOption('manager', 'm', InputOption::VALUE_OPTIONAL, 'The manager name to used.', 'default'); + ->addOption('manager', 'm', InputOption::VALUE_OPTIONAL, 'The manager name to used.', 'default') + ->addOption('drop', 'd', InputOption::VALUE_NONE, 'Drop and create Schema before loading.'); } protected function execute(InputInterface $input, OutputInterface $output) @@ -55,9 +56,11 @@ protected function execute(InputInterface $input, OutputInterface $output) } $managerServiceId = 'h4cc_alice_fixtures.manager'; + $schemaToolServiceId = 'h4cc_alice_fixtures.orm.schema_tool'; if ('default' !== $input->getOption('manager')) { - $managerServiceId = sprintf('h4cc_alice_fixtures.%s_manager', $input->getOption('manager')); + $managerServiceId = sprintf('h4cc_alice_fixtures.%s_manager', $input->getOption('manager')); + $schemaToolServiceId = sprintf('h4cc_alice_fixtures.orm.%s_schema_tool', $input->getOption('manager')); } /** @@ -65,6 +68,15 @@ protected function execute(InputInterface $input, OutputInterface $output) */ $manager = $this->getContainer()->get($managerServiceId); + if ($input->getOption('drop')) { + $schemaTool = $this->getContainer()->get($schemaToolServiceId); + $schemaTool->dropSchema(); + $schemaTool->createSchema(); + } + + // Store all loaded references in this array, so they can be used by other FixtureSets. + $references = array(); + foreach ($sets as $file) { $output->write("Loading file '$file' ... "); @@ -75,7 +87,10 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new \InvalidArgumentException("File '$file' does not return a FixtureSetInterface."); } - $entities = $manager->load($set); + $entities = $manager->load($set, $references); + + // Only reusing loaded entities. Internal references are ignored because of intended private state. + $references = array_merge($references, $entities); $output->writeln("loaded " . count($entities) . " entities ... done."); } diff --git a/Fixtures/FixtureManager.php b/Fixtures/FixtureManager.php index 1cdb036..14b8585 100644 --- a/Fixtures/FixtureManager.php +++ b/Fixtures/FixtureManager.php @@ -129,14 +129,14 @@ public function createFixtureSet() /** * {@inheritDoc} */ - public function load(FixtureSet $set) + public function load(FixtureSet $set, array $initialReferences = array()) { $loaders = $this->createNeededLoaders($set); // Objects are the loaded entities without "local". $objects = array(); // References contain, _all_ objects loaded. Needed only for loading. - $references = array(); + $references = $initialReferences; // Load each file foreach ($set->getFiles() as $file) { @@ -158,9 +158,6 @@ public function load(FixtureSet $set) $this->logDebug("Persisted " . count($objects) . " loaded objects."); } - // Detach entities - $this->getORM()->detach($objects); - return $objects; } diff --git a/Fixtures/FixtureManagerInterface.php b/Fixtures/FixtureManagerInterface.php index 07f1f63..827fc54 100644 --- a/Fixtures/FixtureManagerInterface.php +++ b/Fixtures/FixtureManagerInterface.php @@ -39,10 +39,13 @@ public function createFixtureSet(); * Loads objects/entities from given FixtureSet. * The FixtureSet Object will decide, if drop or persist will be done as well as all other parameters. * + * The initial references array can be used to provide already loaded entities so they can be referenced. + * * @param FixtureSet $set + * @param array $initialReferences * @return mixed */ - public function load(FixtureSet $set); + public function load(FixtureSet $set, array $initialReferences = array()); /** * Persists all given entities. diff --git a/README.md b/README.md index fc8a281..541021d 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ This means _all_ tables managed by Doctrine will be dropped and recreated. A dat ## Installation Simply require the bundle by its name with composer: + ```bash $ php composer.phar require h4cc/alice-fixtures-bundle ``` @@ -40,6 +41,7 @@ Follow the 'dev-master' branch for latest dev version. But i recommend to use mo After that, add the Bundle to your Kernel, most likely in the "dev" or "test" environment. + ```php getContainer()->get('h4cc_alice_fixtures.manager'); @@ -177,23 +181,31 @@ h4cc_alice_fixtures h4cc_alice_fixtures:load:sets Load fixture sets using alice and faker. ``` +By default, all fixture files or sets will share their references. This way a Bundle can reference the fixtures from another bundles. + Example for loading single files using all available options: + ```bash $ php app/console h4cc_alice_fixtures:load:files --manager=default --type=yaml --seed=42 --local=de_DE --no-persist --drop src/Acme/DemoBundle/Fixtures/Users.yml src/Acme/DemoBundle/Fixtures/Articles.yml ``` Example command for loading the given FixtureSet: + ```bash $ php app/console h4cc_alice_fixtures:load:sets src/Acme/DemoBundle/Fixtures/UsersAndArticlesSet.php ``` -When your FixtureSets are stored at the default path 'DataFixtures/Alice/' and are named like 'ExampleSet.php', they can be found automaticaly. Like the fixtures in Doctrine Datafixtures do. +When your FixtureSets are stored at the default path 'DataFixtures/Alice/' and are named ending in ...'Set.php', they can be found automaticaly. Like the fixtures in Doctrine Datafixtures do. To load the default fixture sets, simply execute this command: + ```bash $ php app/console h4cc_alice_fixtures:load:sets ``` -Preconfigured FixtureSet: +The order in which the bundles are loaded is defined by the order in which they are defined in `AppKernel`. + +Example for a Preconfigured FixtureSet: + ```php managerMock->expects($this->once())->method('load'); + $this->managerMock->expects($this->once())->method('load')->willReturn(array('abc' => 42)); $tester = new CommandTester($this->command); @@ -80,7 +80,7 @@ public function testLoad() public function testLoadWithoutDefaultManager() { - $this->managerMock->expects($this->once())->method('load'); + $this->managerMock->expects($this->once())->method('load')->willReturn(array('abc' => 42)); $tester = new CommandTester($this->command); diff --git a/Tests/Command/LoadSetsCommandTest.php b/Tests/Command/LoadSetsCommandTest.php index 241b15c..c1cd74b 100644 --- a/Tests/Command/LoadSetsCommandTest.php +++ b/Tests/Command/LoadSetsCommandTest.php @@ -67,7 +67,7 @@ public function setUp() public function testLoad() { - $this->managerMock->expects($this->once())->method('load'); + $this->managerMock->expects($this->once())->method('load')->willReturn(array('abc' => 42)); $tester = new CommandTester($this->command); @@ -78,7 +78,7 @@ public function testLoad() public function testLoadWithoutDefaultManager() { - $this->managerMock->expects($this->once())->method('load'); + $this->managerMock->expects($this->once())->method('load')->willReturn(array('abc' => 42)); $tester = new CommandTester($this->command); @@ -120,6 +120,7 @@ public function testLoadErrorNoSets() public function testLoadWithDefaultLoadedSet() { $this->bundleMock->expects($this->any())->method('getPath')->will($this->returnValue(__DIR__.'/SampleBundle')); + $this->managerMock->expects($this->once())->method('load')->willReturn(array('abc' => 42)); $tester = new CommandTester($this->command); @@ -127,7 +128,7 @@ public function testLoadWithDefaultLoadedSet() array('command' => $this->command->getName()) ); - $this->assertEquals("Loading file '".__DIR__.'/SampleBundle'."/DataFixtures/Alice/FooSet.php' ... loaded 0 entities ... done.\n", $tester->getDisplay()); + $this->assertEquals("Loading file '".__DIR__.'/SampleBundle'."/DataFixtures/Alice/FooSet.php' ... loaded 1 entities ... done.\n", $tester->getDisplay()); } /**