Completed
Push — master ( 016ff4...fb2978 )
by Julián
07:54
created

DocumentManagerBuilder::getCacheDriver()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 25
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 25
rs 8.439
cc 6
eloc 20
nc 6
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 InvalidArgumentException;
13
use Doctrine\Common\Annotations\AnnotationRegistry;
14
use Doctrine\Common\Cache\Cache;
15
use Doctrine\Common\Proxy\AbstractProxyFactory;
16
use Doctrine\MongoDB\Connection;
17
use Doctrine\ODM\MongoDB\Configuration;
18
use Doctrine\ODM\MongoDB\DocumentManager;
19
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
20
use Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver;
21
use Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver;
22
23
/**
24
 * Doctrine Document Manager service builder.
25
 */
26
class DocumentManagerBuilder
27
{
28
    /**
29
     * Default configuration options.
30
     *
31
     * @var array
32
     */
33
    protected static $defaultOptions = [
34
        'connection' => null,
35
        'proxy_path' => null,
36
        'hydrator_path' => null,
37
        'cache_driver' => null,
38
        'annotation_files' => [],
39
        'annotation_namespaces' => [],
40
        'annotation_autoloaders' => [],
41
        'annotation_paths' => null,
42
        'xml_paths' => null,
43
        'yaml_paths' => null,
44
        'proxies_namespace' => null,
45
        'auto_generate_proxies' => AbstractProxyFactory::AUTOGENERATE_NEVER,
46
        'hydrators_namespace' => null,
47
        'logger_callable' => null,
48
    ];
49
50
    /**
51
     * Create a Doctrine entity manager.
52
     *
53
     * @param array $options
54
     *
55
     * @throws \InvalidArgumentException
56
     *
57
     * @return \Doctrine\ORM\EntityManager
0 ignored issues
show
Documentation introduced by
Should the return type not be DocumentManager?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
58
     */
59
    public static function build(array $options)
60
    {
61
        $options = array_merge(static::$defaultOptions, $options);
62
63
        if ($options['cache_driver'] !== null && !$options['cache_driver'] instanceof Cache) {
64
            throw new InvalidArgumentException('Cache Driver provided is not valid');
65
        }
66
67
        static::setupAnnotationMetadata($options);
68
69
        $config = static::createConfiguration($options);
70
        if (!$config instanceof Configuration) {
71
            throw new InvalidArgumentException('No Metadata Driver defined');
72
        }
73
74
        static::setupProxy($config, $options);
75
76
        static::setupHydrator($config, $options);
77
78
        static::setupLogger($config, $options);
79
80
        return DocumentManager::create(self::getConnection($options), $config);
81
    }
82
83
    /**
84
     * Set up annotation metadata.
85
     *
86
     * @param array $options
87
     */
88
    protected static function setupAnnotationMetadata(array $options)
89
    {
90
        AnnotationDriver::registerAnnotationClasses();
91
92
        foreach ($options['annotation_files'] as $file) {
93
            AnnotationRegistry::registerFile($file);
94
        }
95
96
        AnnotationRegistry::registerAutoloadNamespaces($options['annotation_namespaces']);
97
98
        foreach ($options['annotation_autoloaders'] as $autoloader) {
99
            AnnotationRegistry::registerLoader($autoloader);
100
        }
101
    }
102
103
    /**
104
     * Create Doctrine ODM configuration.
105
     *
106
     * @param array $options
107
     *
108
     * @return \Doctrine\ODM\MongoDB\Configuration|null
109
     */
110
    protected static function createConfiguration(array $options)
111
    {
112
        $config = static::createBareConfiguration($options);
113
114
        if ($options['annotation_paths']) {
115
            $config->setMetadataDriverImpl(
116
                $config->newDefaultAnnotationDriver(static::normalizePaths($options['annotation_paths']), false)
0 ignored issues
show
Unused Code introduced by
The call to Configuration::newDefaultAnnotationDriver() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
117
            );
118
        }
119
120
        if ($options['xml_paths']) {
121
            $config->setMetadataDriverImpl(new XmlDriver(static::normalizePaths($options['xml_paths'])));
122
        }
123
124
        if ($options['yaml_paths']) {
125
            $config->setMetadataDriverImpl(new XmlDriver(static::normalizePaths($options['yaml_paths'])));
126
        }
127
128
        return $config->getMetadataDriverImpl() !== null ? $config : null;
129
    }
130
131
    /**
132
     * Create Doctrine ODM bare configuration.
133
     *
134
     * @param array $options
135
     *
136
     * @return \Doctrine\ODM\MongoDB\Configuration
137
     */
138
    protected static function createBareConfiguration(array $options)
139
    {
140
        $proxyDir = $options['proxy_path'] ?: sys_get_temp_dir();
141
142
        $cache = static::getCacheDriver($options);
143
        if ($cache instanceof CacheProvider) {
0 ignored issues
show
Bug introduced by
The class Jgut\Slim\Doctrine\CacheProvider does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
144
            $cache->setNamespace('odm_dc2_' . md5($proxyDir) . '_');
145
        }
146
147
        $config = new Configuration();
148
        $config->setMetadataCacheImpl($cache);
149
        $config->setProxyDir($proxyDir);
150
        $config->setProxyNamespace('DoctrineODMProxies');
151
        $config->setHydratorDir($options['hydrator_path'] ?: sys_get_temp_dir());
152
        $config->setHydratorNamespace('DoctrineODMHydrators');
153
154
        return $config;
155
    }
156
157
    /**
158
     * Get cache driver.
159
     *
160
     * @param  array $options
161
     *
162
     * @return \Doctrine\Common\Cache\Cache
163
     */
164
    protected static function getCacheDriver(array $options)
165
    {
166
        $cache = $options['cache_driver'];
167
        if ($cache === null) {
168
            if (extension_loaded('apc')) {
169
                $cache = new \Doctrine\Common\Cache\ApcCache();
170
            } elseif (extension_loaded('xcache')) {
171
                $cache = new \Doctrine\Common\Cache\XcacheCache();
172
            } elseif (extension_loaded('memcache')) {
173
                $memcache = new \Memcache();
174
                $memcache->connect('127.0.0.1');
175
                $cache = new \Doctrine\Common\Cache\MemcacheCache();
176
                $cache->setMemcache($memcache);
177
            } elseif (extension_loaded('redis')) {
178
                $redis = new \Redis();
179
                $redis->connect('127.0.0.1');
180
                $cache = new \Doctrine\Common\Cache\RedisCache();
181
                $cache->setRedis($redis);
182
            } else {
183
                $cache = new \Doctrine\Common\Cache\ArrayCache();
184
            }
185
        }
186
187
        return $cache;
188
    }
189
190
    /**
191
     * Normalize paths to array.
192
     *
193
     * @param array|string $paths
194
     *
195
     * @return array
196
     */
197
    protected static function normalizePaths($paths)
198
    {
199
        return is_array($paths) ? $paths : [$paths];
200
    }
201
202
    /**
203
     * Setup proxies.
204
     *
205
     * @param \Doctrine\ODM\MongoDB\Configuration $config
206
     * @param array                               $options
207
     */
208
    protected static function setupProxy(Configuration &$config, array $options)
209
    {
210
        if ($options['proxies_namespace']) {
211
            $config->setProxyNamespace($options['proxies_namespace']);
212
        }
213
214
        $config->setAutoGenerateProxyClasses(intval($options['auto_generate_proxies']));
215
    }
216
217
    /**
218
     * Setup hydrators.
219
     *
220
     * @param \Doctrine\ODM\MongoDB\Configuration $config
221
     * @param array                               $options
222
     */
223
    protected static function setupHydrator(Configuration &$config, array $options)
224
    {
225
        if ($options['hydrators_namespace']) {
226
            $config->setHydratorNamespace($options['hydrators_namespace']);
227
        }
228
    }
229
230
    /**
231
     * Setup logger.
232
     *
233
     * @param \Doctrine\ODM\MongoDB\Configuration $config
234
     * @param array                               $options
235
     */
236
    protected static function setupLogger(Configuration &$config, array $options)
237
    {
238
        if ($options['logger_callable']) {
239
            $config->setLoggerCallable($options['logger_callable']);
240
        }
241
    }
242
243
    /**
244
     * Create MongoDB Connection.
245
     *
246
     * @param  array $options
247
     *
248
     * @throws \InvalidArgumentException
249
     *
250
     * @return \Doctrine\MongoDB\Connection
251
     */
252
    protected static function getConnection(array $options)
253
    {
254
        $connection = $options['connection'];
255
256
        if (!$connection instanceof Connection) {
257
            if (!is_array($connection)) {
258
                throw new InvalidArgumentException(sprintf('Invalid argument: %s', $connection));
259
            }
260
261
            $connection = new Connection(
262
                isset($options['connection']['server']) ? $options['connection']['server'] : null,
263
                isset($options['connection']['options']) ? $options['connection']['options'] : []
264
            );
265
        }
266
267
        return $connection;
268
    }
269
}
270