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

Add support for array of objects as reference #141

Open
wants to merge 22 commits into
base: 1.5.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
language: php

php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm

matrix:
allow_failures:
- php: hhvm

before_script: composer --dev --prefer-source install

script: phpunit -v
198 changes: 109 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,109 +4,125 @@ This extension aims to provide a simple way to manage and execute the loading of
for the Doctrine ORM or ODM. You can write fixture classes by implementing the
Doctrine\Common\DataFixtures\FixtureInterface interface:

namespace MyDataFixtures;
```php
namespace MyDataFixtures;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;

class LoadUserData implements FixtureInterface
class LoadUserData implements FixtureInterface
{
public function load(ObjectManager $manager)
{
public function load(ObjectManager $manager)
{
$user = new User();
$user->setUsername('jwage');
$user->setPassword('test');

$manager->persist($user);
$manager->flush();
}
$user = new User();
$user->setUsername('jwage');
$user->setPassword('test');

$manager->persist($user);
$manager->flush();
}
}
```

Now you can begin adding the fixtures to a loader instance:

use Doctrine\Common\DataFixtures\Loader;
use MyDataFixtures\LoadUserData;
```php
use Doctrine\Common\DataFixtures\Loader;
use MyDataFixtures\LoadUserData;

$loader = new Loader();
$loader->addFixture(new LoadUserData);
$loader = new Loader();
$loader->addFixture(new LoadUserData);
```

You can load a set of fixtures from a directory as well:

$loader->loadFromDirectory('/path/to/MyDataFixtures');
```php
$loader->loadFromDirectory('/path/to/MyDataFixtures');
```

You can get the added fixtures using the getFixtures() method:

$fixtures = $loader->getFixtures();
```php
$fixtures = $loader->getFixtures();
```

Now you can easily execute the fixtures:

use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
```php
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;

$purger = new ORMPurger();
$executor = new ORMExecutor($em, $purger);
$executor->execute($loader->getFixtures());
$purger = new ORMPurger();
$executor = new ORMExecutor($em, $purger);
$executor->execute($loader->getFixtures());
```

If you want to append the fixtures instead of purging before loading then pass true
to the 2nd argument of execute:

$executor->execute($loader->getFixtures(), true);
```php
$executor->execute($loader->getFixtures(), true);
```

## Sharing objects between fixtures

In case if fixture objects have relations to other fixtures, it is now possible
to easily add a reference to that object by name and later reference it to form
a relation. Here is an example fixtures for **Role** and **User** relation

namespace MyDataFixtures;
```php
namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;

class LoadUserRoleData extends AbstractFixture
class LoadUserRoleData extends AbstractFixture
{
public function load(ObjectManager $manager)
{
public function load(ObjectManager $manager)
{
$adminRole = new Role();
$adminRole->setName('admin');
$adminRole = new Role();
$adminRole->setName('admin');

$anonymousRole = new Role;
$anonymousRole->setName('anonymous');
$anonymousRole = new Role;
$anonymousRole->setName('anonymous');

$manager->persist($adminRole);
$manager->persist($anonymousRole);
$manager->flush();
$manager->persist($adminRole);
$manager->persist($anonymousRole);
$manager->flush();

// store reference to admin role for User relation to Role
$this->addReference('admin-role', $adminRole);
}
// store reference to admin role for User relation to Role
$this->addReference('admin-role', $adminRole);
}
}
```

And the **User** data loading fixture:

namespace MyDataFixtures;
```php
namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;

class LoadUserData extends AbstractFixture
class LoadUserData extends AbstractFixture
{
public function load(ObjectManager $manager)
{
public function load(ObjectManager $manager)
{
$user = new User();
$user->setUsername('jwage');
$user->setPassword('test');
$user->setRole(
$this->getReference('admin-role') // load the stored reference
);

$manager->persist($user);
$manager->flush();

// store reference of admin-user for other Fixtures
$this->addReference('admin-user', $user);
}
$user = new User();
$user->setUsername('jwage');
$user->setPassword('test');
$user->setRole(
$this->getReference('admin-role') // load the stored reference
);

$manager->persist($user);
$manager->flush();

// store reference of admin-user for other Fixtures
$this->addReference('admin-user', $user);
}
}
```

## Fixture ordering
**Notice** that the fixture loading order is important! To handle it manually
Expand All @@ -116,49 +132,53 @@ implement one of the following interfaces:

Set the order manually:

namespace MyDataFixtures;
```php
namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;

class MyFixture extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{}
class MyFixture extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{}

public function getOrder()
{
return 10; // number in which order to load fixtures
}
public function getOrder()
{
return 10; // number in which order to load fixtures
}
}
```

### DependentFixtureInterface

Provide an array of fixture class names:

namespace MyDataFixtures;
```php
namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;

class MyFixture extends AbstractFixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager)
{}

public function getDependencies()
{
return array('MyDataFixtures\MyOtherFixture'); // fixture classes fixture is dependent on
}
}
class MyFixture extends AbstractFixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager)
{}

class MyOtherFixture extends AbstractFixture
public function getDependencies()
{
public function load(ObjectManager $manager)
{}
return array('MyDataFixtures\MyOtherFixture'); // fixture classes fixture is dependent on
}
}

class MyOtherFixture extends AbstractFixture
{
public function load(ObjectManager $manager)
{}
}
```

**Notice** the ordering is relevant to Loader class.

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
],
"require": {
"php": ">=5.3.2",
"doctrine/common": ">=2.2,<2.5-dev"
"doctrine/common": "~2.2"
},
"require-dev": {
"doctrine/orm": ">=2.2,<2.5-dev"
"doctrine/orm": "~2.2"
},
"suggest": {
"doctrine/orm": "For loading ORM fixtures",
Expand Down
5 changes: 4 additions & 1 deletion lib/Doctrine/Common/DataFixtures/AbstractFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,14 @@ public function setReference($name, $object)
/**
* Set the reference entry identified by $name
* and referenced to managed $object. If $name
* already is set, it overrides it
* already is set, it throws a
* BadMethodCallException exception
*
* @param string $name
* @param object $object - managed object
* @see Doctrine\Common\DataFixtures\ReferenceRepository::addReference
* @throws BadMethodCallException - if repository already has
* a reference by $name
* @return void
*/
public function addReference($name, $object)
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/Common/DataFixtures/FixtureInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface FixtureInterface
/**
* Load data fixtures with the passed EntityManager
*
* @param Doctrine\Common\Persistence\ObjectManager $manager
* @param ObjectManager $manager
*/
function load(ObjectManager $manager);
public function load(ObjectManager $manager);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ interface OrderedFixtureInterface
*
* @return integer
*/
function getOrder();
public function getOrder();
}
6 changes: 4 additions & 2 deletions lib/Doctrine/Common/DataFixtures/ProxyReferenceRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* Allow data fixture references and identities to be persisted when cached data fixtures
* are pre-loaded, for example, by LiipFunctionalTestBundle\Test\WebTestCase loadFixtures().
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Anthon Pang <anthonp@nationalfibre.net>
*/
class ProxyReferenceRepository extends ReferenceRepository
Expand Down Expand Up @@ -59,12 +60,13 @@ protected function getRealClass($className)
*/
public function serialize()
{
$unitOfWork = $this->getManager()->getUnitOfWork();
$simpleReferences = array();

foreach ($this->getReferences() as $name => $reference) {
$className = $this->getRealClass(get_class($reference));

$simpleReferences[$name] = array($className, $reference->getId());
$simpleReferences[$name] = array($className, $this->getIdentifier($reference, $unitOfWork));
}

$serializedData = json_encode(array(
Expand All @@ -90,7 +92,7 @@ public function unserialize($serializedData)
$name,
$this->getManager()->getReference(
$proxyReference[0], // entity class name
$proxyReference[1] // id
$proxyReference[1] // identifiers
)
);
}
Expand Down
7 changes: 5 additions & 2 deletions lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,11 @@ public function purge()
for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
$class = $commitOrder[$i];

if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
|| $class->isMappedSuperclass) {
if (
($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName) ||
(isset($class->isEmbeddedClass) && $class->isEmbeddedClass) ||
$class->isMappedSuperclass
) {
continue;
}

Expand Down
Loading