PK CV 0$ $ phpunit.xml.distnu W+A
./tests/Doctrine/
PK CVqo o = lib/Doctrine/Common/DataFixtures/ProxyReferenceRepository.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures;
use Doctrine\Common\Version;
use Doctrine\Common\Util\ClassUtils;
/**
* Proxy reference repository
*
* 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
* @author Anthon Pang
*/
class ProxyReferenceRepository extends ReferenceRepository
{
/**
* Get real class name of a reference that could be a proxy
*
* @param string $className Class name of reference object
*
* @return string
*/
protected function getRealClass($className)
{
if (Version::compare('2.2.0') <= 0) {
return ClassUtils::getRealClass($className);
}
if (substr($className, -5) === 'Proxy') {
return substr($className, 0, -5);
}
return $className;
}
/**
* Serialize reference repository
*
* @return string
*/
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, $this->getIdentifier($reference, $unitOfWork));
}
$serializedData = json_encode(array(
'references' => $simpleReferences,
'identities' => $this->getIdentities(),
));
return $serializedData;
}
/**
* Unserialize reference repository
*
* @param string $serializedData Serialized data
*/
public function unserialize($serializedData)
{
$repositoryData = json_decode($serializedData, true);
$references = $repositoryData['references'];
foreach ($references as $name => $proxyReference) {
$this->setReference(
$name,
$this->getManager()->getReference(
$proxyReference[0], // entity class name
$proxyReference[1] // identifiers
)
);
}
$identities = $repositoryData['identities'];
foreach ($identities as $name => $identity) {
$this->setReferenceIdentity($name, $identity);
}
}
/**
* Load data fixture reference repository
*
* @param string $baseCacheName Base cache name
*
* @return boolean
*/
public function load($baseCacheName)
{
$filename = $baseCacheName . '.ser';
if ( ! file_exists($filename) || ($serializedData = file_get_contents($filename)) === false) {
return false;
}
$this->unserialize($serializedData);
return true;
}
/**
* Save data fixture reference repository
*
* @param string $baseCacheName Base cache name
*/
public function save($baseCacheName)
{
$serializedData = $this->serialize();
file_put_contents($baseCacheName . '.ser', $serializedData);
}
}
PK CVJ1 J1 + lib/Doctrine/Common/DataFixtures/Loader.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures;
use Doctrine\Common\DataFixtures\Exception\CircularReferenceException;
/**
* Class responsible for loading data fixture classes.
*
* @author Jonathan H. Wage
*/
class Loader
{
/**
* Array of fixture object instances to execute.
*
* @var array
*/
private $fixtures = array();
/**
* Array of ordered fixture object instances.
*
* @var array
*/
private $orderedFixtures = array();
/**
* Determines if we must order fixtures by number
*
* @var boolean
*/
private $orderFixturesByNumber = false;
/**
* Determines if we must order fixtures by its dependencies
*
* @var boolean
*/
private $orderFixturesByDependencies = false;
/**
* The file extension of fixture files.
*
* @var string
*/
private $fileExtension = '.php';
/**
* Find fixtures classes in a given directory and load them.
*
* @param string $dir Directory to find fixture classes in.
* @return array $fixtures Array of loaded fixture object instances.
*/
public function loadFromDirectory($dir)
{
if (!is_dir($dir)) {
throw new \InvalidArgumentException(sprintf('"%s" does not exist', $dir));
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
return $this->loadFromIterator($iterator);
}
/**
* Find fixtures classes in a given file and load them.
*
* @param string $fileName File to find fixture classes in.
* @return array $fixtures Array of loaded fixture object instances.
*/
public function loadFromFile($fileName)
{
if (!is_readable($fileName)) {
throw new \InvalidArgumentException(sprintf('"%s" does not exist or is not readable', $fileName));
}
$iterator = new \ArrayIterator(array(new \SplFileInfo($fileName)));
return $this->loadFromIterator($iterator);
}
/**
* Has fixture?
*
* @param FixtureInterface $fixture
*
* @return boolean
*/
public function hasFixture($fixture)
{
return isset($this->fixtures[get_class($fixture)]);
}
/**
* Add a fixture object instance to the loader.
*
* @param FixtureInterface $fixture
*/
public function addFixture(FixtureInterface $fixture)
{
$fixtureClass = get_class($fixture);
if (!isset($this->fixtures[$fixtureClass])) {
if ($fixture instanceof OrderedFixtureInterface && $fixture instanceof DependentFixtureInterface) {
throw new \InvalidArgumentException(sprintf('Class "%s" can\'t implement "%s" and "%s" at the same time.',
get_class($fixture),
'OrderedFixtureInterface',
'DependentFixtureInterface'));
}
$this->fixtures[$fixtureClass] = $fixture;
if ($fixture instanceof OrderedFixtureInterface) {
$this->orderFixturesByNumber = true;
} elseif ($fixture instanceof DependentFixtureInterface) {
$this->orderFixturesByDependencies = true;
foreach($fixture->getDependencies() as $class) {
if (class_exists($class)) {
$this->addFixture(new $class);
}
}
}
}
}
/**
* Returns the array of data fixtures to execute.
*
* @return array $fixtures
*/
public function getFixtures()
{
$this->orderedFixtures = array();
if ($this->orderFixturesByNumber) {
$this->orderFixturesByNumber();
}
if ($this->orderFixturesByDependencies) {
$this->orderFixturesByDependencies();
}
if (!$this->orderFixturesByNumber && !$this->orderFixturesByDependencies) {
$this->orderedFixtures = $this->fixtures;
}
return $this->orderedFixtures;
}
/**
* Check if a given fixture is transient and should not be considered a data fixtures
* class.
*
* @return boolean
*/
public function isTransient($className)
{
$rc = new \ReflectionClass($className);
if ($rc->isAbstract()) return true;
$interfaces = class_implements($className);
return in_array('Doctrine\Common\DataFixtures\FixtureInterface', $interfaces) ? false : true;
}
/**
* Orders fixtures by number
*
* @todo maybe there is a better way to handle reordering
* @return void
*/
private function orderFixturesByNumber()
{
$this->orderedFixtures = $this->fixtures;
usort($this->orderedFixtures, function($a, $b) {
if ($a instanceof OrderedFixtureInterface && $b instanceof OrderedFixtureInterface) {
if ($a->getOrder() === $b->getOrder()) {
return 0;
}
return $a->getOrder() < $b->getOrder() ? -1 : 1;
} elseif ($a instanceof OrderedFixtureInterface) {
return $a->getOrder() === 0 ? 0 : 1;
} elseif ($b instanceof OrderedFixtureInterface) {
return $b->getOrder() === 0 ? 0 : -1;
}
return 0;
});
}
/**
* Orders fixtures by dependencies
*
* @return void
*/
private function orderFixturesByDependencies()
{
$sequenceForClasses = array();
// If fixtures were already ordered by number then we need
// to remove classes which are not instances of OrderedFixtureInterface
// in case fixtures implementing DependentFixtureInterface exist.
// This is because, in that case, the method orderFixturesByDependencies
// will handle all fixtures which are not instances of
// OrderedFixtureInterface
if ($this->orderFixturesByNumber) {
$count = count($this->orderedFixtures);
for ($i = 0 ; $i < $count ; ++$i) {
if (!($this->orderedFixtures[$i] instanceof OrderedFixtureInterface)) {
unset($this->orderedFixtures[$i]);
}
}
}
// First we determine which classes has dependencies and which don't
foreach ($this->fixtures as $fixture) {
$fixtureClass = get_class($fixture);
if ($fixture instanceof OrderedFixtureInterface) {
continue;
} elseif ($fixture instanceof DependentFixtureInterface) {
$dependenciesClasses = $fixture->getDependencies();
$this->validateDependencies($dependenciesClasses);
if (!is_array($dependenciesClasses) || empty($dependenciesClasses)) {
throw new \InvalidArgumentException(sprintf('Method "%s" in class "%s" must return an array of classes which are dependencies for the fixture, and it must be NOT empty.', 'getDependencies', $fixtureClass));
}
if (in_array($fixtureClass, $dependenciesClasses)) {
throw new \InvalidArgumentException(sprintf('Class "%s" can\'t have itself as a dependency', $fixtureClass));
}
// We mark this class as unsequenced
$sequenceForClasses[$fixtureClass] = -1;
} else {
// This class has no dependencies, so we assign 0
$sequenceForClasses[$fixtureClass] = 0;
}
}
// Now we order fixtures by sequence
$sequence = 1;
$lastCount = -1;
while (($count = count($unsequencedClasses = $this->getUnsequencedClasses($sequenceForClasses))) > 0 && $count !== $lastCount) {
foreach ($unsequencedClasses as $key => $class) {
$fixture = $this->fixtures[$class];
$dependencies = $fixture->getDependencies();
$unsequencedDependencies = $this->getUnsequencedClasses($sequenceForClasses, $dependencies);
if (count($unsequencedDependencies) === 0) {
$sequenceForClasses[$class] = $sequence++;
}
}
$lastCount = $count;
}
$orderedFixtures = array();
// If there're fixtures unsequenced left and they couldn't be sequenced,
// it means we have a circular reference
if ($count > 0) {
$msg = 'Classes "%s" have produced a CircularReferenceException. ';
$msg .= 'An example of this problem would be the following: Class C has class B as its dependency. ';
$msg .= 'Then, class B has class A has its dependency. Finally, class A has class C as its dependency. ';
$msg .= 'This case would produce a CircularReferenceException.';
throw new CircularReferenceException(sprintf($msg, implode(',', $unsequencedClasses)));
} else {
// We order the classes by sequence
asort($sequenceForClasses);
foreach ($sequenceForClasses as $class => $sequence) {
// If fixtures were ordered
$orderedFixtures[] = $this->fixtures[$class];
}
}
$this->orderedFixtures = array_merge($this->orderedFixtures, $orderedFixtures);
}
private function validateDependencies($dependenciesClasses)
{
$loadedFixtureClasses = array_keys($this->fixtures);
foreach ($dependenciesClasses as $class) {
if (!in_array($class, $loadedFixtureClasses)) {
throw new \RuntimeException(sprintf('Fixture "%s" was declared as a dependency, but it should be added in fixture loader first.', $class));
}
}
return true;
}
private function getUnsequencedClasses($sequences, $classes = null)
{
$unsequencedClasses = array();
if (is_null($classes)) {
$classes = array_keys($sequences);
}
foreach ($classes as $class) {
if ($sequences[$class] === -1) {
$unsequencedClasses[] = $class;
}
}
return $unsequencedClasses;
}
/**
* Load fixtures from files contained in iterator.
*
* @param \Iterator $iterator Iterator over files from which fixtures should be loaded.
* @return array $fixtures Array of loaded fixture object instances.
*/
private function loadFromIterator(\Iterator $iterator)
{
$includedFiles = array();
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
$fixtures = array();
$declared = get_declared_classes();
foreach ($declared as $className) {
$reflClass = new \ReflectionClass($className);
$sourceFile = $reflClass->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$fixture = new $className;
$fixtures[] = $fixture;
$this->addFixture($fixture);
}
}
return $fixtures;
}
}
PK CVA 8 lib/Doctrine/Common/DataFixtures/ReferenceRepository.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ODM\PHPCR\DocumentManager as PhpcrDocumentManager;
/**
* ReferenceRepository class manages references for
* fixtures in order to easily support the relations
* between fixtures
*
* @author Gediminas Morkevicius
*/
class ReferenceRepository
{
/**
* List of named references to the fixture objects
* gathered during loads of fixtures
*
* @var array
*/
private $references = array();
/**
* List of identifiers stored for references
* in case if reference gets unmanaged, it will
* use a proxy referenced by this identity
*
* @var array
*/
private $identities = array();
/**
* Currently used object manager
*
* @var Doctrine\Common\Persistence\ObjectManager
*/
private $manager;
/**
* Initialize the ReferenceRepository
*
* @param Doctrine\Common\Persistence\ObjectManager $manager
*/
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Get identifier for a unit of work
*
* @param object $reference Reference object
* @param object $uow Unit of work
*
* @return array
*/
protected function getIdentifier($reference, $uow)
{
// In case Reference is not yet managed in UnitOfWork
if ( ! $this->hasIdentifier($reference)) {
$class = $this->manager->getClassMetadata(get_class($reference));
return $class->getIdentifierValues($reference);
}
// Dealing with ORM UnitOfWork
if (method_exists($uow, 'getEntityIdentifier')) {
return $uow->getEntityIdentifier($reference);
}
// ODM UnitOfWork
return $uow->getDocumentIdentifier($reference);
}
/**
* Set the reference entry identified by $name
* and referenced to $reference. If $name
* already is set, it overrides it
*
* @param string $name
* @param object $reference
*/
public function setReference($name, $reference)
{
$this->references[$name] = $reference;
if ($this->hasIdentifier($reference)) {
// in case if reference is set after flush, store its identity
$uow = $this->manager->getUnitOfWork();
$this->identities[$name] = $this->getIdentifier($reference, $uow);
}
}
/**
* Store the identifier of a reference
*
* @param string $name
* @param mixed $identity
*/
public function setReferenceIdentity($name, $identity)
{
$this->identities[$name] = $identity;
}
/**
* Set the reference entry identified by $name
* and referenced to managed $object. $name must
* not be set yet
*
* Notice: in case if identifier is generated after
* the record is inserted, be sure tu use this method
* after $object is flushed
*
* @param string $name
* @param object $object - managed object
* @throws BadMethodCallException - if repository already has
* a reference by $name
* @return void
*/
public function addReference($name, $object)
{
if (isset($this->references[$name])) {
throw new \BadMethodCallException("Reference to: ({$name}) already exists, use method setReference in order to override it");
}
$this->setReference($name, $object);
}
/**
* Loads an object using stored reference
* named by $name
*
* @param string $name
* @throws OutOfBoundsException - if repository does not exist
* @return object
*/
public function getReference($name)
{
if (!$this->hasReference($name)) {
throw new \OutOfBoundsException("Reference to: ({$name}) does not exist");
}
$reference = $this->references[$name];
$meta = $this->manager->getClassMetadata(get_class($reference));
if (!$this->manager->contains($reference) && isset($this->identities[$name])) {
$reference = $this->manager->getReference(
$meta->name,
$this->identities[$name]
);
$this->references[$name] = $reference; // already in identity map
}
return $reference;
}
/**
* Check if an object is stored using reference
* named by $name
*
* @param string $name
* @return boolean
*/
public function hasReference($name)
{
return isset($this->references[$name]);
}
/**
* Searches for reference names in the
* list of stored references
*
* @param object $reference
* @return array
*/
public function getReferenceNames($reference)
{
return array_keys($this->references, $reference, true);
}
/**
* Checks if reference has identity stored
*
* @param string $name
*/
public function hasIdentity($name)
{
return array_key_exists($name, $this->identities);
}
/**
* Get all stored identities
*
* @return array
*/
public function getIdentities()
{
return $this->identities;
}
/**
* Get all stored references
*
* @return array
*/
public function getReferences()
{
return $this->references;
}
/**
* Get object manager
*
* @return Doctrine\Common\Persistence\ObjectManager
*/
public function getManager()
{
return $this->manager;
}
/**
* Checks if object has identifier already in unit of work.
*
* @param $reference
*
* @return bool
*/
private function hasIdentifier($reference)
{
// in case if reference is set after flush, store its identity
$uow = $this->manager->getUnitOfWork();
if ($this->manager instanceof PhpcrDocumentManager) {
return $uow->contains($reference);
} else {
return $uow->isInIdentityMap($reference);
}
}
}
PK CVrUk L lib/Doctrine/Common/DataFixtures/Event/Listener/MongoDBReferenceListener.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Event\Listener;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
/**
* Reference Listener populates identities for
* stored references
*
* @author Gediminas Morkevicius
*/
final class MongoDBReferenceListener implements EventSubscriber
{
/**
* @var ReferenceRepository
*/
private $referenceRepository;
/**
* Initialize listener
*
* @param ReferenceRepository $referenceRepository
*/
public function __construct(ReferenceRepository $referenceRepository)
{
$this->referenceRepository = $referenceRepository;
}
/**
* {@inheritdoc}
*/
public function getSubscribedEvents()
{
return array(
'postPersist'
);
}
/**
* Populates identities for stored references
*
* @param LifecycleEventArgs $args
*/
public function postPersist(LifecycleEventArgs $args)
{
$object = $args->getDocument();
if (($names = $this->referenceRepository->getReferenceNames($object)) !== false) {
foreach ($names as $name) {
$identity = $args->getDocumentManager()
->getUnitOfWork()
->getDocumentIdentifier($object);
$this->referenceRepository->setReferenceIdentity($name, $identity);
}
}
}
}
PK CV H lib/Doctrine/Common/DataFixtures/Event/Listener/ORMReferenceListener.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Event\Listener;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\ORM\Event\LifecycleEventArgs;
/**
* Reference Listener populates identities for
* stored references
*
* @author Gediminas Morkevicius
*/
final class ORMReferenceListener implements EventSubscriber
{
/**
* @var ReferenceRepository
*/
private $referenceRepository;
/**
* Initialize listener
*
* @param ReferenceRepository $referenceRepository
*/
public function __construct(ReferenceRepository $referenceRepository)
{
$this->referenceRepository = $referenceRepository;
}
/**
* {@inheritdoc}
*/
public function getSubscribedEvents()
{
return array(
'postPersist' // would be better to use onClear, but it is supported only in 2.1
);
}
/**
* Populates identities for stored references
*
* @param LifecycleEventArgs $args
*/
public function postPersist(LifecycleEventArgs $args)
{
$object = $args->getEntity();
if (($names = $this->referenceRepository->getReferenceNames($object)) !== false) {
foreach ($names as $name) {
$identity = $args->getEntityManager()
->getUnitOfWork()
->getEntityIdentifier($object);
$this->referenceRepository->setReferenceIdentity($name, $identity);
}
}
}
}
PK CV~e I lib/Doctrine/Common/DataFixtures/Exception/CircularReferenceException.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Sorter;
/**
* @author Marco Pivetta
*
* @internal this class is to be used only by data-fixtures internals: do not
* rely on it in your own libraries/applications. This class is
* designed to work with {@see \Doctrine\Common\DataFixtures\Sorter\TopologicalSorter}
* only.
*/
class Vertex
{
const NOT_VISITED = 0;
const IN_PROGRESS = 1;
const VISITED = 2;
/**
* @var int one of either {@see self::NOT_VISITED}, {@see self::IN_PROGRESS} or {@see self::VISITED}.
*/
public $state = self::NOT_VISITED;
/**
* @var mixed Actual node value
*/
public $value;
/**
* @var string[] Map of node dependencies defined as hashes.
*/
public $dependencyList = [];
/**
* @param mixed $value
*/
public function __construct($value)
{
$this->value = $value;
}
}
PK CVj'egb b = lib/Doctrine/Common/DataFixtures/Sorter/TopologicalSorter.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Sorter;
use Doctrine\Common\DataFixtures\Exception\CircularReferenceException;
/**
* TopologicalSorter is an ordering algorithm for directed graphs (DG) and/or
* directed acyclic graphs (DAG) by using a depth-first searching (DFS) to
* traverse the graph built in memory.
* This algorithm have a linear running time based on nodes (V) and dependency
* between the nodes (E), resulting in a computational complexity of O(V + E).
*
* @author Guilherme Blanco
* @author Roman Borschel
*
* @internal this class is to be used only by data-fixtures internals: do not
* rely on it in your own libraries/applications.
*/
class TopologicalSorter
{
/**
* Matrix of nodes (aka. vertex).
* Keys are provided hashes and values are the node definition objects.
*
* @var Vertex[]
*/
private $nodeList = [];
/**
* Volatile variable holding calculated nodes during sorting process.
*
* @var array
*/
private $sortedNodeList = [];
/**
* Adds a new node (vertex) to the graph, assigning its hash and value.
*
* @param string $hash
* @param mixed $node
*
* @return void
*/
public function addNode($hash, $node)
{
$this->nodeList[$hash] = new Vertex($node);
}
/**
* Checks the existence of a node in the graph.
*
* @param string $hash
*
* @return bool
*/
public function hasNode($hash)
{
return isset($this->nodeList[$hash]);
}
/**
* Adds a new dependency (edge) to the graph using their hashes.
*
* @param string $fromHash
* @param string $toHash
*
* @return void
*/
public function addDependency($fromHash, $toHash)
{
$definition = $this->nodeList[$fromHash];
$definition->dependencyList[] = $toHash;
}
/**
* Return a valid order list of all current nodes.
* The desired topological sorting is the postorder of these searches.
*
* Note: Highly performance-sensitive method.
*
* @throws \RuntimeException
* @throws CircularReferenceException
*
* @return array
*/
public function sort()
{
foreach ($this->nodeList as $definition) {
if ($definition->state !== Vertex::NOT_VISITED) {
continue;
}
$this->visit($definition);
}
$sortedList = $this->sortedNodeList;
$this->nodeList = [];
$this->sortedNodeList = [];
return $sortedList;
}
/**
* Visit a given node definition for reordering.
*
* Note: Highly performance-sensitive method.
*
* @throws \RuntimeException
* @throws CircularReferenceException
*
* @param Vertex $definition
*/
private function visit(Vertex $definition)
{
$definition->state = Vertex::IN_PROGRESS;
foreach ($definition->dependencyList as $dependency) {
if ( ! isset($this->nodeList[$dependency])) {
throw new \RuntimeException(sprintf(
'Fixture "%s" has a dependency of fixture "%s", but it not listed to be loaded.',
get_class($definition->value),
$dependency
));
}
$childDefinition = $this->nodeList[$dependency];
switch ($childDefinition->state) {
case Vertex::VISITED:
break;
case Vertex::IN_PROGRESS:
throw new CircularReferenceException(
'Graph contains cyclic dependency. An example of this problem would be the following: '
. 'Class C has class B as its dependency. Then, class B has class A has its dependency. '
. 'Finally, class A has class C as its dependency.'
);
case Vertex::NOT_VISITED:
$this->visit($childDefinition);
}
}
$definition->state = Vertex::VISITED;
$this->sortedNodeList[] = $definition->value;
}
}
PK CV; 7 lib/Doctrine/Common/DataFixtures/Purger/PHPCRPurger.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Purger;
use PHPCR\Util\NodeHelper;
use Doctrine\ODM\PHPCR\DocumentManager;
/**
* Class responsible for purging databases of data before reloading data fixtures.
*
* @author Daniel Barsotti
*/
class PHPCRPurger implements PurgerInterface
{
/**
* DocumentManager instance used for persistence.
* @var DocumentManager
*/
private $dm;
/**
* Construct new purger instance.
*
* @param DocumentManager $dm DocumentManager instance used for persistence.
*/
public function __construct(DocumentManager $dm = null)
{
$this->dm = $dm;
}
/**
* Set the DocumentManager instance this purger instance should use.
*
* @param DocumentManager $dm
*/
public function setDocumentManager(DocumentManager $dm)
{
$this->dm = $dm;
}
/**
* Retrieve the DocumentManager instance this purger instance is using.
*
* @return \Doctrine\ODM\PHPCR\DocumentManager
*/
public function getObjectManager()
{
return $this->dm;
}
/**
* @inheritDoc
*/
public function purge()
{
$session = $this->dm->getPhpcrSession();
NodeHelper::purgeWorkspace($session);
$session->save();
}
}
PK CVUY 9 lib/Doctrine/Common/DataFixtures/Purger/MongoDBPurger.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Purger;
use Doctrine\ODM\MongoDB\DocumentManager;
/**
* Class responsible for purging databases of data before reloading data fixtures.
*
* @author Jonathan H. Wage
*/
class MongoDBPurger implements PurgerInterface
{
/** DocumentManager instance used for persistence. */
private $dm;
/**
* Construct new purger instance.
*
* @param DocumentManager $dm DocumentManager instance used for persistence.
*/
public function __construct(DocumentManager $dm = null)
{
$this->dm = $dm;
}
/**
* Set the DocumentManager instance this purger instance should use.
*
* @param DocumentManager $dm
*/
public function setDocumentManager(DocumentManager $dm)
{
$this->dm = $dm;
}
/**
* Retrieve the DocumentManager instance this purger instance is using.
*
* @return \Doctrine\ODM\MongoDB\DocumentManager
*/
public function getObjectManager()
{
return $this->dm;
}
/** @inheritDoc */
public function purge()
{
$metadatas = $this->dm->getMetadataFactory()->getAllMetadata();
foreach ($metadatas as $metadata) {
if ( ! $metadata->isMappedSuperclass) {
$this->dm->getDocumentCollection($metadata->name)->drop();
}
}
$this->dm->getSchemaManager()->ensureIndexes();
}
}
PK CVo ; lib/Doctrine/Common/DataFixtures/Purger/PurgerInterface.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Purger;
/**
* PurgerInterface
*
* @author Jonathan H. Wage
*/
interface PurgerInterface
{
/**
* Purge the data from the database for the given EntityManager.
*
* @return void
*/
function purge();
}
PK CV~ 5 lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures\Purger;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Common\DataFixtures\Sorter\TopologicalSorter;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* Class responsible for purging databases of data before reloading data fixtures.
*
* @author Jonathan H. Wage
* @author Benjamin Eberlei
*/
class ORMPurger implements PurgerInterface
{
const PURGE_MODE_DELETE = 1;
const PURGE_MODE_TRUNCATE = 2;
/** EntityManagerInterface instance used for persistence. */
private $em;
/**
* If the purge should be done through DELETE or TRUNCATE statements
*
* @var int
*/
private $purgeMode = self::PURGE_MODE_DELETE;
/**
* Construct new purger instance.
*
* @param EntityManagerInterface $em EntityManagerInterface instance used for persistence.
*/
public function __construct(EntityManagerInterface $em = null)
{
$this->em = $em;
}
/**
* Set the purge mode
*
* @param $mode
* @return void
*/
public function setPurgeMode($mode)
{
$this->purgeMode = $mode;
}
/**
* Get the purge mode
*
* @return int
*/
public function getPurgeMode()
{
return $this->purgeMode;
}
/**
* Set the EntityManagerInterface instance this purger instance should use.
*
* @param EntityManagerInterface $em
*/
public function setEntityManager(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Retrieve the EntityManagerInterface instance this purger instance is using.
*
* @return \Doctrine\ORM\EntityManagerInterface
*/
public function getObjectManager()
{
return $this->em;
}
/** @inheritDoc */
public function purge()
{
$classes = array();
foreach ($this->em->getMetadataFactory()->getAllMetadata() as $metadata) {
if (! $metadata->isMappedSuperclass && ! (isset($metadata->isEmbeddedClass) && $metadata->isEmbeddedClass)) {
$classes[] = $metadata;
}
}
$commitOrder = $this->getCommitOrder($this->em, $classes);
// Get platform parameters
$platform = $this->em->getConnection()->getDatabasePlatform();
// Drop association tables first
$orderedTables = $this->getAssociationTables($commitOrder, $platform);
// Drop tables in reverse commit order
for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
$class = $commitOrder[$i];
if (
(isset($class->isEmbeddedClass) && $class->isEmbeddedClass) ||
$class->isMappedSuperclass ||
($class->isInheritanceTypeSingleTable() && $class->name !== $class->rootEntityName)
) {
continue;
}
$orderedTables[] = $this->getTableName($class, $platform);
}
$connection = $this->em->getConnection();
foreach($orderedTables as $tbl) {
if ($this->purgeMode === self::PURGE_MODE_DELETE) {
$connection->executeUpdate('DELETE FROM ' . $tbl);
} else {
$connection->executeUpdate($platform->getTruncateTableSQL($tbl, true));
}
}
}
/**
* @param EntityManagerInterface $em
* @param ClassMetadata[] $classes
*
* @return ClassMetadata[]
*/
private function getCommitOrder(EntityManagerInterface $em, array $classes)
{
$sorter = new TopologicalSorter();
foreach ($classes as $class) {
$sorter->addNode($class->name, $class);
// $class before its parents
foreach ($class->parentClasses as $parentClass) {
$parentClass = $em->getClassMetadata($parentClass);
$parentClassName = $parentClass->getName();
if ( ! $sorter->hasNode($parentClassName)) {
$sorter->addNode($parentClassName, $parentClass);
}
$sorter->addDependency($class->name, $parentClassName);
}
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide']) {
/* @var $targetClass ClassMetadata */
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
$targetClassName = $targetClass->getName();
if ( ! $sorter->hasNode($targetClassName)) {
$sorter->addNode($targetClassName, $targetClass);
}
// add dependency ($targetClass before $class)
$sorter->addDependency($targetClassName, $class->name);
// parents of $targetClass before $class, too
foreach ($targetClass->parentClasses as $parentClass) {
$parentClass = $em->getClassMetadata($parentClass);
$parentClassName = $parentClass->getName();
if ( ! $sorter->hasNode($parentClassName)) {
$sorter->addNode($parentClassName, $parentClass);
}
$sorter->addDependency($parentClassName, $class->name);
}
}
}
}
return $sorter->sort();
}
/**
* @param array $classes
* @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
* @return array
*/
private function getAssociationTables(array $classes, AbstractPlatform $platform)
{
$associationTables = array();
foreach ($classes as $class) {
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) {
$associationTables[] = $this->getJoinTableName($assoc, $class, $platform);
}
}
}
return $associationTables;
}
/**
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
* @return string
*/
private function getTableName($class, $platform)
{
if (isset($class->table['schema']) && !method_exists($class, 'getSchemaName')) {
return $class->table['schema'].'.'.$this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform);
}
return $this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform);
}
/**
*
* @param array $association
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
* @return string
*/
private function getJoinTableName($assoc, $class, $platform)
{
if (isset($assoc['joinTable']['schema']) && !method_exists($class, 'getSchemaName')) {
return $assoc['joinTable']['schema'].'.'.$this->em->getConfiguration()->getQuoteStrategy()->getJoinTableName($assoc, $class, $platform);
}
return $this->em->getConfiguration()->getQuoteStrategy()->getJoinTableName($assoc, $class, $platform);
}
}
PK CVS > lib/Doctrine/Common/DataFixtures/DependentFixtureInterface.phpnu W+A .
*/
namespace Doctrine\Common\DataFixtures;
/**
* DependentFixtureInterface needs to be implemented
* by fixtures which depend on other fixtures
*
* @author Gustavo Adrian
*/
interface DependentFixtureInterface
{
/**
* This method must return an array of fixtures classes
* on which the implementing class depends on
*
* @return array
*/
function getDependencies();
}
PK CVd <