Completed
Pull Request — master (#271)
by Alexis
06:31
created

FixturesLoader::getExecutorClass()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 3
eloc 4
nc 4
nop 1
crap 3
1
<?php
2
3
/*
4
 * This file is part of the Liip/FunctionalTestBundle
5
 *
6
 * (c) Lukas Kahwe Smith <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Liip\FunctionalTestBundle\Utils;
13
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
16
use Doctrine\DBAL\Connection;
17
use Nelmio\Alice\Fixtures;
18
use Symfony\Bundle\DoctrineFixturesBundle\Common\DataFixtures\Loader;
19
use Doctrine\Common\Persistence\ObjectManager;
20
use Doctrine\Common\DataFixtures\ProxyReferenceRepository;
21
22
class FixturesLoader
23
{
24
    /**
25
     * @param string $type
26
     *
27
     * @return string
28
     */
29 32
    public static function getExecutorClass($type)
30
    {
31 32
        return 'PHPCR' === $type && class_exists('Doctrine\Bundle\PHPCRBundle\DataFixtures\PHPCRExecutor')
32 32
            ? 'Doctrine\Bundle\PHPCRBundle\DataFixtures\PHPCRExecutor'
33 32
            : 'Doctrine\\Common\\DataFixtures\\Executor\\'.$type.'Executor';
34
    }
35
36
    /**
37
     * Get file path of the SQLite database.
38
     *
39
     * @param Connection $connection
40
     *
41
     * @return string $name
42
     */
43 31
    public static function getNameParameter(Connection $connection)
44
    {
45 27
        $params = $connection->getParams();
46
47 31
        if (isset($params['master'])) {
48
            $params = $params['master'];
49
        }
50
51 27
        $name = isset($params['path']) ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false);
52
53 27
        if (!$name) {
54
            throw new \InvalidArgumentException("Connection does not contain a 'path' or 'dbname' parameter and cannot be dropped.");
55
        }
56
57 27
        return $name;
58
    }
59
60
    /**
61
     * This function finds the time when the data blocks of a class definition
62
     * file were being written to, that is, the time when the content of the
63
     * file was changed.
64
     *
65
     * @param string $class The fully qualified class name of the fixture class to
66
     *                      check modification date on.
67
     *
68
     * @return \DateTime|null
69
     */
70 3
    protected static function getFixtureLastModified($class)
71
    {
72 3
        $lastModifiedDateTime = null;
73
74 3
        $reflClass = new \ReflectionClass($class);
75 3
        $classFileName = $reflClass->getFileName();
76
77 3
        if (file_exists($classFileName)) {
78 3
            $lastModifiedDateTime = new \DateTime();
79 3
            $lastModifiedDateTime->setTimestamp(filemtime($classFileName));
80 3
        }
81
82 3
        return $lastModifiedDateTime;
83
    }
84
85
    /**
86
     * Determine if the Fixtures that define a database backup have been
87
     * modified since the backup was made.
88
     *
89
     * @param array  $classNames The fixture classnames to check
90
     * @param string $backup     The fixture backup SQLite database file path
91
     *
92
     * @return bool TRUE if the backup was made since the modifications to the
93
     *              fixtures; FALSE otherwise
94
     */
95 7
    public static function isBackupUpToDate(array $classNames, $backup, $container)
96
    {
97 7
        $backupLastModifiedDateTime = new \DateTime();
98 7
        $backupLastModifiedDateTime->setTimestamp(filemtime($backup));
99
100
        /** @var \Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader $loader */
101 7
        $loader = self::getFixtureLoader($container, $classNames);
102
103
        // Use loader in order to fetch all the dependencies fixtures.
104 7
        foreach ($loader->getFixtures() as $className) {
105 3
            $fixtureLastModifiedDateTime = self::getFixtureLastModified($className);
106 3
            if ($backupLastModifiedDateTime < $fixtureLastModifiedDateTime) {
107 1
                return false;
108
            }
109 7
        }
110
111 7
        return true;
112
    }
113
114
    /**
115
     * Locate fixture files.
116
     *
117
     * @param array $paths
118
     *
119
     * @return array $files
120
     */
121 6
    public static function locateResources($paths, $container)
122
    {
123 6
        $files = array();
124
125 6
        $kernel = $container->get('kernel');
126
127 6
        foreach ($paths as $path) {
128 6
            if ($path[0] !== '@' && file_exists($path) === true) {
129 1
                $files[] = $path;
130 1
                continue;
131
            }
132
133 5
            $files[] = $kernel->locateResource($path);
134 6
        }
135
136 6
        return $files;
137
    }
138
139
    /**
140
     * Retrieve Doctrine DataFixtures loader.
141
     *
142
     * @param ContainerInterface $container
143
     * @param array              $classNames
144
     *
145
     * @return Loader
146
     */
147 32
    public static function getFixtureLoader(ContainerInterface $container, array $classNames)
148
    {
149 32
        $loaderClass = class_exists('Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader')
150 32
            ? 'Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader'
151 32
            : (class_exists('Doctrine\Bundle\FixturesBundle\Common\DataFixtures\Loader')
152
                // This class is not available during tests.
153
                // @codeCoverageIgnoreStart
154
                ? 'Doctrine\Bundle\FixturesBundle\Common\DataFixtures\Loader'
155
                // @codeCoverageIgnoreEnd
156 32
                : 'Symfony\Bundle\DoctrineFixturesBundle\Common\DataFixtures\Loader');
157
158 32
        $loader = new $loaderClass($container);
159
160 32
        foreach ($classNames as $className) {
161 10
            self::loadFixtureClass($loader, $className);
162 32
        }
163
164 32
        return $loader;
165
    }
166
167
    /**
168
     * Purge database.
169
     *
170
     * @param ObjectManager            $om
171
     * @param string                   $type
172
     * @param int                      $purgeMode
173
     * @param string                   $executorClass
174
     * @param ProxyReferenceRepository $referenceRepository
175
     *
176
     * @return \Doctrine\Common\DataFixtures\Executor\ORMExecutor
177
     */
178 5
    public static function purgeDatabase(ObjectManager $om, $type, $purgeMode,
179
         $executorClass,
180
         ProxyReferenceRepository $referenceRepository,
181
         $container)
182
    {
183 5
        $purgerClass = 'Doctrine\\Common\\DataFixtures\\Purger\\'.$type.'Purger';
184 5
        if ('PHPCR' === $type) {
185 1
            $purger = new $purgerClass($om);
186 1
            $initManager = $container->has('doctrine_phpcr.initializer_manager')
187 1
                ? $container->get('doctrine_phpcr.initializer_manager')
188 1
                : null;
189
190 1
            $executor = new $executorClass($om, $purger, $initManager);
191 1
        } else {
192 4
            $purger = new $purgerClass();
193 4
            if (null !== $purgeMode) {
194 1
                $purger->setPurgeMode($purgeMode);
195 1
            }
196
197 4
            $executor = new $executorClass($om, $purger);
198
        }
199
200 5
        $executor->setReferenceRepository($referenceRepository);
201 5
        $executor->purge();
202
203 5
        return $executor;
204
    }
205
206
    /**
207
     * Load a data fixture class.
208
     *
209
     * @param Loader $loader
210
     * @param string $className
211
     */
212 10
    protected static function loadFixtureClass($loader, $className)
213
    {
214 10
        $fixture = new $className();
215
216 10
        if ($loader->hasFixture($fixture)) {
217 2
            unset($fixture);
218
219 2
            return;
220
        }
221
222 10
        $loader->addFixture($fixture);
223
224 10
        if ($fixture instanceof DependentFixtureInterface) {
225 2
            foreach ($fixture->getDependencies() as $dependency) {
226 2
                self::loadFixtureClass($loader, $dependency);
227 2
            }
228 2
        }
229 10
    }
230
}
231