Doctrine\Common\DataFixtures\Loader::orderFixturesByDependencies PHP Method

orderFixturesByDependencies() private method

Orders fixtures by dependencies
private orderFixturesByDependencies ( ) : void
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);
    }