Completed
Push — master ( fb0873...0bfc19 )
by Julián
02:05
created

RelationalBuilder::getDefaultRepositoryClass()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
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 Symfony\Component\Console\Command\Command;
32
use Symfony\Component\Console\Helper\HelperSet;
33
34
/**
35
 * Doctrine RDBMS Entity Manager builder.
36
 */
37
class RelationalBuilder extends AbstractManagerBuilder
38
{
39
    /**
40
     * Entity Manager.
41
     *
42
     * @var EntityManager
43
     */
44
    protected $manager;
45
46
    /**
47
     * Query cache driver.
48
     *
49
     * @var CacheProvider
50
     */
51
    protected $queryCacheDriver;
52
53
    /**
54
     * Result cache driver.
55
     *
56
     * @var CacheProvider
57
     */
58
    protected $resultCacheDriver;
59
60
    /**
61
     * Naming strategy.
62
     *
63
     * @var NamingStrategy
64
     */
65
    protected $namingStrategy;
66
67
    /**
68
     * Quote strategy.
69
     *
70
     * @var QuoteStrategy
71
     */
72
    protected $quoteStrategy;
73
74
    /**
75
     * SQL logger.
76
     *
77
     * @var SQLLogger
78
     */
79
    protected $SQLLogger;
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    protected function getDefaultOptions()
85
    {
86
        return [
87
            'connection' => [], // Array or \Doctrine\DBAL\Connection
88
            'proxies_namespace' => 'DoctrineRDBMSORMProxy',
89
            'metadata_cache_namespace' => 'DoctrineRDBMSORMMetadataCache',
90
            'query_cache_namespace' => 'DoctrineRDBMSORMQueryCache',
91
            'result_cache_namespace' => 'DoctrineRDBMSORMResultCache',
92
            'default_repository_class' => EntityRepository::class,
93
        ];
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     *
99
     * @throws \Doctrine\DBAL\DBALException
100
     * @throws \Doctrine\ORM\ORMException
101
     * @throws \InvalidArgumentException
102
     * @throws \RuntimeException
103
     * @throws \UnexpectedValueException
104
     *
105
     * @return EntityManager
106
     */
107
    public function getManager($force = false)
108
    {
109
        if ($force === true) {
110
            $this->wipe();
111
        }
112
113
        if (!$this->manager instanceof EntityManager) {
114
            $this->manager = $this->buildManager();
115
        }
116
117
        return $this->manager;
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    protected function wipe()
124
    {
125
        parent::wipe();
126
127
        $this->manager = null;
128
        $this->queryCacheDriver = null;
129
        $this->resultCacheDriver = null;
130
        $this->namingStrategy = null;
131
        $this->quoteStrategy = null;
132
        $this->SQLLogger = null;
133
    }
134
135
    /**
136
     * Build new Doctrine entity manager.
137
     *
138
     * @throws \Doctrine\DBAL\DBALException
139
     * @throws \Doctrine\ORM\ORMException
140
     * @throws \InvalidArgumentException
141
     * @throws \RuntimeException
142
     * @throws \UnexpectedValueException
143
     *
144
     * @return EntityManager
145
     */
146
    protected function buildManager()
147
    {
148
        $config = new Configuration();
149
150
        $this->setupAnnotationMetadata();
151
        $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...
152
153
        $config->setProxyDir($this->getProxiesPath());
154
        $config->setProxyNamespace($this->getProxiesNamespace());
155
        $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...
156
157
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
158
        $config->setQueryCacheImpl($this->getQueryCacheDriver());
159
        $config->setResultCacheImpl($this->getResultCacheDriver());
160
161
        if ($this->getRepositoryFactory() !== null) {
162
            $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...
163
        }
164
165
        if ($this->getDefaultRepositoryClass() !== null) {
166
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
167
        }
168
169
        $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...
170
        $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...
171
172
        $config->setSQLLogger($this->getSQLLogger());
173
        $config->setCustomStringFunctions($this->getCustomStringFunctions());
174
        $config->setCustomNumericFunctions($this->getCustomNumericFunctions());
175
        $config->setCustomDatetimeFunctions($this->getCustomDateTimeFunctions());
176
177
        $entityManager = EntityManager::create($this->getOption('connection'), $config, $this->getEventManager());
178
179
        $platform = $entityManager->getConnection()->getDatabasePlatform();
180
        foreach ($this->getCustomTypes() as $type => $class) {
181
            Type::addType($type, $class);
182
            $platform->registerDoctrineTypeMapping($type, $type);
183
        }
184
185
        return $entityManager;
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191
    protected function getAnnotationMetadataDriver(array $paths)
192
    {
193
        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...
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    protected function getXmlMetadataDriver(array $paths, $extension = null)
200
    {
201
        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...
202
    }
203
204
    /**
205
     * {@inheritdoc}
206
     */
207
    protected function getYamlMetadataDriver(array $paths, $extension = null)
208
    {
209
        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...
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     *
215
     * @throws \InvalidArgumentException
216
     *
217
     * @return RepositoryFactory|null
218
     */
219
    protected function getRepositoryFactory()
220
    {
221
        if (!array_key_exists('repository_factory', $this->options)) {
222
            return;
223
        }
224
225
        $repositoryFactory = $this->options['repository_factory'];
226
227
        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...
228
            throw new \InvalidArgumentException(sprintf(
229
                'Invalid factory class "%s". It must be a Doctrine\ORM\Repository\RepositoryFactory.',
230
                get_class($repositoryFactory)
231
            ));
232
        }
233
234
        return $repositoryFactory;
235
    }
236
237
    /**
238
     * Retrieve query cache driver.
239
     *
240
     * @throws \InvalidArgumentException
241
     *
242
     * @return CacheProvider
243
     */
244
    public function getQueryCacheDriver()
245
    {
246
        if (!$this->queryCacheDriver instanceof CacheProvider) {
247
            $queryCacheDriver = $this->getOption('query_cache_driver');
248
            $cacheNamespace = (string) $this->getOption('query_cache_namespace');
249
250
            if (!$queryCacheDriver instanceof CacheProvider) {
251
                $queryCacheDriver = clone $this->getMetadataCacheDriver();
252
                $queryCacheDriver->setNamespace($cacheNamespace);
253
            }
254
255
            if ($queryCacheDriver->getNamespace() === '') {
256
                $queryCacheDriver->setNamespace($cacheNamespace);
257
            }
258
259
            $this->queryCacheDriver = $queryCacheDriver;
260
        }
261
262
        return $this->queryCacheDriver;
263
    }
264
265
    /**
266
     * Set query cache driver.
267
     *
268
     * @param CacheProvider $queryCacheDriver
269
     */
270
    public function setQueryCacheDriver(CacheProvider $queryCacheDriver)
271
    {
272
        $this->queryCacheDriver = $queryCacheDriver;
273
    }
274
275
    /**
276
     * Retrieve result cache driver.
277
     *
278
     * @throws \InvalidArgumentException
279
     *
280
     * @return CacheProvider
281
     */
282
    public function getResultCacheDriver()
283
    {
284
        if (!$this->resultCacheDriver instanceof CacheProvider) {
285
            $resultCacheDriver = $this->getOption('result_cache_driver');
286
            $cacheNamespace = (string) $this->getOption('result_cache_namespace');
287
288
            if (!$resultCacheDriver instanceof CacheProvider) {
289
                $resultCacheDriver = clone $this->getMetadataCacheDriver();
290
                $resultCacheDriver->setNamespace($cacheNamespace);
291
            }
292
293
            if ($resultCacheDriver->getNamespace() === '') {
294
                $resultCacheDriver->setNamespace($cacheNamespace);
295
            }
296
297
            $this->resultCacheDriver = $resultCacheDriver;
298
        }
299
300
        return $this->resultCacheDriver;
301
    }
302
303
    /**
304
     * Set result cache driver.
305
     *
306
     * @param CacheProvider $resultCacheDriver
307
     */
308
    public function setResultCacheDriver(CacheProvider $resultCacheDriver)
309
    {
310
        $this->resultCacheDriver = $resultCacheDriver;
311
    }
312
313
    /**
314
     * Retrieve naming strategy.
315
     *
316
     * @return NamingStrategy
317
     */
318
    protected function getNamingStrategy()
319
    {
320
        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...
321
            $namingStrategy = $this->getOption('naming_strategy');
322
323
            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...
324
                $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
325
            }
326
327
            $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...
328
        }
329
330
        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 330 which is incompatible with the return type documented by Jgut\Doctrine\ManagerBui...lder::getNamingStrategy of type Doctrine\ORM\Mapping\NamingStrategy.
Loading history...
331
    }
332
333
    /**
334
     * Retrieve quote strategy.
335
     *
336
     * @throws \InvalidArgumentException
337
     *
338
     * @return QuoteStrategy
339
     */
340
    protected function getQuoteStrategy()
341
    {
342
        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...
343
            $quoteStrategy = $this->getOption('quote_strategy');
344
345
            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...
346
                $quoteStrategy = new DefaultQuoteStrategy;
347
            }
348
349
            $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...
350
        }
351
352
        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 352 which is incompatible with the return type documented by Jgut\Doctrine\ManagerBui...ilder::getQuoteStrategy of type Doctrine\ORM\Mapping\QuoteStrategy.
Loading history...
353
    }
354
355
    /**
356
     * Retrieve SQL logger.
357
     *
358
     * @return SQLLogger|null
359
     */
360
    protected function getSQLLogger()
361
    {
362
        if (!$this->SQLLogger instanceof SQLLogger) {
363
            $sqlLogger = $this->getOption('sql_logger');
364
365
            if ($sqlLogger instanceof SQLLogger) {
366
                $this->SQLLogger = $sqlLogger;
367
            }
368
        }
369
370
        return $this->SQLLogger;
371
    }
372
373
    /**
374
     * Retrieve custom DQL string functions.
375
     *
376
     * @return array
377
     */
378
    protected function getCustomStringFunctions()
379
    {
380
        $functions = (array) $this->getOption('custom_string_functions');
381
382
        return array_filter(
383
            $functions,
384
            function ($name) {
385
                return is_string($name);
386
            },
387
            ARRAY_FILTER_USE_KEY
388
        );
389
    }
390
391
    /**
392
     * Retrieve custom DQL numeric functions.
393
     *
394
     * @return array
395
     */
396
    protected function getCustomNumericFunctions()
397
    {
398
        $functions = (array) $this->getOption('custom_numeric_functions');
399
400
        return array_filter(
401
            $functions,
402
            function ($name) {
403
                return is_string($name);
404
            },
405
            ARRAY_FILTER_USE_KEY
406
        );
407
    }
408
409
    /**
410
     * Retrieve custom DQL date time functions.
411
     *
412
     * @return array
413
     */
414
    protected function getCustomDateTimeFunctions()
415
    {
416
        $functions = (array) $this->getOption('custom_datetime_functions');
417
418
        return array_filter(
419
            $functions,
420
            function ($name) {
421
                return is_string($name);
422
            },
423
            ARRAY_FILTER_USE_KEY
424
        );
425
    }
426
427
    /**
428
     * Retrieve custom DBAL types.
429
     *
430
     * @return array
431
     */
432
    protected function getCustomTypes()
433
    {
434
        $types = (array) $this->getOption('custom_types');
435
436
        return array_filter(
437
            $types,
438
            function ($name) {
439
                return is_string($name);
440
            },
441
            ARRAY_FILTER_USE_KEY
442
        );
443
    }
444
445
    /**
446
     * {@inheritdoc}
447
     *
448
     * @throws \Doctrine\DBAL\DBALException
449
     * @throws \Doctrine\ORM\ORMException
450
     * @throws \InvalidArgumentException
451
     * @throws \RuntimeException
452
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
453
     * @throws \Symfony\Component\Console\Exception\LogicException
454
     * @throws \UnexpectedValueException
455
     *
456
     * @return Command[]
457
     */
458
    public function getConsoleCommands()
459
    {
460
        $commands = [
461
            // DBAL
462
            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
463
            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
464
465
            // ORM
466
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
467
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
468
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
469
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
470
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
471
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
472
            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
473
            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
474
            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
475
            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
476
            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
477
            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
478
            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
479
            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
480
            new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
481
            new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand(),
482
        ];
483
        $commandPrefix = (string) $this->getName();
484
485
        if ($commandPrefix !== '') {
486
            $commands = array_map(
487
                function (Command $command) use ($commandPrefix) {
488
                    $commandNames = array_map(
489
                        function ($commandName) use ($commandPrefix) {
490
                            return preg_replace('/^(dbal|orm):/', $commandPrefix . ':$1:', $commandName);
491
                        },
492
                        array_merge([$command->getName()], $command->getAliases())
493
                    );
494
495
                    $command->setName(array_shift($commandNames));
496
                    $command->setAliases($commandNames);
497
498
                    return $command;
499
                },
500
                $commands
501
            );
502
        }
503
504
        return $commands;
505
    }
506
507
    /**
508
     * {@inheritdoc}
509
     *
510
     * @throws \Doctrine\DBAL\DBALException
511
     * @throws \Doctrine\ORM\ORMException
512
     * @throws \InvalidArgumentException
513
     * @throws \RuntimeException
514
     * @throws \UnexpectedValueException
515
     */
516
    public function getConsoleHelperSet()
517
    {
518
        $entityManager = $this->getManager();
519
520
        return new HelperSet([
521
            'db' => new ConnectionHelper($entityManager->getConnection()),
522
            'em' => new EntityManagerHelper($entityManager),
523
        ]);
524
    }
525
}
526