Completed
Push — master ( ec1826...17149c )
by Taosikai
15:14
created

DoctrineOrmServiceProvider   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Importance

Changes 0
Metric Value
wmc 22
lcom 0
cbo 4
dl 0
loc 207
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A provide() 0 10 2
F register() 0 177 19
A getOrmDefaults() 0 15 1
1
<?php
2
3
/*
4
 * This file is part of the jade/jade package.
5
 *
6
 * (c) Slince <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Jade\Provider;
13
14
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
15
use Doctrine\ORM\Configuration;
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
18
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
19
use Doctrine\ORM\Mapping\Driver\XmlDriver;
20
use Doctrine\ORM\Mapping\Driver\YamlDriver;
21
use Doctrine\ORM\Tools\Console\ConsoleRunner;
22
use Doctrine\ORM\Tools\ResolveTargetEntityListener;
23
use Jade\CommandProviderInterface;
24
use Jade\Console\Application;
25
use Jade\Container;
26
use Jade\ContainerInterface;
27
use Jade\ServiceProviderInterface;
28
29
/**
30
 * Doctrine ORM Pimple Service Provider.
31
 *
32
 * @author Beau Simensen <[email protected]>
33
 */
34
class DoctrineOrmServiceProvider implements ServiceProviderInterface, CommandProviderInterface
35
{
36
    public function provide(Application $app, ContainerInterface $container)
37
    {
38
        ConsoleRunner::addCommands($app);
39
        $helperSet = $app->getHelperSet();
40
        $doctrineHelperSet = ConsoleRunner::createHelperSet($container['orm']);
41
        foreach ($doctrineHelperSet as $alias =>$helper) {
42
            $helperSet->set($helper, $alias);
43
        }
44
        $app->setHelperSet($helperSet);
45
    }
46
47
    public function register(ContainerInterface $container)
48
    {
49
        if (!isset($container['dbs'])) {
50
            throw new \LogicException(
51
                'You must register the DoctrineServiceProvider to use the DoctrineOrmServiceProvider.'
52
            );
53
        }
54
55
        if (!isset($container['caches'])) {
56
            throw new \LogicException(
57
                'You must register the DoctrineCacheServiceProvider to use the DoctrineOrmServiceProvider.'
58
            );
59
        }
60
61
        // 初始值
62
        $container->add($this->getOrmDefaults());
63
64
        $container['ems.options.initializer'] = $container->protect(function () use ($container) {
65
            static $initialized = false;
66
67
            if ($initialized) {
68
                return;
69
            }
70
71
            $initialized = true;
72
73
            if (!isset($container['ems.options'])) {
74
                $container['ems.options'] = [
75
                    'default' => $container['orm.options'] ?? [],
76
                ];
77
            }
78
79
            $container['ems.options'] = array_map(function ($options) use ($container) {
80
                return array_replace($container['orm.default_options'], $options);
81
            }, $container['ems.options']);
82
83
            if (!isset($container['ems.default'])) {
84
                $container['ems.default'] = array_keys(
85
                    array_slice($container['ems.options'], 0, 1)
86
                )[0];
87
            }
88
        });
89
90
        $container['ems'] = function (Container $container) {
91
            $container['ems.options.initializer']();
92
93
            $ems = new Container();
94
            foreach ($container['ems.options'] as $name => $options) {
95
                $config = $container['ems.default'] === $name
96
                    ? $container['orm.config']
97
                    : $container['ems.config'][$name];
98
99
                $connection = $container['dbs'][$options['connection']];
100
                $manager = $container['dbs.event_manager'][$options['connection']];
101
102
                if ($targetEntities = $options['resolve_target_entities'] ?? []) {
103
                    $manager->addEventSubscriber(
104
                        $container['orm.resolve_target_entity']($targetEntities)
105
                    );
106
                }
107
108
                $ems[$name] = function () use ($connection, $config, $manager) {
109
                    return EntityManager::create($connection, $config, $manager);
110
                };
111
            }
112
113
            return $ems;
114
        };
115
116
        $container['ems.config'] = function (Container $container) {
117
            $container['ems.options.initializer']();
118
119
            $configs = new Container();
120
            foreach ($container['ems.options'] as $name => $options) {
121
                $config = new Configuration();
122
                $config->setProxyDir($container['orm.proxy_dir']);
123
                $config->setProxyNamespace($container['orm.proxy_namespace']);
124
                $config->setAutoGenerateProxyClasses($container['orm.auto_generate_proxy_classes']);
125
                $config->setCustomStringFunctions($container['orm.custom_functions_string']);
126
                $config->setCustomNumericFunctions($container['orm.custom_functions_numeric']);
127
                $config->setCustomDatetimeFunctions($container['orm.custom_functions_datetime']);
128
                $config->setMetadataCacheImpl($container['orm.cache.factory']('metadata', $options));
129
                $config->setQueryCacheImpl($container['orm.cache.factory']('query', $options));
130
                $config->setResultCacheImpl($container['orm.cache.factory']('result', $options));
131
                $config->setMetadataDriverImpl($container['orm.mapping.chain']($config, $options['mappings']));
132
133
                $configs[$name] = $config;
134
            }
135
136
            return $configs;
137
        };
138
139
        $container['orm.cache.factory'] = $container->protect(function ($type, $options) use ($container) {
140
            $type = $type . '_cache_driver';
141
142
            $options[$type] = $options[$type] ?? 'array';
143
144
            if (!is_array($options[$type])) {
145
                $options[$type] = [
146
                    'driver' => $options[$type],
147
                ];
148
            }
149
150
            $driver = $options[$type]['driver'];
151
            $namespace = $options[$type]['namespace'] ?? null;
152
153
            $cache = $container['cache_factory']($driver, $options);
154
            $cache->setNamespace($namespace);
155
156
            return $cache;
157
        });
158
159
        $container['orm.mapping.chain'] = $container->protect(function (Configuration $config, array $mappings) {
160
            $chain = new MappingDriverChain();
161
162
            foreach ($mappings as $mapping) {
163
                if (!is_array($mapping)) {
164
                    throw new \InvalidArgumentException();
165
                }
166
167
                $path = $mapping['path'];
168
                $namespace = $mapping['namespace'];
169
170
                switch ($mapping['type']) {
171
                    case 'annotation':
172
                        $annotationDriver = $config->newDefaultAnnotationDriver(
173
                            $path,
174
                            $mapping['use_simple_annotation_reader'] ?? true
175
                        );
176
                        $chain->addDriver($annotationDriver, $namespace);
177
                        break;
178
                    case 'yml':
179
                        $chain->addDriver(new YamlDriver($path), $namespace);
180
                        break;
181
                    case 'simple_yml':
182
                        $driver = new SimplifiedYamlDriver([$path => $namespace]);
183
                        $chain->addDriver($driver, $namespace);
184
                        break;
185
                    case 'xml':
186
                        $chain->addDriver(new XmlDriver($path), $namespace);
187
                        break;
188
                    case 'simple_xml':
189
                        $driver = new SimplifiedXmlDriver([$path => $namespace]);
190
                        $chain->addDriver($driver, $namespace);
191
                        break;
192
                    default:
193
                        throw new \InvalidArgumentException();
194
                        break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
195
                }
196
            }
197
198
            return $chain;
199
        });
200
201
        $container['orm.resolve_target_entity'] = $container->protect(function (array $targetEntities) {
202
            $rtel = new ResolveTargetEntityListener();
203
204
            foreach ($targetEntities as $originalEntity => $newEntity) {
205
                $rtel->addResolveTargetEntity($originalEntity, $newEntity, []);
206
            }
207
208
            return $rtel;
209
        });
210
211
        // shortcuts for the "first" ORM
212
        $container['orm'] = function (Container $container) {
213
            $ems = $container['ems'];
214
215
            return $ems[$container['ems.default']];
216
        };
217
218
        $container['orm.config'] = function (Container $container) {
219
            $ems = $container['ems.config'];
220
221
            return $ems[$container['ems.default']];
222
        };
223
    }
224
225
    protected function getOrmDefaults()
226
    {
227
        return [
228
            'orm.proxy_dir' => null,
229
            'orm.proxy_namespace' => 'Proxy',
230
            'orm.auto_generate_proxy_classes' => true,
231
            'orm.custom_functions_string' => [],
232
            'orm.custom_functions_numeric' => [],
233
            'orm.custom_functions_datetime' => [],
234
            'orm.default_options' => [
235
                'connection' => 'default',
236
                'mappings' => [],
237
            ]
238
        ];
239
    }
240
}