Test Failed
Push — v0.2 ( beadd5...4e23eb )
by Freddie
02:19
created

DoctrineOrmFactory::createConfig()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 4
nop 2
dl 0
loc 27
ccs 14
cts 16
cp 0.875
crap 3.0175
rs 8.8571
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A DoctrineOrmFactory::buildConfig() 0 11 1
1
<?php declare(strict_types=1);
2
3
namespace Simplex\Quickstart\Shared\Factory;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
6
use Doctrine\Common\Cache\ArrayCache;
7
use Doctrine\Common\Cache\FilesystemCache;
8
use Doctrine\Common\EventManager;
9
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
10
use Doctrine\DBAL\Types\Type;
11
use Doctrine\ORM\Configuration;
12
use Doctrine\ORM\EntityManager;
13
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
14
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
15
use Gedmo\DoctrineExtensions as GedmoExtensions;
16
use Gedmo\Timestampable\TimestampableListener;
17
use Ramsey\Uuid\Doctrine\UuidType;
18
use Simplex\Quickstart\Shared\Doctrine\Type\DateTimeMicroType;
19
use Symfony\Component\Finder\Finder;
20
21
class DoctrineOrmFactory
22
{
23
    const DOCTRINE_CACHE_DIRECTORY = 'doctrine';
24
25
    const PROXY_DIRECTORY = self::DOCTRINE_CACHE_DIRECTORY . DIRECTORY_SEPARATOR . 'proxy';
26
27
    const PROXY_NAMESPACE = 'DoctrineProxies';
28
29
    const MODULES_DIRECTORY_PATH = __DIR__ . '/../../Module';
30
31
    const ENTITY_DIRECTORY_NAME = 'Model';
32
33
    /**
34
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
35
     */
36 1
    public function create(
37
        string $host,
38
        string $port,
39
        string $name,
40
        string $user,
41
        string $pass,
42
        string $cacheDir,
43
        bool $enableCache): EntityManager
44
    {
45
        $connectionOptions = [
46 1
            'driver' => 'pdo_mysql',
47 1
            'host' => $host,
48 1
            'port' => $port,
49 1
            'dbname' => $name,
50 1
            'user' => $user,
51 1
            'password' => $pass,
52
        ];
53
54 1
        $annotationReader = new AnnotationReader();
55
56 1
        $config = $this->buildConfig($cacheDir, $enableCache, $annotationReader);
57
58 1
        $this->addCustomTypes();
59
60 1
        $entityManager = $this->buildEntityManager($annotationReader, $connectionOptions, $config);
61
62 1
        return $entityManager;
63
    }
64
65 1
    private function buildConfig(string $cacheDir, bool $enableCache, AnnotationReader $annotationReader): Configuration
66
    {
67 1
        $config = new Configuration;
68
69 1
        $this->configureMetadataDrivers($annotationReader, $config);
70
71 1
        $this->configureCache($cacheDir, $enableCache, $config);
72
73 1
        $this->configureNamingStrategy($config);
74
75 1
        return $config;
76
    }
77
78 1
    private function configureMetadataDrivers(AnnotationReader $annotationReader, Configuration $config): void
79
    {
80 1
        $driverChain = new MappingDriverChain();
81
82 1
        $defaultDriver = new AnnotationDriver($annotationReader, $this->getEntityDirPaths());
83
84 1
        $driverChain->setDefaultDriver($defaultDriver);
85 1
        $config->setMetadataDriverImpl($driverChain); // was driver imp
86
87 1
        GedmoExtensions::registerAbstractMappingIntoDriverChainORM(
88 1
            $driverChain,
89 1
            $annotationReader
90
        );
91 1
    }
92
93 1
    private function getEntityDirPaths(): array
94
    {
95 1
        $finder = new Finder();
96 1
        $finder->directories()->depth(0)->in(self::MODULES_DIRECTORY_PATH);
97
98 1
        $paths = [];
99 1
        foreach ($finder as $dir) {
100 1
            $modelDir = $dir->getPathname() . DIRECTORY_SEPARATOR . self::ENTITY_DIRECTORY_NAME;
101 1
            if (is_readable($modelDir)) {
102 1
                $paths[] = $modelDir;
103
            }
104
        }
105
106 1
        return $paths;
107
    }
108
109
    /**
110
     * @SuppressWarnings(PHPMD.ElseExpression)
111
     */
112 1
    private function configureCache(string $cacheDir, bool $enableCache, Configuration $config): void
113
    {
114 1
        $cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR);
115
116 1
        if (!$enableCache) {
117 1
            $cache = new ArrayCache();
118
        } else {
119
            $cache = new FilesystemCache($cacheDir . DIRECTORY_SEPARATOR . self::DOCTRINE_CACHE_DIRECTORY);
120
        }
121
122 1
        $config->setMetadataCacheImpl($cache);
123 1
        $config->setQueryCacheImpl($cache);
124 1
        $config->setProxyDir($cacheDir . DIRECTORY_SEPARATOR . self::PROXY_DIRECTORY);
125 1
        $config->setProxyNamespace(self::PROXY_NAMESPACE);
126
127 1
        if ($enableCache) {
128
            $config->setAutoGenerateProxyClasses(true);
129
        } else {
130 1
            $config->setAutoGenerateProxyClasses(false);
131
        }
132 1
    }
133
134 1
    private function configureNamingStrategy(Configuration $config): void
135
    {
136 1
        $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
137 1
        $config->setNamingStrategy($namingStrategy);
138 1
    }
139
140 1
    private function addCustomTypes(): void
141
    {
142 1
        Type::addType(UuidType::NAME, UuidType::class);
143 1
        Type::addType(DateTimeMicroType::NAME, DateTimeMicroType::class);
144 1
    }
145
146 1
    private function buildEntityManager(
147
        AnnotationReader $annotationReader,
148
        array $connectionOptions,
149
        Configuration$config): EntityManager
150
    {
151 1
        $eventManager = $this->buildEventManager($annotationReader);
152
153 1
        $entityManager = EntityManager::create($connectionOptions, $config, $eventManager);
154
155 1
        return $entityManager;
156
    }
157
158 1
    private function buildEventManager(AnnotationReader $annotationReader): EventManager
159
    {
160 1
        $eventManager = new EventManager();
161
162 1
        $this->addEventListeners($annotationReader, $eventManager);
163
164 1
        return $eventManager;
165
    }
166
167 1
    private function addEventListeners(AnnotationReader $annotationReader, EventManager $eventManager): void
168
    {
169 1
        $timestampableListener = new TimestampableListener();
170 1
        $timestampableListener->setAnnotationReader($annotationReader);
171
172 1
        $eventManager->addEventSubscriber($timestampableListener);
173 1
    }
174
}
175