Completed
Push — master ( d72a9d...b72433 )
by Julián
02:18
created

RelationalBuilder::getDefaultOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
/*
4
 * doctrine-manager-builder (https://github.com/juliangut/doctrine-manager-builder).
5
 * Doctrine2 managers builder.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/doctrine-manager-builder
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Jgut\Doctrine\ManagerBuilder;
13
14
use Doctrine\Common\Annotations\AnnotationReader;
15
use Doctrine\Common\Cache\CacheProvider;
16
use Doctrine\DBAL\Logging\SQLLogger;
17
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
18
use Doctrine\DBAL\Types\Type;
19
use Doctrine\ORM\Configuration;
20
use Doctrine\ORM\EntityManager;
21
use Doctrine\ORM\EntityRepository;
22
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
23
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
24
use Doctrine\ORM\Mapping\Driver\XmlDriver;
25
use Doctrine\ORM\Mapping\Driver\YamlDriver;
26
use Doctrine\ORM\Mapping\NamingStrategy;
27
use Doctrine\ORM\Mapping\QuoteStrategy;
28
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
29
use Doctrine\ORM\Repository\RepositoryFactory;
30
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
31
use Doctrine\ORM\Version;
32
use Symfony\Component\Console\Command\Command;
33
use Symfony\Component\Console\Helper\HelperSet;
34
35
/**
36
 * Doctrine RDBMS Entity Manager builder.
37
 */
38
class RelationalBuilder extends AbstractManagerBuilder
39
{
40
    /**
41
     * Entity Manager.
42
     *
43
     * @var EntityManager
44
     */
45
    protected $manager;
46
47
    /**
48
     * Query cache driver.
49
     *
50
     * @var CacheProvider
51
     */
52
    protected $queryCacheDriver;
53
54
    /**
55
     * Result cache driver.
56
     *
57
     * @var CacheProvider
58
     */
59
    protected $resultCacheDriver;
60
61
    /**
62
     * Naming strategy.
63
     *
64
     * @var NamingStrategy
65
     */
66
    protected $namingStrategy;
67
68
    /**
69
     * Quote strategy.
70
     *
71
     * @var QuoteStrategy
72
     */
73
    protected $quoteStrategy;
74
75
    /**
76
     * SQL logger.
77
     *
78
     * @var SQLLogger
79
     */
80
    protected $SQLLogger;
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    protected function getDefaultOptions()
86
    {
87
        return [
88
            'connection' => [], // Array or \Doctrine\DBAL\Connection
89
            'proxies_namespace' => 'DoctrineRDBMSORMProxy',
90
            'metadata_cache_namespace' => 'DoctrineRDBMSORMMetadataCache',
91
            'query_cache_namespace' => 'DoctrineRDBMSORMQueryCache',
92
            'result_cache_namespace' => 'DoctrineRDBMSORMResultCache',
93
            'default_repository_class' => EntityRepository::class,
94
        ];
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     *
100
     * @throws \Doctrine\DBAL\DBALException
101
     * @throws \Doctrine\ORM\ORMException
102
     * @throws \InvalidArgumentException
103
     * @throws \RuntimeException
104
     * @throws \UnexpectedValueException
105
     *
106
     * @return EntityManager
107
     */
108
    public function getManager($force = false)
109
    {
110
        if ($force === true) {
111
            $this->wipe();
112
        }
113
114
        if (!$this->manager instanceof EntityManager) {
115
            $this->manager = $this->buildManager();
116
        }
117
118
        return $this->manager;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    protected function wipe()
125
    {
126
        parent::wipe();
127
128
        $this->manager = null;
129
        $this->queryCacheDriver = null;
130
        $this->resultCacheDriver = null;
131
        $this->namingStrategy = null;
132
        $this->quoteStrategy = null;
133
        $this->SQLLogger = null;
134
    }
135
136
    /**
137
     * Build new Doctrine entity manager.
138
     *
139
     * @throws \Doctrine\DBAL\DBALException
140
     * @throws \Doctrine\ORM\ORMException
141
     * @throws \InvalidArgumentException
142
     * @throws \RuntimeException
143
     * @throws \UnexpectedValueException
144
     *
145
     * @return EntityManager
146
     */
147
    protected function buildManager()
148
    {
149
        $config = new Configuration();
150
151
        $this->setupAnnotationMetadata();
152
        $config->setMetadataDriverImpl($this->getMetadataMappingDriver());
0 ignored issues
show
Documentation introduced by
$this->getMetadataMappingDriver() is of type object<Doctrine\Common\P...g\Driver\MappingDriver>, but the function expects a object<Doctrine\ORM\Mapping\Driver\Driver>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
153
154
        $config->setProxyDir($this->getProxiesPath());
155
        $config->setProxyNamespace($this->getProxiesNamespace());
156
        $config->setAutoGenerateProxyClasses($this->getProxiesAutoGeneration());
0 ignored issues
show
Documentation introduced by
$this->getProxiesAutoGeneration() is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
157
158
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
159
        $config->setQueryCacheImpl($this->getQueryCacheDriver());
160
        $config->setResultCacheImpl($this->getResultCacheDriver());
161
162
        if ($this->getRepositoryFactory() !== null) {
163
            $config->setRepositoryFactory($this->getRepositoryFactory());
0 ignored issues
show
Bug introduced by
The method setRepositoryFactory() does not seem to exist on object<Doctrine\ORM\Configuration>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
164
        }
165
166
        if ($this->getDefaultRepositoryClass() !== null) {
167
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
168
        }
169
170
        $config->setNamingStrategy($this->getNamingStrategy());
0 ignored issues
show
Bug introduced by
The method setNamingStrategy() does not seem to exist on object<Doctrine\ORM\Configuration>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
171
        $config->setQuoteStrategy($this->getQuoteStrategy());
0 ignored issues
show
Bug introduced by
The method setQuoteStrategy() does not seem to exist on object<Doctrine\ORM\Configuration>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
173
        $config->setSQLLogger($this->getSQLLogger());
174
        $config->setCustomStringFunctions($this->getCustomStringFunctions());
175
        $config->setCustomNumericFunctions($this->getCustomNumericFunctions());
176
        $config->setCustomDatetimeFunctions($this->getCustomDateTimeFunctions());
177
178
        $entityManager = EntityManager::create($this->getOption('connection'), $config, $this->getEventManager());
179
180
        $platform = $entityManager->getConnection()->getDatabasePlatform();
181
        foreach ($this->getCustomTypes() as $type => $class) {
182
            Type::addType($type, $class);
183
            $platform->registerDoctrineTypeMapping($type, $type);
184
        }
185
186
        return $entityManager;
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    protected function getAnnotationMetadataDriver(array $paths)
193
    {
194
        return new AnnotationDriver(new AnnotationReader, $paths);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \Doctrine\ORM...ationReader(), $paths); (Doctrine\ORM\Mapping\Driver\AnnotationDriver) is incompatible with the return type declared by the abstract method Jgut\Doctrine\ManagerBui...nnotationMetadataDriver of type Doctrine\Common\Persiste...ng\Driver\MappingDriver.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200
    protected function getXmlMetadataDriver(array $paths, $extension = null)
201
    {
202
        return new XmlDriver($paths, $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION);
0 ignored issues
show
Unused Code introduced by
The call to XmlDriver::__construct() has too many arguments starting with $extension ?: \Doctrine\...:DEFAULT_FILE_EXTENSION.

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...
Bug Best Practice introduced by
The return type of return new \Doctrine\ORM...EFAULT_FILE_EXTENSION); (Doctrine\ORM\Mapping\Driver\XmlDriver) is incompatible with the return type declared by the abstract method Jgut\Doctrine\ManagerBui...r::getXmlMetadataDriver of type Doctrine\Common\Persiste...ng\Driver\MappingDriver.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208
    protected function getYamlMetadataDriver(array $paths, $extension = null)
209
    {
210
        return new YamlDriver($paths, $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION);
0 ignored issues
show
Unused Code introduced by
The call to YamlDriver::__construct() has too many arguments starting with $extension ?: \Doctrine\...:DEFAULT_FILE_EXTENSION.

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...
Bug Best Practice introduced by
The return type of return new \Doctrine\ORM...EFAULT_FILE_EXTENSION); (Doctrine\ORM\Mapping\Driver\YamlDriver) is incompatible with the return type declared by the abstract method Jgut\Doctrine\ManagerBui...::getYamlMetadataDriver of type Doctrine\Common\Persiste...ng\Driver\MappingDriver.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     *
216
     * @throws \InvalidArgumentException
217
     *
218
     * @return RepositoryFactory|null
219
     */
220
    protected function getRepositoryFactory()
221
    {
222
        if (!array_key_exists('repository_factory', $this->options)) {
223
            return;
224
        }
225
226
        $repositoryFactory = $this->options['repository_factory'];
227
228
        if (!$repositoryFactory instanceof RepositoryFactory) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\Repository\RepositoryFactory 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...
229
            throw new \InvalidArgumentException(sprintf(
230
                'Invalid factory class "%s". It must be a Doctrine\ORM\Repository\RepositoryFactory.',
231
                get_class($repositoryFactory)
232
            ));
233
        }
234
235
        return $repositoryFactory;
236
    }
237
238
    /**
239
     * Retrieve query cache driver.
240
     *
241
     * @throws \InvalidArgumentException
242
     *
243
     * @return CacheProvider
244
     */
245
    public function getQueryCacheDriver()
246
    {
247
        if (!$this->queryCacheDriver instanceof CacheProvider) {
248
            $queryCacheDriver = $this->getOption('query_cache_driver');
249
            $cacheNamespace = (string) $this->getOption('query_cache_namespace');
250
251
            if (!$queryCacheDriver instanceof CacheProvider) {
252
                $queryCacheDriver = clone $this->getMetadataCacheDriver();
253
                $queryCacheDriver->setNamespace($cacheNamespace);
254
            }
255
256
            if ($queryCacheDriver->getNamespace() === '') {
257
                $queryCacheDriver->setNamespace($cacheNamespace);
258
            }
259
260
            $this->queryCacheDriver = $queryCacheDriver;
261
        }
262
263
        return $this->queryCacheDriver;
264
    }
265
266
    /**
267
     * Set query cache driver.
268
     *
269
     * @param CacheProvider $queryCacheDriver
270
     */
271
    public function setQueryCacheDriver(CacheProvider $queryCacheDriver)
272
    {
273
        $this->queryCacheDriver = $queryCacheDriver;
274
    }
275
276
    /**
277
     * Retrieve result cache driver.
278
     *
279
     * @throws \InvalidArgumentException
280
     *
281
     * @return CacheProvider
282
     */
283
    public function getResultCacheDriver()
284
    {
285
        if (!$this->resultCacheDriver instanceof CacheProvider) {
286
            $resultCacheDriver = $this->getOption('result_cache_driver');
287
            $cacheNamespace = (string) $this->getOption('result_cache_namespace');
288
289
            if (!$resultCacheDriver instanceof CacheProvider) {
290
                $resultCacheDriver = clone $this->getMetadataCacheDriver();
291
                $resultCacheDriver->setNamespace($cacheNamespace);
292
            }
293
294
            if ($resultCacheDriver->getNamespace() === '') {
295
                $resultCacheDriver->setNamespace($cacheNamespace);
296
            }
297
298
            $this->resultCacheDriver = $resultCacheDriver;
299
        }
300
301
        return $this->resultCacheDriver;
302
    }
303
304
    /**
305
     * Set result cache driver.
306
     *
307
     * @param CacheProvider $resultCacheDriver
308
     */
309
    public function setResultCacheDriver(CacheProvider $resultCacheDriver)
310
    {
311
        $this->resultCacheDriver = $resultCacheDriver;
312
    }
313
314
    /**
315
     * Retrieve naming strategy.
316
     *
317
     * @return NamingStrategy
318
     */
319
    protected function getNamingStrategy()
320
    {
321
        if (!$this->namingStrategy instanceof NamingStrategy) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\Mapping\NamingStrategy 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...
322
            $namingStrategy = $this->getOption('naming_strategy');
323
324
            if (!$namingStrategy instanceof NamingStrategy) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\Mapping\NamingStrategy 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...
325
                $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
326
            }
327
328
            $this->namingStrategy = $namingStrategy;
0 ignored issues
show
Documentation Bug introduced by
It seems like $namingStrategy can also be of type object<Doctrine\ORM\Mapp...derscoreNamingStrategy>. However, the property $namingStrategy is declared as type object<Doctrine\ORM\Mapping\NamingStrategy>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
329
        }
330
331
        return $this->namingStrategy;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->namingStrategy; of type Doctrine\ORM\Mapping\Und...\Mapping\NamingStrategy adds the type Doctrine\ORM\Mapping\UnderscoreNamingStrategy to the return on line 331 which is incompatible with the return type documented by Jgut\Doctrine\ManagerBui...lder::getNamingStrategy of type Doctrine\ORM\Mapping\NamingStrategy.
Loading history...
332
    }
333
334
    /**
335
     * Retrieve quote strategy.
336
     *
337
     * @throws \InvalidArgumentException
338
     *
339
     * @return QuoteStrategy
340
     */
341
    protected function getQuoteStrategy()
342
    {
343
        if (!$this->quoteStrategy instanceof QuoteStrategy) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\Mapping\QuoteStrategy 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...
344
            $quoteStrategy = $this->getOption('quote_strategy');
345
346
            if (!$quoteStrategy instanceof QuoteStrategy) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\Mapping\QuoteStrategy 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...
347
                $quoteStrategy = new DefaultQuoteStrategy;
348
            }
349
350
            $this->quoteStrategy = $quoteStrategy;
0 ignored issues
show
Documentation Bug introduced by
It seems like $quoteStrategy can also be of type object<Doctrine\ORM\Mapping\DefaultQuoteStrategy>. However, the property $quoteStrategy is declared as type object<Doctrine\ORM\Mapping\QuoteStrategy>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
351
        }
352
353
        return $this->quoteStrategy;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->quoteStrategy; of type Doctrine\ORM\Mapping\Def...M\Mapping\QuoteStrategy adds the type Doctrine\ORM\Mapping\DefaultQuoteStrategy to the return on line 353 which is incompatible with the return type documented by Jgut\Doctrine\ManagerBui...ilder::getQuoteStrategy of type Doctrine\ORM\Mapping\QuoteStrategy.
Loading history...
354
    }
355
356
    /**
357
     * Retrieve SQL logger.
358
     *
359
     * @return SQLLogger|null
360
     */
361
    protected function getSQLLogger()
362
    {
363
        if (!$this->SQLLogger instanceof SQLLogger) {
364
            $sqlLogger = $this->getOption('sql_logger');
365
366
            if ($sqlLogger instanceof SQLLogger) {
367
                $this->SQLLogger = $sqlLogger;
368
            }
369
        }
370
371
        return $this->SQLLogger;
372
    }
373
374
    /**
375
     * Retrieve custom DQL string functions.
376
     *
377
     * @return array
378
     */
379
    protected function getCustomStringFunctions()
380
    {
381
        $functions = (array) $this->getOption('custom_string_functions');
382
383
        return array_filter(
384
            $functions,
385
            function ($name) {
386
                return is_string($name);
387
            },
388
            ARRAY_FILTER_USE_KEY
389
        );
390
    }
391
392
    /**
393
     * Retrieve custom DQL numeric functions.
394
     *
395
     * @return array
396
     */
397
    protected function getCustomNumericFunctions()
398
    {
399
        $functions = (array) $this->getOption('custom_numeric_functions');
400
401
        return array_filter(
402
            $functions,
403
            function ($name) {
404
                return is_string($name);
405
            },
406
            ARRAY_FILTER_USE_KEY
407
        );
408
    }
409
410
    /**
411
     * Retrieve custom DQL date time functions.
412
     *
413
     * @return array
414
     */
415
    protected function getCustomDateTimeFunctions()
416
    {
417
        $functions = (array) $this->getOption('custom_datetime_functions');
418
419
        return array_filter(
420
            $functions,
421
            function ($name) {
422
                return is_string($name);
423
            },
424
            ARRAY_FILTER_USE_KEY
425
        );
426
    }
427
428
    /**
429
     * Retrieve custom DBAL types.
430
     *
431
     * @return array
432
     */
433
    protected function getCustomTypes()
434
    {
435
        $types = (array) $this->getOption('custom_types');
436
437
        return array_filter(
438
            $types,
439
            function ($name) {
440
                return is_string($name);
441
            },
442
            ARRAY_FILTER_USE_KEY
443
        );
444
    }
445
446
    /**
447
     * {@inheritdoc}
448
     *
449
     * @throws \Doctrine\DBAL\DBALException
450
     * @throws \Doctrine\ORM\ORMException
451
     * @throws \InvalidArgumentException
452
     * @throws \RuntimeException
453
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
454
     * @throws \Symfony\Component\Console\Exception\LogicException
455
     * @throws \UnexpectedValueException
456
     *
457
     * @return Command[]
458
     */
459
    public function getConsoleCommands()
460
    {
461
        $commands = [
462
            // DBAL
463
            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
464
            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
465
466
            // ORM
467
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
468
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
469
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
470
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
471
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
472
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
473
            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
474
            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
475
            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
476
            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
477
            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
478
            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
479
            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
480
            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
481
            new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
482
        ];
483
484
        if (Version::compare('2.5') <= 0) {
485
            $commands[] = new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand();
486
        }
487
488
        $commandPrefix = (string) $this->getName();
489
490
        if ($commandPrefix !== '') {
491
            $commands = array_map(
492
                function (Command $command) use ($commandPrefix) {
493
                    $commandNames = array_map(
494
                        function ($commandName) use ($commandPrefix) {
495
                            return preg_replace('/^(dbal|orm):/', $commandPrefix . ':$1:', $commandName);
496
                        },
497
                        array_merge([$command->getName()], $command->getAliases())
498
                    );
499
500
                    $command->setName(array_shift($commandNames));
501
                    $command->setAliases($commandNames);
502
503
                    return $command;
504
                },
505
                $commands
506
            );
507
        }
508
509
        return $commands;
510
    }
511
512
    /**
513
     * {@inheritdoc}
514
     *
515
     * @throws \Doctrine\DBAL\DBALException
516
     * @throws \Doctrine\ORM\ORMException
517
     * @throws \InvalidArgumentException
518
     * @throws \RuntimeException
519
     * @throws \UnexpectedValueException
520
     */
521
    public function getConsoleHelperSet()
522
    {
523
        $entityManager = $this->getManager();
524
525
        return new HelperSet([
526
            'db' => new ConnectionHelper($entityManager->getConnection()),
527
            'em' => new EntityManagerHelper($entityManager),
528
        ]);
529
    }
530
}
531