Completed
Push — master ( 862da3...24dc02 )
by Julián
02:20
created

EntityManagerBuilder::setMetadataDriver()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
rs 8.439
cc 5
eloc 15
nc 5
nop 2
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\Proxy\AbstractProxyFactory;
13
use Doctrine\DBAL\Connection;
14
use Doctrine\DBAL\Types\Type;
15
use Doctrine\ORM\Configuration;
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
18
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
19
use Doctrine\ORM\Mapping\NamingStrategy;
20
use Doctrine\ORM\Mapping\QuoteStrategy;
21
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
22
use Doctrine\ORM\Mapping\Driver\XmlDriver;
23
use Doctrine\ORM\Mapping\Driver\YamlDriver;
24
25
/**
26
 * Doctrine Entity Manager service builder
27
 */
28
class EntityManagerBuilder
29
{
30
    use ObjectManagerTrait;
31
32
    /**
33
     * Default configuration options.
34
     *
35
     * @var array
36
     */
37
    protected static $defaultOptions = [
38
        'connection' => null,
39
        'cache_driver' => null,
40
        'cache_namespace' => null,
41
        'annotation_files' => [],
42
        'annotation_namespaces' => [],
43
        'annotation_autoloaders' => [],
44
        'annotation_paths' => null,
45
        'xml_paths' => null,
46
        'yaml_paths' => null,
47
        'php_paths' => null,
48
        'naming_strategy' => null,
49
        'quote_strategy' => null,
50
        'proxy_path' => null,
51
        'proxies_namespace' => 'DoctrineORMProxy',
52
        'auto_generate_proxies' => AbstractProxyFactory::AUTOGENERATE_NEVER,
53
        'sql_logger' => null,
54
        'event_manager' => null,
55
        'custom_types' => [],
56
        'string_functions' => [],
57
        'numeric_functions' => [],
58
        'datetime_functions' => [],
59
    ];
60
61
    /**
62
     * Create a Doctrine entity manager.
63
     *
64
     * @param array $options
65
     *
66
     * @throws \Doctrine\DBAL\DBALException
67
     * @throws \Doctrine\ORM\ORMException
68
     * @throws \InvalidArgumentException
69
     * @throws \RuntimeException
70
     *
71
     * @return \Doctrine\ORM\EntityManager
72
     */
73
    public static function build(array $options)
74
    {
75
        $options = array_merge(static::$defaultOptions, $options);
76
77
        static::setupAnnotationMetadata($options);
78
79
        $config = static::getConfiguration($options);
80
        static::setMetadataDriver($config, $options);
81
        static::setupNamingStrategy($config, $options);
82
        static::setupQuoteStrategy($config, $options);
83
        static::setupProxy($config, $options);
84
        static::setupSQLLogger($config, $options);
85
        static::setupCustomDQLFunctions($config, $options);
86
87
        $entityManager = EntityManager::create(
88
            $options['connection'],
89
            $config,
90
            $options['event_manager']
91
        );
92
93
        $connection = $entityManager->getConnection();
94
        static::setupCustomDBALTypes($connection, $options);
95
96
        return $entityManager;
97
    }
98
99
    /**
100
     * Create Doctrine ORM bare configuration.
101
     *
102
     * @param array $options
103
     *
104
     * @throws \InvalidArgumentException
105
     *
106
     * @return \Doctrine\ORM\Configuration
107
     */
108
    protected static function getConfiguration(array $options)
109
    {
110
        $cacheDriver = static::getCacheDriver(
111
            $options['cache_driver'],
112
            $options['cache_namespace'] ?: 'orm_dc2_' . sha1($options['proxy_path'] ?: sys_get_temp_dir()) . '_'
113
        );
114
115
        $config = new Configuration();
116
        $config->setMetadataCacheImpl($cacheDriver);
117
        $config->setQueryCacheImpl($cacheDriver);
118
        $config->setResultCacheImpl($cacheDriver);
119
120
        return $config;
121
    }
122
123
    /**
124
     * Create Doctrine configuration.
125
     *
126
     * @param \Doctrine\ORM\Configuration $config
127
     * @param array                       $options
128
     *
129
     * @throws \RuntimeException
130
     */
131
    protected static function setMetadataDriver(Configuration $config, array $options)
132
    {
133
        if ($options['annotation_paths']) {
134
            $config->setMetadataDriverImpl(
135
                $config->newDefaultAnnotationDriver((array) $options['annotation_paths'], false)
136
            );
137
138
            return;
139
        }
140
141
        if ($options['xml_paths']) {
142
            $config->setMetadataDriverImpl(new XmlDriver((array) $options['xml_paths']));
143
144
            return;
145
        }
146
147
        if ($options['yaml_paths']) {
148
            $config->setMetadataDriverImpl(new YamlDriver((array) $options['yaml_paths']));
149
150
            return;
151
        }
152
153
        if ($options['php_paths']) {
154
            $config->setMetadataDriverImpl(new StaticPHPDriver((array) $options['php_paths']));
155
156
            return;
157
        }
158
159
        throw new \RuntimeException('No Metadata Driver defined');
160
    }
161
162
    /**
163
     * Setup naming strategy.
164
     *
165
     * @param \Doctrine\ORM\Configuration $config
166
     * @param array                       $options
167
     *
168
     * @throws \InvalidArgumentException
169
     */
170
    protected static function setupNamingStrategy(Configuration $config, array $options)
171
    {
172
        $namingStrategy = $options['naming_strategy'] ?: new UnderscoreNamingStrategy(CASE_LOWER);
173
        if (!$namingStrategy instanceof NamingStrategy) {
174
            throw new \InvalidArgumentException('Naming strategy provided is not valid');
175
        }
176
177
        $config->setNamingStrategy($namingStrategy);
178
    }
179
180
    /**
181
     * Setup quote strategy.
182
     *
183
     * @param \Doctrine\ORM\Configuration $config
184
     * @param array                       $options
185
     *
186
     * @throws \InvalidArgumentException
187
     */
188
    protected static function setupQuoteStrategy(Configuration $config, array $options)
189
    {
190
        $quoteStrategy = $options['quote_strategy'] ?: new DefaultQuoteStrategy();
191
        if (!$quoteStrategy instanceof QuoteStrategy) {
192
            throw new \InvalidArgumentException('Quote strategy provided is not valid');
193
        }
194
195
        $config->setQuoteStrategy($quoteStrategy);
196
    }
197
198
    /**
199
     * Setup SQL logger.
200
     *
201
     * @param \Doctrine\ORM\Configuration $config
202
     * @param array                       $options
203
     */
204
    protected static function setupSQLLogger(Configuration $config, array $options)
205
    {
206
        if ($options['sql_logger']) {
207
            $config->setSQLLogger($options['sql_logger']);
208
        }
209
    }
210
211
    /**
212
     * Setup custom DQL functions.
213
     *
214
     * @param \Doctrine\ORM\Configuration $config
215
     * @param array                       $options
216
     */
217
    protected static function setupCustomDQLFunctions(Configuration $config, array $options)
218
    {
219
        $config->setCustomStringFunctions($options['string_functions']);
220
221
        $config->setCustomNumericFunctions($options['numeric_functions']);
222
223
        $config->setCustomDatetimeFunctions($options['datetime_functions']);
224
    }
225
226
    /**
227
     * Setup Custom DBAL types.
228
     *
229
     * @param \Doctrine\DBAL\Connection $connection
230
     * @param array                     $options
231
     *
232
     * @throws \Doctrine\DBAL\DBALException
233
     * @throws \RuntimeException
234
     */
235
    protected static function setupCustomDBALTypes(Connection $connection, array $options)
236
    {
237
        $platform = $connection->getDatabasePlatform();
238
239
        foreach ($options['custom_types'] as $type => $class) {
240
            if (Type::hasType($type)) {
241
                throw new \RuntimeException(sprintf('Type "%s" is already registered', $type));
242
            }
243
244
            Type::addType($type, $class);
245
            $platform->registerDoctrineTypeMapping($type, $type);
246
        }
247
    }
248
}
249