Issues (28)

src/Adapter/Nette/DI/DoctrineExtension.php (17 issues)

1
<?php declare(strict_types = 1);
2
3
namespace Portiny\Doctrine\Adapter\Nette\DI;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
0 ignored issues
show
The type Doctrine\Common\Annotations\AnnotationReader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Doctrine\Common\Annotations\AnnotationRegistry;
0 ignored issues
show
The type Doctrine\Common\Annotations\AnnotationRegistry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Doctrine\Common\Annotations\CachedReader;
0 ignored issues
show
The type Doctrine\Common\Annotations\CachedReader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Doctrine\Common\Annotations\Reader;
0 ignored issues
show
The type Doctrine\Common\Annotations\Reader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Doctrine\Common\Cache\ApcuCache;
0 ignored issues
show
The type Doctrine\Common\Cache\ApcuCache was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Doctrine\Common\Cache\ArrayCache;
0 ignored issues
show
The type Doctrine\Common\Cache\ArrayCache was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Doctrine\Common\Cache\ChainCache;
0 ignored issues
show
The type Doctrine\Common\Cache\ChainCache was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Doctrine\Common\Cache\RedisCache;
0 ignored issues
show
The type Doctrine\Common\Cache\RedisCache was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Doctrine\Common\EventManager;
14
use Doctrine\Common\EventSubscriber;
15
use Doctrine\DBAL\Connection;
16
use Doctrine\DBAL\Tools\Console\Command\ImportCommand;
0 ignored issues
show
The type Doctrine\DBAL\Tools\Console\Command\ImportCommand was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Doctrine\ORM\Cache\CacheConfiguration;
18
use Doctrine\ORM\Cache\CacheFactory;
19
use Doctrine\ORM\Cache\DefaultCacheFactory;
20
use Doctrine\ORM\Cache\Logging\CacheLogger;
21
use Doctrine\ORM\Cache\Logging\CacheLoggerChain;
22
use Doctrine\ORM\Cache\Logging\StatisticsCacheLogger;
23
use Doctrine\ORM\Cache\RegionsConfiguration;
24
use Doctrine\ORM\Configuration;
25
use Doctrine\ORM\EntityManager;
26
use Doctrine\ORM\EntityManagerInterface;
27
use Doctrine\ORM\EntityRepository;
28
use Doctrine\ORM\Events;
29
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
30
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
31
use Doctrine\ORM\Query\Filter\SQLFilter;
32
use Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand;
33
use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand;
34
use Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand;
35
use Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand;
36
use Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand;
37
use Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand;
38
use Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand;
39
use Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand;
40
use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand;
41
use Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand;
42
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
43
use Doctrine\ORM\Tools\ResolveTargetEntityListener;
44
use Nette\DI\CompilerExtension;
45
use Nette\DI\ContainerBuilder;
46
use Nette\DI\ServiceDefinition;
47
use Nette\DI\Statement;
48
use Nette\PhpGenerator\ClassType;
49
use Nette\PhpGenerator\PhpLiteral;
50
use Nette\Schema\Expect;
51
use Nette\Schema\Schema;
52
use Nette\Utils\AssertionException;
53
use Nette\Utils\Validators;
54
use Portiny\Doctrine\Adapter\Nette\Tracy\DoctrineSQLPanel;
55
use Portiny\Doctrine\Cache\DefaultCache;
56
use Portiny\Doctrine\Contract\Provider\ClassMappingProviderInterface;
57
use Portiny\Doctrine\Contract\Provider\EntitySourceProviderInterface;
58
use stdClass;
59
use Symfony\Component\Console\Application;
60
use Symfony\Component\Console\Helper\HelperSet;
61
use Tracy\IBarPanel;
62
63
class DoctrineExtension extends CompilerExtension
64
{
65
	private const DOCTRINE_SQL_PANEL = DoctrineSQLPanel::class;
66
67
	/**
68
	 * @var string[]
69
	 */
70
	private $classMappings = [];
71
72
	/**
73
	 * @var string[]
74
	 */
75
	private $entitySources = [];
76
77
78
	/**
79
	 * {@inheritdoc}
80
	 */
81 1
	public function getConfigSchema(): Schema
82
	{
83 1
		$params = $this->getContainerBuilder()->parameters;
84 1
		$tempDir = $params['tempDir'] ?? '';
85
86 1
		return Expect::structure([
87 1
			'debug' => Expect::bool(interface_exists(IBarPanel::class)),
88 1
			'connection' => Expect::structure([
89 1
				'driver' => Expect::string('pdo_mysql'),
90 1
				'host' => Expect::string('localhost')->nullable(),
91 1
				'port' => Expect::int(3306)->nullable(),
92 1
				'user' => Expect::string('username')->nullable(),
93 1
				'password' => Expect::string('password')->nullable(),
94 1
				'dbname' => Expect::string('dbname')->nullable(),
95 1
				'memory' => Expect::bool(false)->nullable(),
96
			]),
97 1
			'dbal' => Expect::structure([
98 1
				'type_overrides' => Expect::array()->default([]),
99 1
				'types' => Expect::array()->default([]),
100 1
				'schema_filter' => Expect::string()->nullable(),
101
			]),
102 1
			'prefix' => Expect::string('doctrine.default'),
103 1
			'proxyDir' => Expect::string($tempDir . '/cache/proxies'),
104 1
			'proxyNamespace' => Expect::string('DoctrineProxies'),
105 1
			'sourceDir' => Expect::string()->required(),
106 1
			'entityManagerClassName' => Expect::string(EntityManager::class),
107 1
			'defaultRepositoryClassName' => Expect::string(EntityRepository::class),
108 1
			'repositoryFactory' => Expect::string()->nullable(),
109 1
			'namingStrategy' => Expect::string(UnderscoreNamingStrategy::class),
110 1
			'sqlLogger' => Expect::string()->nullable(),
111 1
			'targetEntityMappings' => Expect::array()->default([]),
112 1
			'metadata' => Expect::array()->default([]),
113 1
			'functions' => Expect::array()->default([]),
114
			// caches
115 1
			'metadataCache' => Expect::anyOf(Expect::string(), Expect::bool())->default('default'),
116 1
			'queryCache' => Expect::anyOf(Expect::string(), Expect::bool())->default('default'),
117 1
			'resultCache' => Expect::anyOf(Expect::string(), Expect::bool())->default('default'),
118 1
			'hydrationCache' => Expect::anyOf(Expect::string(), Expect::bool())->default('default'),
119 1
			'secondLevelCache' => Expect::structure([
120 1
				'enabled' => Expect::bool(false),
121 1
				'factoryClass' => Expect::string(DefaultCacheFactory::class),
122 1
				'driver' => Expect::string('default'),
123 1
				'regions' => Expect::structure([
124 1
					'defaultLifetime' => Expect::int(3600),
125 1
					'defaultLockLifetime' => Expect::int(60),
126
				]),
127 1
				'fileLockRegionDirectory' => Expect::string($tempDir . '/cache/Doctrine.Cache.Locks'),
128 1
				'logging' => Expect::bool(false),
129
			]),
130 1
			'cache' => Expect::structure([
131 1
				'redis' => Expect::structure([
132 1
					'class' => Expect::string(RedisCache::class),
133
				]),
134
			]),
135
		]);
136
	}
137
138
139
	/**
140
	 * {@inheritdoc}
141
	 */
142 1
	public function loadConfiguration(): void
143
	{
144 1
		$config = $this->parseConfig();
145
146 1
		$builder = $this->getContainerBuilder();
147 1
		$name = $config->prefix;
148
149 1
		$builder->addDefinition($name . '.namingStrategy')
150 1
			->setType($config->namingStrategy);
151
152 1
		$configurationDefinition = $builder->addDefinition($name . '.config')
153 1
			->setType(Configuration::class)
154 1
			->addSetup('setFilterSchemaAssetsExpression', [$config->dbal->schema_filter])
155 1
			->addSetup('setDefaultRepositoryClassName', [$config->defaultRepositoryClassName])
156 1
			->addSetup('setProxyDir', [$config->proxyDir])
157 1
			->addSetup('setProxyNamespace', [$config->proxyNamespace])
158 1
			->addSetup('setAutoGenerateProxyClasses', [$config->debug])
159 1
			->addSetup('setNamingStrategy', ['@' . $name . '.namingStrategy']);
160
161 1
		$builder->addDefinition($name . '.annotationReader')
162 1
			->setType(AnnotationReader::class)
163 1
			->setAutowired(false);
164
165 1
		$metadataCache = $this->getCache($name . '.metadata', $builder, $config->metadataCache ?: 'array');
166 1
		$builder->addDefinition($name . '.reader')
167 1
			->setType(Reader::class)
168 1
			->setFactory(CachedReader::class, ['@' . $name . '.annotationReader', $metadataCache, $config->debug]);
169
170 1
		$builder->addDefinition($name . '.annotationDriver')
171 1
			->setFactory(AnnotationDriver::class, ['@' . $name . '.reader', array_values($this->entitySources)]);
172
173 1
		$configurationDefinition->addSetup('setMetadataDriverImpl', ['@' . $name . '.annotationDriver']);
174
175 1
		foreach ($config->functions as $functionName => $function) {
176 1
			$configurationDefinition->addSetup('addCustomStringFunction', [$functionName, $function]);
177
		}
178
179 1
		if ($config->repositoryFactory) {
180
			$builder->addDefinition($name . '.repositoryFactory')
181
				->setType($config->repositoryFactory);
182
			$configurationDefinition->addSetup('setRepositoryFactory', ['@' . $name . '.repositoryFactory']);
183
		}
184 1
		if ($config->sqlLogger) {
185
			$builder->addDefinition($name . '.sqlLogger')
186
				->setType($config->sqlLogger);
187
			$configurationDefinition->addSetup('setSQLLogger', ['@' . $name . '.sqlLogger']);
188
		}
189
190 1
		if ($config->metadataCache !== false) {
191 1
			$configurationDefinition->addSetup(
192 1
				'setMetadataCacheImpl',
193 1
				[$this->getCache($name . '.metadata', $builder, $config->metadataCache)]
194
			);
195
		}
196
197 1
		if ($config->queryCache !== false) {
198 1
			$configurationDefinition->addSetup(
199 1
				'setQueryCacheImpl',
200 1
				[$this->getCache($name . '.query', $builder, $config->queryCache)]
201
			);
202
		}
203
204 1
		if ($config->resultCache !== false) {
205 1
			$configurationDefinition->addSetup(
206 1
				'setResultCacheImpl',
207 1
				[$this->getCache($name . '.ormResult', $builder, $config->resultCache)]
208
			);
209
		}
210
211 1
		if ($config->hydrationCache !== false) {
212 1
			$configurationDefinition->addSetup(
213 1
				'setHydrationCacheImpl',
214 1
				[$this->getCache($name . '.hydration', $builder, $config->hydrationCache)]
215
			);
216
		}
217
218 1
		$this->processSecondLevelCache($name, $config->secondLevelCache);
219
220 1
		$builder->addDefinition($name . '.connection')
221 1
			->setType(Connection::class)
222 1
			->setFactory('@' . $name . '.entityManager::getConnection');
223
224 1
		$builder->addDefinition($name . '.entityManager')
225 1
			->setType($config->entityManagerClassName)
226 1
			->setFactory(
227 1
				$config->entityManagerClassName . '::create',
228 1
				[(array) $config->connection, '@' . $name . '.config', '@Doctrine\Common\EventManager']
229
			);
230
231 1
		$builder->addDefinition($name . '.resolver')
232 1
			->setType(ResolveTargetEntityListener::class);
233
234 1
		if ($config->debug === true) {
235
			$builder->addDefinition($this->prefix($name . '.diagnosticsPanel'))
236
				->setType(self::DOCTRINE_SQL_PANEL);
237
		}
238
239
		// import Doctrine commands into Symfony/Console if exists
240 1
		$this->registerCommandsIntoConsole($builder, $name);
241 1
	}
242
243
244
	/**
245
	 * {@inheritdoc}
246
	 */
247 1
	public function beforeCompile(): void
248
	{
249
		/** @var stdClass $config */
250 1
		$config = (object) $this->config;
251 1
		$name = $config->prefix;
252
253 1
		$builder = $this->getContainerBuilder();
254
255 1
		foreach ($this->classMappings as $source => $target) {
256
			$builder->getDefinition($name . '.resolver')
257
				->addSetup('addResolveTargetEntity', [$source, $target, []]);
258
		}
259
260 1
		$this->processDbalTypes($name, $config->dbal->types);
261 1
		$this->processDbalTypeOverrides($name, $config->dbal->type_overrides);
262 1
		$this->processEventSubscribers($name);
263 1
		$this->processFilters();
264 1
	}
265
266
267
	/**
268
	 * {@inheritdoc}
269
	 */
270 1
	public function afterCompile(ClassType $classType): void
271
	{
272
		/** @var stdClass $config */
273 1
		$config = (object) $this->config;
274 1
		$initialize = $classType->methods['initialize'];
275
276 1
		$initialize->addBody('?::registerUniqueLoader("class_exists");', [new PhpLiteral(AnnotationRegistry::class)]);
0 ignored issues
show
Deprecated Code introduced by
The class Nette\PhpGenerator\PhpLiteral has been deprecated: use Nette\PhpGenerator\Literal ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

276
		$initialize->addBody('?::registerUniqueLoader("class_exists");', [/** @scrutinizer ignore-deprecated */ new PhpLiteral(AnnotationRegistry::class)]);
Loading history...
277
278 1
		if ($config->debug === true) {
279
			$initialize->addBody('$this->getByType(\'' . self::DOCTRINE_SQL_PANEL . '\')->bindToBar();');
280
		}
281
282 1
		$builder = $this->getContainerBuilder();
283 1
		$filterDefinitions = $builder->findByType(SQLFilter::class);
284 1
		if ($filterDefinitions !== []) {
285
			$initialize->addBody(
286
				'$filterCollection = $this->getByType(\'' . EntityManagerInterface::class . '\')->getFilters();'
287
			);
288
			foreach (array_keys($filterDefinitions) as $name) {
289
				$initialize->addBody('$filterCollection->enable(\'' . $name . '\');');
290
			}
291
		}
292 1
	}
293
294
295 1
	protected function processSecondLevelCache(string $name, stdClass $config): void
296
	{
297 1
		if (! $config->enabled) {
298 1
			return;
299
		}
300
301
		$builder = $this->getContainerBuilder();
302
303
		$cacheService = $this->getCache($name . '.secondLevel', $builder, $config->driver);
304
305
		$cacheFactoryId = '@' . $name . '.cacheRegionsConfiguration';
306
		$builder->addDefinition($this->prefix($name . '.cacheFactory'))
307
			->setType(CacheFactory::class)
308
			->setFactory($config->factoryClass, [$this->prefix($cacheFactoryId), $cacheService])
309
			->addSetup('setFileLockRegionDirectory', [$config->fileLockRegionDirectory]);
310
311
		$builder->addDefinition($this->prefix($name . '.cacheRegionsConfiguration'))
312
			->setFactory(RegionsConfiguration::class, [
313
				$config->regions->defaultLifetime,
314
				$config->regions->defaultLockLifetime,
315
			]);
316
317
		$logger = $builder->addDefinition($this->prefix($name . '.cacheLogger'))
318
			->setType(CacheLogger::class)
319
			->setFactory(CacheLoggerChain::class)
320
			->setAutowired(false);
321
322
		if ($config->logging) {
323
			$logger->addSetup('setLogger', ['statistics', new Statement(StatisticsCacheLogger::class)]);
0 ignored issues
show
The call to Nette\DI\Statement::__construct() has too many arguments starting with Doctrine\ORM\Cache\Loggi...sticsCacheLogger::class. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

323
			$logger->addSetup('setLogger', ['statistics', /** @scrutinizer ignore-call */ new Statement(StatisticsCacheLogger::class)]);

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. Please note the @ignore annotation hint above.

Loading history...
Deprecated Code introduced by
The class Nette\DI\Statement has been deprecated: use Nette\DI\Definitions\Statement ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

323
			$logger->addSetup('setLogger', ['statistics', /** @scrutinizer ignore-deprecated */ new Statement(StatisticsCacheLogger::class)]);
Loading history...
324
		}
325
326
		$cacheConfigName = $this->prefix($name . '.ormCacheConfiguration');
327
		$builder->addDefinition($cacheConfigName)
328
			->setType(CacheConfiguration::class)
329
			->addSetup('setCacheFactory', [$this->prefix('@' . $name . '.cacheFactory')])
330
			->addSetup('setCacheLogger', [$this->prefix('@' . $name . '.cacheLogger')])
331
			->setAutowired(false);
332
333
		$configuration = $builder->getDefinitionByType(Configuration::class);
334
		$configuration->addSetup('setSecondLevelCacheEnabled');
335
		$configuration->addSetup('setSecondLevelCacheConfiguration', ['@' . $cacheConfigName]);
336
	}
337
338
339
	/**
340
	 * @throws AssertionException
341
	 */
342 1
	private function parseConfig(): stdClass
343
	{
344
		/** @var stdClass $config */
345 1
		$config = (object) $this->config;
346
347 1
		$this->classMappings = $config->targetEntityMappings;
348 1
		$this->entitySources = $config->metadata;
349
350 1
		foreach ($this->compiler->getExtensions() as $extension) {
351 1
			if ($extension instanceof ClassMappingProviderInterface) {
352
				$entityMapping = $extension->getClassMapping();
353
				Validators::assert($entityMapping, 'array');
354
				$this->classMappings = array_merge($this->classMappings, $entityMapping);
0 ignored issues
show
It seems like $entityMapping can also be of type null; however, parameter $arrays of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

354
				$this->classMappings = array_merge($this->classMappings, /** @scrutinizer ignore-type */ $entityMapping);
Loading history...
355
			}
356
357 1
			if ($extension instanceof EntitySourceProviderInterface) {
358
				$entitySource = $extension->getEntitySource();
359
				Validators::assert($entitySource, 'array');
360
				$this->entitySources = array_merge($this->entitySources, $entitySource);
361
			}
362
		}
363
364 1
		if ($config->sourceDir) {
365 1
			$this->entitySources[] = $config->sourceDir;
366
		}
367
368 1
		return $config;
369
	}
370
371
372 1
	private function getCache(string $prefix, ContainerBuilder $containerBuilder, string $cacheType): string
373
	{
374 1
		if ($containerBuilder->hasDefinition($prefix . '.cache')) {
375 1
			return '@' . $prefix . '.cache';
376
		}
377
378 1
		$config = $this->parseConfig();
379
380 1
		switch ($cacheType) {
381 1
			case 'apcu':
382
				$cacheClass = ApcuCache::class;
383
				break;
384
385 1
			case 'array':
386
				$cacheClass = ArrayCache::class;
387
				break;
388
389 1
			case 'redis':
390
				$cacheClass = $config->cache->redis->class;
391
				break;
392
393 1
			case 'default':
394
			default:
395 1
				$cacheClass = DefaultCache::class;
396 1
				break;
397
		}
398
399 1
		$containerBuilder->addDefinition($prefix . '.cache1')
400 1
			->setType(ArrayCache::class)
401 1
			->setAutowired(false);
402
403 1
		$mainCacheDefinition = $containerBuilder->addDefinition($prefix . '.cache2')
404 1
			->setType($cacheClass)
405 1
			->setAutowired(false);
406
407 1
		$containerBuilder->addDefinition($prefix . '.cache')
408 1
			->setFactory(ChainCache::class, [['@' . $prefix . '.cache1', '@' . $prefix . '.cache2']])
409 1
			->setAutowired(false);
410
411 1
		if ($cacheType === 'redis') {
412
			$redisConfig = $config->cache->redis;
413
414
			$containerBuilder->addDefinition($prefix . '.redis')
415
				->setType('\Redis')
416
				->setAutowired(false)
417
				->addSetup('connect', [
418
					$redisConfig->host ?? '127.0.0.1',
419
					$redisConfig->port ?? null,
420
					$redisConfig->timeout ?? 0.0,
421
					$redisConfig->reserved ?? null,
422
					$redisConfig->retryInterval ?? 0,
423
				])
424
				->addSetup('select', [$redisConfig->database ?? 1]);
425
426
			$mainCacheDefinition->addSetup('setRedis', ['@' . $prefix . '.redis']);
427
		}
428
429 1
		return '@' . $prefix . '.cache';
430
	}
431
432
433 1
	private function registerCommandsIntoConsole(ContainerBuilder $containerBuilder, string $name): void
434
	{
435 1
		if ($this->hasSymfonyConsole()) {
436
			$commands = [
437 1
				ConvertMappingCommand::class,
438
				CreateCommand::class,
439
				DropCommand::class,
440
				GenerateEntitiesCommand::class,
441
				GenerateProxiesCommand::class,
442
				ImportCommand::class,
443
				MetadataCommand::class,
444
				QueryCommand::class,
445
				ResultCommand::class,
446
				UpdateCommand::class,
447
				ValidateSchemaCommand::class,
448
			];
449 1
			foreach ($commands as $index => $command) {
450 1
				$containerBuilder->addDefinition($name . '.command.' . $index)
451 1
					->setType($command);
452
			}
453
454 1
			$helperSets = $containerBuilder->findByType(HelperSet::class);
455 1
			if (! empty($helperSets)) {
456
				/** @var ServiceDefinition $helperSet */
457
				$helperSet = reset($helperSets);
458
				$helperSet->addSetup('set', [new Statement(EntityManagerHelper::class), 'em']);
0 ignored issues
show
The method addSetup() does not exist on Nette\DI\ServiceDefinition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

458
				$helperSet->/** @scrutinizer ignore-call */ 
459
                addSetup('set', [new Statement(EntityManagerHelper::class), 'em']);

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...
The call to Nette\DI\Statement::__construct() has too many arguments starting with Doctrine\ORM\Tools\Conso...ityManagerHelper::class. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

458
				$helperSet->addSetup('set', [/** @scrutinizer ignore-call */ new Statement(EntityManagerHelper::class), 'em']);

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. Please note the @ignore annotation hint above.

Loading history...
Deprecated Code introduced by
The class Nette\DI\Statement has been deprecated: use Nette\DI\Definitions\Statement ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

458
				$helperSet->addSetup('set', [/** @scrutinizer ignore-deprecated */ new Statement(EntityManagerHelper::class), 'em']);
Loading history...
459
			}
460
		}
461 1
	}
462
463
464 1
	private function processDbalTypes(string $name, array $types): void
465
	{
466 1
		$builder = $this->getContainerBuilder();
467 1
		$entityManagerDefinition = $builder->getDefinition($name . '.entityManager');
468
469 1
		foreach ($types as $type => $className) {
470 1
			$entityManagerDefinition->addSetup(
471 1
				'if ( ! Doctrine\DBAL\Types\Type::hasType(?)) { Doctrine\DBAL\Types\Type::addType(?, ?); }',
472 1
				[$type, $type, $className]
473
			);
474
		}
475 1
	}
476
477
478 1
	private function processDbalTypeOverrides(string $name, array $types): void
479
	{
480 1
		$builder = $this->getContainerBuilder();
481 1
		$entityManagerDefinition = $builder->getDefinition($name . '.entityManager');
482
483 1
		foreach ($types as $type => $className) {
484 1
			$entityManagerDefinition->addSetup('Doctrine\DBAL\Types\Type::overrideType(?, ?);', [$type, $className]);
485
		}
486 1
	}
487
488
489 1
	private function processEventSubscribers(string $name): void
490
	{
491 1
		$builder = $this->getContainerBuilder();
492
493 1
		if ($this->hasEventManager($builder)) {
494
			$eventManagerDefinition = $builder->getDefinition((string) $builder->getByType(EventManager::class))
0 ignored issues
show
Are you sure the assignment to $eventManagerDefinition is correct as $builder->getDefinition(.... $name . '.resolver')) targeting Nette\DI\Definitions\Definition::__call() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
495
				->addSetup('addEventListener', [Events::loadClassMetadata, '@' . $name . '.resolver']);
496
		} else {
497 1
			$eventManagerDefinition = $builder->addDefinition($name . '.eventManager')
498 1
				->setType(EventManager::class)
499 1
				->addSetup('addEventListener', [Events::loadClassMetadata, '@' . $name . '.resolver']);
500
		}
501
502 1
		foreach (array_keys($builder->findByType(EventSubscriber::class)) as $serviceName) {
503 1
			$eventManagerDefinition->addSetup('addEventSubscriber', ['@' . $serviceName]);
504
		}
505 1
	}
506
507
508 1
	private function processFilters(): void
509
	{
510 1
		$builder = $this->getContainerBuilder();
511
512 1
		$configurationService = $builder->getDefinitionByType(Configuration::class);
513 1
		foreach ($builder->findByType(SQLFilter::class) as $name => $filterDefinition) {
514
			$configurationService->addSetup('addFilter', [$name, $filterDefinition->getType()]);
515
		}
516 1
	}
517
518
519 1
	private function hasSymfonyConsole(): bool
520
	{
521 1
		return class_exists(Application::class);
522
	}
523
524
525 1
	private function hasEventManager(ContainerBuilder $containerBuilder): bool
526
	{
527 1
		$eventManagerServiceName = $containerBuilder->getByType(EventManager::class);
528 1
		return $eventManagerServiceName !== null && strlen($eventManagerServiceName) > 0;
529
	}
530
531
}
532