Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Allow fixture classes to be loaded individually. #68

Closed
wants to merge 1 commit into from

3 participants

@mariusz-alef-bak

This pull requests allows to load individual fixture classes by their class names by adding --fixture-classes option.

In some projects which require various fixture sets (e.g. for different setups for various environments) being able to point fixtures only by directory is quite a pain as some fixtures may be reused in few sets. Moving them to subdirectories doesn't solve the problem in some cases as namespaces would have to be adjusted accordingly and code would have to be duplicated. There were some issues reported concerning the lack of this feature both in this repo and in data-fixtures.

I have made a similar pull request doctrine/data-fixtures#79 to data-fixtures to allow loading individual files instead of directories and I was hoping to add this behaviour also to DoctrineFixturesBundle, but the pull request hasn't been merged yet. This pull request is another way to add similar (or maybe even better) functionality directly to DoctrineFixturesBundle, as addFixture method is already available in data-fixtures Loader class.

@lsmith77
Collaborator

maybe it should be possible to be able to specify the class names with some glob like syntax?

@mariusz-alef-bak

@lsmith77 I think it would be difficult as one depends on autoloader to find and require these classes when their names are specified and they are to be instantiated. Only solution I can think of is to load or scan all fixture classes located in DataFixture/ORM directories of all bundles and later execute search with glob-like pattern on this list. However it doesn't seem very neat, does it? Can you think of any other solution?

Please note that the option I propose gives a developer full flexibility, as it can be used together with --fixtures option. So one still can load whole sets of fixtures if only they are grouped in directories.

@lavoiesl
Collaborator

Will be fixed by #97 (only by files)

@lavoiesl lavoiesl added the Duplicate label
@lavoiesl lavoiesl closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
43 Command/LoadDataFixturesDoctrineCommand.php
@@ -37,7 +37,8 @@ protected function configure()
$this
->setName('doctrine:fixtures:load')
->setDescription('Load data fixtures to your database.')
- ->addOption('fixtures', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The directory or file to load data fixtures from.')
+ ->addOption('fixtures', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The directory to load data fixtures from.')
+ ->addOption('fixture-classes', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The fixtures classes to load data fixtures from.')
->addOption('append', null, InputOption::VALUE_NONE, 'Append the data fixtures instead of deleting all data from the database first.')
->addOption('em', null, InputOption::VALUE_REQUIRED, 'The entity manager to use for this command.')
->addOption('purge-with-truncate', null, InputOption::VALUE_NONE, 'Purge data by using a database-level TRUNCATE statement')
@@ -50,6 +51,11 @@ protected function configure()
<info>./app/console doctrine:fixtures:load --fixtures=/path/to/fixtures1 --fixtures=/path/to/fixtures2</info>
+You can also optionally specify the classes of fixtures with the <info>--fixture-classes</info> option
+(replace <comment>\</comment> in class name with <comment>/</comment>):
+
+ <info>./app/console doctrine:fixtures:load --fixture-classes=ClassName/Of/Fixtures1 --fixture-classes=ClassName/Of/Fixtures2</info>
+
If you want to append the fixtures instead of flushing the database first you can use the <info>--append</info> option:
<info>./app/console doctrine:fixtures:load --append</info>
@@ -80,21 +86,54 @@ protected function execute(InputInterface $input, OutputInterface $output)
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
} else {
$paths = array();
+ }
+
+ $classNames = $input->getOption('fixture-classes');
+ if ($classNames) {
+ $classNames = is_array($classNames) ? $classNames : array($classNames);
+ $classNames = array_map(function ($className) {
+ return str_replace('/', '\\', $className);
+ }, $classNames);
+ } else {
+ $classNames = array();
+ }
+
+ if (!$paths && !$classNames) {
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);
}
}
+
+ foreach ($classNames as $className) {
+ if (!class_exists($className)) {
+ throw new InvalidArgumentException(
+ sprintf('Could not load class %s', $className)
+ );
+ }
+ if (!$loader->isTransient($className)) {
+ $loader->addFixture(new $className);
+ }
+ }
+
$fixtures = $loader->getFixtures();
if (!$fixtures) {
+ $message = array();
+ if ($paths) {
+ $message[] = sprintf('in paths: %s', "\n\n- ".implode("\n- ", $paths));
+ }
+ if ($classNames) {
+ $message[] = sprintf('in classes: %s', "\n\n- ".implode("\n- ", $classNames));
+ }
throw new InvalidArgumentException(
- sprintf('Could not find any fixtures to load in: %s', "\n\n- ".implode("\n- ", $paths))
+ sprintf('Could not find any fixtures to load %s', implode("\n\nand ", $message))
);
}
$purger = new ORMPurger($em);
View
3  Resources/doc/index.rst
@@ -128,6 +128,9 @@ Both commands come with a few options:
* ``--fixtures=/path/to/fixture`` - Use this option to manually specify the
directory where the fixtures classes should be loaded;
+* ``--fixture-classes=ClassName/Of/Fixture`` - Use this option to manualy specify the
+ class of the fixtures that should be loaded (replace ``\`` in class name with ``/``);
+
* ``--append`` - Use this flag to append data instead of deleting data before
loading it (deleting first is the default behavior);
Something went wrong with that request. Please try again.