Completed
Push — master ( 8bbd01...52c1f9 )
by Julián
02:26
created

EntityManagerBuilder::getMetadataDriver()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
rs 8.8571
cc 5
eloc 10
nc 5
nop 1
1
<?php
2
/**
3
 * Slim3 Doctrine integration (https://github.com/juliangut/slim-doctrine)
4
 *
5
 * @link https://github.com/juliangut/slim-doctrine for the canonical source repository
6
 *
7
 * @license https://raw.githubusercontent.com/juliangut/slim-doctrine/master/LICENSE
8
 */
9
10
namespace Jgut\Slim\Doctrine;
11
12
use Doctrine\Common\Annotations\AnnotationReader;
13
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
14
use Doctrine\Common\Proxy\AbstractProxyFactory;
15
use Doctrine\DBAL\Connection;
16
use Doctrine\DBAL\Types\Type;
17
use Doctrine\ORM\Configuration;
18
use Doctrine\ORM\EntityManager;
19
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
20
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
21
use Doctrine\ORM\Mapping\NamingStrategy;
22
use Doctrine\ORM\Mapping\QuoteStrategy;
23
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
24
use Doctrine\ORM\Mapping\Driver\XmlDriver;
25
use Doctrine\ORM\Mapping\Driver\YamlDriver;
26
27
/**
28
 * Doctrine Entity Manager service builder
29
 */
30
class EntityManagerBuilder
31
{
32
    use ObjectManagerTrait;
33
34
    /**
35
     * Default configuration options.
36
     *
37
     * @var array
38
     */
39
    protected static $defaultOptions = [
40
        'connection' => null,
41
        'cache_driver' => null,
42
        'cache_namespace' => null,
43
        'annotation_files' => [],
44
        'annotation_namespaces' => [],
45
        'annotation_autoloaders' => [],
46
        'annotation_paths' => null,
47
        'xml_paths' => null,
48
        'yaml_paths' => null,
49
        'php_paths' => null,
50
        'naming_strategy' => null,
51
        'quote_strategy' => null,
52
        'proxy_path' => null,
53
        'proxies_namespace' => 'DoctrineORMProxy',
54
        'auto_generate_proxies' => AbstractProxyFactory::AUTOGENERATE_NEVER,
55
        'sql_logger' => null,
56
        'event_manager' => null,
57
        'custom_types' => [],
58
        'string_functions' => [],
59
        'numeric_functions' => [],
60
        'datetime_functions' => [],
61
    ];
62
63
    /**
64
     * Create a Doctrine entity manager.
65
     *
66
     * @param array $options
67
     *
68
     * @throws \Doctrine\DBAL\DBALException
69
     * @throws \Doctrine\ORM\ORMException
70
     * @throws \InvalidArgumentException
71
     * @throws \RuntimeException
72
     *
73
     * @return \Doctrine\ORM\EntityManager
74
     */
75
    public static function build(array $options)
76
    {
77
        $options = array_merge(static::$defaultOptions, $options);
78
79
        static::setupAnnotationMetadata($options);
80
81
        $config = static::getConfiguration($options);
82
        static::setupMetadataDriver($config, $options);
83
        static::setupNamingStrategy($config, $options);
84
        static::setupQuoteStrategy($config, $options);
85
        static::setupProxy($config, $options);
86
        static::setupSQLLogger($config, $options);
87
        static::setupCustomDQLFunctions($config, $options);
88
89
        $entityManager = EntityManager::create(
90
            $options['connection'],
91
            $config,
92
            $options['event_manager']
93
        );
94
95
        $connection = $entityManager->getConnection();
96
        static::setupCustomDBALTypes($connection, $options);
97
98
        return $entityManager;
99
    }
100
101
    /**
102
     * Create Doctrine ORM bare configuration.
103
     *
104
     * @param array $options
105
     *
106
     * @throws \InvalidArgumentException
107
     *
108
     * @return \Doctrine\ORM\Configuration
109
     */
110
    protected static function getConfiguration(array $options)
111
    {
112
        $cacheDriver = static::getCacheDriver(
113
            $options['cache_driver'],
114
            $options['cache_namespace'] ?: 'orm_dc2_' . sha1($options['proxy_path'] ?: sys_get_temp_dir()) . '_'
115
        );
116
117
        $config = new Configuration();
118
        $config->setMetadataCacheImpl($cacheDriver);
119
        $config->setQueryCacheImpl($cacheDriver);
120
        $config->setResultCacheImpl($cacheDriver);
121
122
        return $config;
123
    }
124
125
    /**
126
     * @param array $options
127
     *
128
     * @throws \RuntimeException
129
     *
130
     * @return \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use AnnotationDriver|XmlDriv...lDriver|StaticPHPDriver.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
131
     */
132
    protected static function getMetadataDriver(array $options)
133
    {
134
        if ($options['annotation_paths']) {
135
            return new AnnotationDriver(new AnnotationReader, (array) $options['annotation_paths']);
136
        }
137
138
        if ($options['xml_paths']) {
139
            return new XmlDriver((array) $options['xml_paths'], '.xml');
140
        }
141
142
        if ($options['yaml_paths']) {
143
            return new YamlDriver((array) $options['yaml_paths'], '.yml');
144
        }
145
146
        if ($options['php_paths']) {
147
            return new StaticPHPDriver((array) $options['php_paths']);
148
        }
149
150
        throw new \RuntimeException('No Metadata paths defined');
151
    }
152
153
    /**
154
     * Setup naming strategy.
155
     *
156
     * @param \Doctrine\ORM\Configuration $config
157
     * @param array                       $options
158
     *
159
     * @throws \InvalidArgumentException
160
     */
161
    protected static function setupNamingStrategy(Configuration $config, array $options)
162
    {
163
        $namingStrategy = $options['naming_strategy'] ?: new UnderscoreNamingStrategy(CASE_LOWER);
164
        if (!$namingStrategy instanceof NamingStrategy) {
165
            throw new \InvalidArgumentException('Naming strategy provided is not valid');
166
        }
167
168
        $config->setNamingStrategy($namingStrategy);
169
    }
170
171
    /**
172
     * Setup quote strategy.
173
     *
174
     * @param \Doctrine\ORM\Configuration $config
175
     * @param array                       $options
176
     *
177
     * @throws \InvalidArgumentException
178
     */
179
    protected static function setupQuoteStrategy(Configuration $config, array $options)
180
    {
181
        $quoteStrategy = $options['quote_strategy'] ?: new DefaultQuoteStrategy();
182
        if (!$quoteStrategy instanceof QuoteStrategy) {
183
            throw new \InvalidArgumentException('Quote strategy provided is not valid');
184
        }
185
186
        $config->setQuoteStrategy($quoteStrategy);
187
    }
188
189
    /**
190
     * Setup SQL logger.
191
     *
192
     * @param \Doctrine\ORM\Configuration $config
193
     * @param array                       $options
194
     */
195
    protected static function setupSQLLogger(Configuration $config, array $options)
196
    {
197
        if ($options['sql_logger']) {
198
            $config->setSQLLogger($options['sql_logger']);
199
        }
200
    }
201
202
    /**
203
     * Setup custom DQL functions.
204
     *
205
     * @param \Doctrine\ORM\Configuration $config
206
     * @param array                       $options
207
     */
208
    protected static function setupCustomDQLFunctions(Configuration $config, array $options)
209
    {
210
        $config->setCustomStringFunctions($options['string_functions']);
211
212
        $config->setCustomNumericFunctions($options['numeric_functions']);
213
214
        $config->setCustomDatetimeFunctions($options['datetime_functions']);
215
    }
216
217
    /**
218
     * Setup Custom DBAL types.
219
     *
220
     * @param \Doctrine\DBAL\Connection $connection
221
     * @param array                     $options
222
     *
223
     * @throws \Doctrine\DBAL\DBALException
224
     * @throws \RuntimeException
225
     */
226
    protected static function setupCustomDBALTypes(Connection $connection, array $options)
227
    {
228
        $platform = $connection->getDatabasePlatform();
229
230
        foreach ($options['custom_types'] as $type => $class) {
231
            if (Type::hasType($type)) {
232
                throw new \RuntimeException(sprintf('Type "%s" is already registered', $type));
233
            }
234
235
            Type::addType($type, $class);
236
            $platform->registerDoctrineTypeMapping($type, $type);
237
        }
238
    }
239
}
240