Permalink
Browse files

Initial functionality for storing the fixture references

  • Loading branch information...
1 parent 374d037 commit 18dbe2a767c100aa79ad36b7e600ea13c5929c07 @l3pp4rd l3pp4rd committed Feb 12, 2011
View
90 lib/Doctrine/Common/DataFixtures/AbstractFixture.php
@@ -0,0 +1,90 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\DataFixtures;
+
+use Doctrine\Common\DataFixtures\ReferenceRepository;
+
+/**
+ * Abstract Fixture class helps to manage references
+ * between fixture classes in order to set relations
+ * among other fixtures
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ */
+abstract class AbstractFixture implements SharedFixtureInterface
+{
+ /**
+ * Fixture reference repository
+ *
+ * @var ReferenceRepository
+ */
+ private $referenceRepository;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setReferenceRepository(ReferenceRepository $referenceRepository)
+ {
+ $this->referenceRepository = $referenceRepository;
+ }
+
+ /**
+ * Set the reference entry identified by $name
+ * and referenced to managed $object. If $name
+ * already is set, it overrides it
+ *
+ * @param string $name
+ * @param object $object - managed object
+ * @see Doctrine\Common\DataFixtures\ReferenceRepository::setReference
+ * @return void
+ */
+ public function setReference($name, $object)
+ {
+ $this->referenceRepository->setReference($name, $object);
+ }
+
+ /**
+ * Set the reference entry identified by $name
+ * and referenced to managed $object. If $name
+ * already is set, it overrides it
+ *
+ * @param string $name
+ * @param object $object - managed object
+ * @see Doctrine\Common\DataFixtures\ReferenceRepository::addReference
+ * @return void
+ */
+ public function addReference($name, $object)
+ {
+ $this->referenceRepository->addReference($name, $object);
+ }
+
+ /**
+ * Loads an object using stored reference
+ * named by $name
+ *
+ * @param string $name
+ * @see Doctrine\Common\DataFixtures\ReferenceRepository::getReference
+ * @return object
+ */
+ public function getReference($name)
+ {
+ return $this->referenceRepository->getReference($name);
+ }
+}
View
22 lib/Doctrine/Common/DataFixtures/Executor/AbstractExecutor.php
@@ -2,7 +2,9 @@
namespace Doctrine\Common\DataFixtures\Executor;
+use Doctrine\Common\DataFixtures\SharedFixtureInterface;
use Doctrine\Common\DataFixtures\FixtureInterface;
+use Doctrine\Common\DataFixtures\ReferenceRepository;
/**
* Abstract fixture executor.
@@ -18,6 +20,22 @@
protected $logger;
/**
+ * Fixture reference repository
+ * @var ReferenceRepository
+ */
+ protected $referenceRepository;
+
+ /**
+ * Loads an instance of reference repository
+ *
+ * @param object $manager
+ */
+ public function __construct($manager)
+ {
+ $this->referenceRepository = new ReferenceRepository($manager);
+ }
+
+ /**
* Sets the Purger instance to use for this exector instance.
*
* @param Purger $purger
@@ -59,6 +77,10 @@ public function load($manager, FixtureInterface $fixture)
if ($this->logger) {
$this->log('loading ' . get_class($fixture));
}
+ // additionaly pass the instance of reference repository to shared fixtures
+ if ($fixture instanceof SharedFixtureInterface) {
+ $fixture->setReferenceRepository($this->referenceRepository);
+ }
$fixture->load($manager);
$manager->clear();
}
View
1 lib/Doctrine/Common/DataFixtures/Executor/MongoDBExecutor.php
@@ -41,6 +41,7 @@ public function __construct(DocumentManager $dm, MongoDBPurger $purger = null)
$this->purger = $purger;
$this->purger->setDocumentManager($dm);
}
+ parent::__construct($dm);
}
/** @inheritDoc */
View
1 lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php
@@ -41,6 +41,7 @@ public function __construct(EntityManager $em, ORMPurger $purger = null)
$this->purger = $purger;
$this->purger->setEntityManager($em);
}
+ parent::__construct($em);
}
/** @inheritDoc */
View
33 lib/Doctrine/Common/DataFixtures/OrderedFixtureInterface.php
@@ -0,0 +1,33 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\DataFixtures;
+
+/**
+ * Shared Fixture interface needs to be implemented
+ * by fixtures, which needs some references to be shared
+ * among other fixture classes in order to maintain
+ * relation mapping
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ */
+interface OrderedFixtureInterface
+{
+ public function getOrder();
+}
View
147 lib/Doctrine/Common/DataFixtures/ReferenceRepository.php
@@ -0,0 +1,147 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\DataFixtures;
+
+/**
+ * ReferenceRepository class manages references for
+ * fixtures in order to easily support the relations
+ * between fixtures
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ */
+class ReferenceRepository
+{
+ /**
+ * List of named references to the fixture objects
+ * gathered during loads of fixtures
+ *
+ * @var array
+ */
+ private $references = array();
+
+ /**
+ * Currently used object manager
+ *
+ * @var object - object manager
+ */
+ private $manager;
+
+ /**
+ * Initialize the ReferenceRepository
+ *
+ * @param object $manager
+ */
+ public function __construct($manager)
+ {
+ $this->manager = $manager;
+ }
+
+ /**
+ * Set the reference entry identified by $name
+ * and referenced to managed $object. If $name
+ * already is set, it overrides it
+ *
+ * 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 LogicException - if object is not mapped or
+ * does not have identifier yet
+ * @return void
+ */
+ public function setReference($name, $object)
+ {
+ $objectClass = get_class($object);
+ if (!$this->manager->getMetadataFactory()->hasMetadataFor(get_class($object))) {
+ throw new \LogicException("While setting a reference object {$objectClass} - must be mapped or persisted before");
+ }
+ $meta = $this->manager->getClassMetadata(get_class($object));
+
+ $identifier = array();
+ foreach ((array)$meta->identifier as $field) {
+ $id = $meta->getReflectionProperty($field)->getValue($object);
+ if (!$id) {
+ throw new \LogicException("Object: {$objectClass} - must be flushed first in order to have generated id");
+ }
+ $identifier[$field] = $id;
+ }
+ if (!is_array($meta->identifier)) {
+ $identifier = reset($identifier);
+ }
+ $this->references[$name] = array(
+ 'class' => $meta->name,
+ 'identifier' => $identifier
+ );
+ }
+
+ /**
+ * 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
+ * @return object
+ */
+ public function getReference($name)
+ {
+ $object = null;
+ if (isset($this->references[$name])) {
+ $object = $this->manager->getReference(
+ $this->references[$name]['class'],
+ $this->references[$name]['identifier']
+ );
+ }
+ return $object;
+ }
+
+ /**
+ * Get all stored references
+ *
+ * @return array
+ */
+ public function getReferences()
+ {
+ return $this->references;
+ }
+}
View
35 lib/Doctrine/Common/DataFixtures/SharedFixtureInterface.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\DataFixtures;
+
+use Doctrine\Common\DataFixtures\ReferenceRepository;
+
+/**
+ * Shared Fixture interface needs to be implemented
+ * by fixtures, which needs some references to be shared
+ * among other fixture classes in order to maintain
+ * relation mapping
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ */
+interface SharedFixtureInterface extends FixtureInterface
+{
+ public function setReferenceRepository(ReferenceRepository $referenceRepository);
+}

0 comments on commit 18dbe2a

Please sign in to comment.