diff --git a/.gitignore b/.gitignore
index 7d05333d..02b6ab05 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-vendor
-tests/mysql.local.neon
-composer.lock
+vendor
+tests/mysql.local.neon
+composer.lock
+/nbproject
diff --git a/.travis.yml b/.travis.yml
index dd7569ae..c665bc58 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,9 +14,7 @@ addons:
- mysql
php:
- - 7.1
- - 7.2
- - 7.3
+ - 7.4
env:
- # dev
@@ -26,31 +24,31 @@ env:
matrix:
fast_finish: true
include:
- - php: 7.3
+ - php: 7.4
env: COMPOSER_EXTRA_ARGS="--prefer-stable" COVERAGE="--coverage ./coverage.xml --coverage-src ./src" TESTER_RUNTIME="phpdbg"
- - php: 7.3
+ - php: 7.4
env: COMPOSER_EXTRA_ARGS="--prefer-stable" PHPSTAN=1
exclude:
- - php: 7.3
+ - php: 7.4
env: COMPOSER_EXTRA_ARGS="--prefer-stable"
allow_failures:
- env:
- - php: 7.3
+ - php: 7.4
env: COMPOSER_EXTRA_ARGS="--prefer-stable" COVERAGE="--coverage ./coverage.xml --coverage-src ./src" TESTER_RUNTIME="phpdbg"
install:
- - if [ "$PHPSTAN" = "1" ]; then composer require --dev --no-update phpstan/phpstan-shim:^0.9; fi
+# - if [ "$PHPSTAN" = "1" ]; then composer require --dev --no-update phpstan/phpstan-shim:^0.9; fi
- travis_retry composer update --no-interaction --no-suggest --no-progress --prefer-dist $COMPOSER_EXTRA_ARGS
- - travis_retry composer create-project --no-interaction jakub-onderka/php-parallel-lint /tmp/php-parallel-lint
+# - travis_retry composer create-project --no-interaction php-parallel-lint/PHP-Parallel-Lint /tmp/php-parallel-lint
# - travis_retry composer create-project --no-interaction kdyby/code-checker /tmp/code-checker
- if [ "$COVERAGE" != "" ]; then travis_retry wget -O /tmp/coveralls.phar https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar; fi
script:
- vendor/bin/tester $COVERAGE -s -p ${TESTER_RUNTIME:-php} -c ./tests/php.ini-unix ./tests/KdybyTests/
- - php /tmp/php-parallel-lint/parallel-lint.php -e php,phpt --exclude vendor .
+# - php /tmp/php-parallel-lint/parallel-lint.php -e php,phpt --exclude vendor .
# - php /tmp/code-checker/src/code-checker.php --short-arrays
# - if [ "$PHPSTAN" = "1" ]; then php vendor/phpstan/phpstan-shim/phpstan.phar -v; fi
- - if [ "$PHPSTAN" = "1" ]; then php vendor/phpstan/phpstan-shim/phpstan.phar analyse --ansi --no-progress -l7 -c phpstan.neon src tests/KdybyTests; fi
+# - if [ "$PHPSTAN" = "1" ]; then php vendor/phpstan/phpstan-shim/phpstan.phar analyse --ansi --no-progress -l7 -c phpstan.neon src tests/KdybyTests; fi
after_script:
- if [ "$COVERAGE" != "" ]; then php /tmp/coveralls.phar --verbose --config tests/.coveralls.yml || true; fi
diff --git a/README.md b/README.md
index 1e0ce4b4..bbca861b 100755
--- a/README.md
+++ b/README.md
@@ -1,19 +1,19 @@
-Kdyby/Doctrine
+dek-cz/Doctrine
======
-[](https://travis-ci.org/Kdyby/Doctrine)
-[](https://packagist.org/packages/kdyby/doctrine)
-[](https://packagist.org/packages/kdyby/doctrine)
-[](https://coveralls.io/github/Kdyby/Doctrine?branch=master)
+[](https://travis-ci.com/dek-cz/Doctrine)
+[](https://packagist.org/packages/dek-cz/doctrine)
+[](https://packagist.org/packages/dek-cz/doctrine)
+[](https://coveralls.io/github/dek-cz/doctrine?branch=master)
Installation
------------
-The best way to install Kdyby/Doctrine is using [Composer](http://getcomposer.org/):
+The best way to install dek-cz/Doctrine is using [Composer](http://getcomposer.org/):
```sh
-$ composer require kdyby/doctrine
+$ composer require dek-cz/doctrine
```
Documentation
diff --git a/composer.json b/composer.json
index 88803804..903e2f97 100644
--- a/composer.json
+++ b/composer.json
@@ -1,65 +1,69 @@
{
- "name": "kdyby/doctrine",
- "type": "library",
- "description": "Doctrine integration into Nette Framework",
- "keywords": ["nette", "kdyby", "doctrine", "orm", "dbal"],
- "homepage": "http://kdyby.org",
- "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
- "authors": [
- {
- "name": "Filip Procházka",
- "homepage": "http://filip-prochazka.com",
- "email": "filip@prochazka.su"
- }
- ],
- "support": {
- "email": "filip@prochazka.su",
- "issues": "https://github.com/kdyby/doctrine/issues"
- },
- "require": {
- "php": "^7.1",
- "doctrine/orm": "~2.7",
- "doctrine/dbal": "~2.9",
- "kdyby/console": "^2.7.1",
- "kdyby/annotations": "^3.0",
- "kdyby/doctrine-cache": "^3.0",
- "kdyby/strict-objects": "^2.0",
- "nette/di": "^3.0",
- "nette/utils": "^3.0",
- "nette/finder": "^2.5"
- },
- "suggest": {
- "kdyby/doctrine-magic-accessors": "Fast-prototyping magic accessors trait for Doctrine entities",
- "kdyby/doctrine-collections-readonly": "Read-only collection wrapper for easier work with Doctrine entity collections",
- "kdyby/doctrine-collections-lazy": "Lazy collection for doctrine/collections",
- "kdyby/doctrine-dbal-batchimport": "Batch import & execute utils for effective processing of SQL Imports from files and strings"
- },
- "require-dev": {
- "kdyby/events": "^3.1.1@dev",
- "nette/bootstrap": "^3.0",
- "nette/caching": "^3.0",
- "nette/http": "^3.0",
- "tracy/tracy": "^2.5",
- "nette/tester": "^2.2"
- },
- "minimum-stability": "dev",
- "autoload": {
- "psr-0": {
- "Kdyby\\Doctrine\\": "src/",
- "Kdyby\\Persistence\\": "src/"
+ "name": "dek-cz/doctrine",
+ "type": "library",
+ "description": "Doctrine integration into Nette Framework",
+ "keywords": ["nette", "kdyby", "doctrine", "orm", "dbal"],
+ "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
+ "authors": [
+ {
+ "name": "Filip Procházka",
+ "homepage": "http://filip-prochazka.com",
+ "email": "filip@prochazka.su"
+ }
+ ],
+ "require": {
+ "php": "^7.4 || ^8.0",
+ "psr/cache": "^1.0.1",
+ "doctrine/orm": "^2.7.1",
+ "doctrine/dbal": "~2.10",
+ "doctrine/common": "^2.13",
+ "kdyby/annotations": "^3.0",
+ "kdyby/doctrine-cache": "^3.0",
+ "kdyby/strict-objects": "^2.0",
+ "nette/di": "^3.0",
+ "nette/utils": "^3.0",
+ "nette/finder": "^2.5",
+ "contributte/console": "0.10.x-dev"
+ },
+ "suggest": {
+ "kdyby/doctrine-magic-accessors": "Fast-prototyping magic accessors trait for Doctrine entities",
+ "kdyby/doctrine-collections-readonly": "Read-only collection wrapper for easier work with Doctrine entity collections",
+ "kdyby/doctrine-collections-lazy": "Lazy collection for doctrine/collections",
+ "kdyby/doctrine-dbal-batchimport": "Batch import & execute utils for effective processing of SQL Imports from files and strings"
+ },
+ "require-dev": {
+ "kdyby/events": "^3.1.1@dev",
+ "nette/bootstrap": "^3.0",
+ "nette/caching": "^3.0",
+ "nette/http": "^3.0",
+ "tracy/tracy": "^2.8",
+ "nette/tester": "^2.4",
+ "phpstan/phpstan": "^0.12.69",
+ "phpstan/phpstan-nette": "^0.12.14",
+ "spaze/phpstan-disallowed-calls": "^1.1",
+ "phpunit/php-code-coverage": "^9.2",
+ "php-coveralls/php-coveralls": "^2.4",
+ "ninjify/qa": "^0.12.1",
+ "phpstan/phpstan-strict-rules": "^0.12.9"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-0": {
+ "Kdyby\\Doctrine\\": "src/",
+ "Kdyby\\Persistence\\": "src/"
+ },
+ "classmap": [
+ "src/Kdyby/Doctrine/exceptions.php"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/KdybyTests"
+ ]
},
- "classmap": [
- "src/Kdyby/Doctrine/exceptions.php"
- ]
- },
- "autoload-dev": {
- "classmap": [
- "tests/KdybyTests"
- ]
- },
- "extra": {
- "branch-alias": {
- "dev-master": "4.0-dev"
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
}
- }
}
diff --git a/docs/en/index.md b/docs/en/index.md
index 0992170f..ea35b22b 100644
--- a/docs/en/index.md
+++ b/docs/en/index.md
@@ -19,7 +19,7 @@ and now enable the extension using your neon config
```yml
extensions:
# add theese four lines
- console: Kdyby\Console\DI\ConsoleExtension
+ console: Contributte\Console\DI\ConsoleExtension
events: Kdyby\Events\DI\EventsExtension
annotations: Kdyby\Annotations\DI\AnnotationsExtension
doctrine: Kdyby\Doctrine\DI\OrmExtension
diff --git a/phpstan.neon b/phpstan.neon
index 65020e34..ba95b524 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,3 +1,6 @@
+includes:
+ - vendor/phpstan/phpstan-nette/extension.neon
+ - vendor/phpstan/phpstan-nette/rules.neon
parameters:
ignoreErrors:
- '#Constant TEMP_DIR not found#'
diff --git a/ruleset.xml b/ruleset.xml
new file mode 100644
index 00000000..512060a3
--- /dev/null
+++ b/ruleset.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Kdyby/Doctrine/Configuration.php b/src/Kdyby/Doctrine/Configuration.php
index 47908060..c57ac85b 100644
--- a/src/Kdyby/Doctrine/Configuration.php
+++ b/src/Kdyby/Doctrine/Configuration.php
@@ -23,7 +23,7 @@
class Configuration extends BaseConfiguration
{
- public function getQueryBuilderClassName()
+ public function getQueryBuilderClassName() : string
{
return isset($this->_attributes['queryBuilderClass'])
? $this->_attributes['queryBuilderClass']
@@ -32,21 +32,21 @@ public function getQueryBuilderClassName()
- public function setQueryBuilderClassName($className)
+ public function setQueryBuilderClassName(string $className) : void
{
$this->_attributes['queryBuilderClass'] = $className;
}
- public function setTargetEntityMap($targetEntityMap)
+ public function setTargetEntityMap(array $targetEntityMap) : void
{
$this->_attributes['targetEntityMap'] = $targetEntityMap;
}
- public function getTargetEntityClassName($className)
+ public function getTargetEntityClassName(string $className) : string
{
return isset($this->_attributes['targetEntityMap'], $this->_attributes['targetEntityMap'][$className])
? $this->_attributes['targetEntityMap'][$className]
diff --git a/src/Kdyby/Doctrine/Console/CommandHelper.php b/src/Kdyby/Doctrine/Console/CommandHelper.php
index 8a12cf6f..6a6c8fa7 100644
--- a/src/Kdyby/Doctrine/Console/CommandHelper.php
+++ b/src/Kdyby/Doctrine/Console/CommandHelper.php
@@ -12,7 +12,7 @@
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
-use Kdyby\Console\ContainerHelper;
+use Kdyby\Doctrine\Console\ContainerHelper;
use Symfony\Component\Console\Helper\HelperSet;
/**
diff --git a/src/Kdyby/Doctrine/Console/ContainerHelper.php b/src/Kdyby/Doctrine/Console/ContainerHelper.php
new file mode 100644
index 00000000..4409819f
--- /dev/null
+++ b/src/Kdyby/Doctrine/Console/ContainerHelper.php
@@ -0,0 +1,78 @@
+container = $dic;
+ }
+
+ public function hasParameter(string $key): bool
+ {
+ return isset($this->container->parameters[$key]);
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getParameter(string $key)
+ {
+ if (!$this->hasParameter($key)) {
+ return NULL;
+ }
+
+ return $this->container->parameters[$key];
+ }
+
+ /**
+ * @return mixed[]
+ */
+ public function getParameters(): array
+ {
+ return $this->container->parameters;
+ }
+
+ public function getContainer(): DIContainer
+ {
+ return $this->container;
+ }
+
+ /**
+ * @return object
+ */
+ public function getByType(string $type)
+ {
+ return $this->container->getByType($type);
+ }
+
+ /**
+ * Returns the canonical name of this helper.
+ */
+ public function getName(): string
+ {
+ return 'container';
+ }
+
+}
diff --git a/src/Kdyby/Doctrine/Console/DbalDelegateCommand.php b/src/Kdyby/Doctrine/Console/DbalDelegateCommand.php
index 2aba7c2d..fac43978 100644
--- a/src/Kdyby/Doctrine/Console/DbalDelegateCommand.php
+++ b/src/Kdyby/Doctrine/Console/DbalDelegateCommand.php
@@ -58,8 +58,9 @@ protected function configure()
$this->setHelp($this->command->getHelp());
$this->setDefinition($this->command->getDefinition());
$this->setDescription($this->command->getDescription());
-
- $this->addOption('connection', NULL, InputOption::VALUE_OPTIONAL, 'The connection to use for this command');
+ if (!$this->getDefinition()->hasOption('connection')) {
+ $this->addOption('connection', NULL, InputOption::VALUE_OPTIONAL, 'The connection to use for this command');
+ }
}
/**
diff --git a/src/Kdyby/Doctrine/Console/OrmDelegateCommand.php b/src/Kdyby/Doctrine/Console/OrmDelegateCommand.php
index 00bf7dc0..94922839 100644
--- a/src/Kdyby/Doctrine/Console/OrmDelegateCommand.php
+++ b/src/Kdyby/Doctrine/Console/OrmDelegateCommand.php
@@ -14,6 +14,7 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Kdyby\Doctrine\Tools\CacheCleaner;
/**
* Command Delegate.
@@ -24,65 +25,78 @@
abstract class OrmDelegateCommand extends Command
{
- use \Kdyby\StrictObjects\Scream;
-
- /**
- * @var \Symfony\Component\Console\Command\Command
- */
- protected $command;
-
- /**
- * @return \Symfony\Component\Console\Command\Command
- */
- abstract protected function createCommand();
-
- /**
- * @param string[]|bool|string|null $entityManagerName
- * @return \Symfony\Component\Console\Command\Command
- */
- protected function wrapCommand($entityManagerName)
- {
- CommandHelper::setApplicationEntityManager($this->getHelper('container'), $entityManagerName);
- $this->command->setApplication($this->getApplication());
- return $this->command;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function configure()
- {
- $this->command = $this->createCommand();
-
- $this->setName($this->command->getName());
- $this->setHelp($this->command->getHelp());
- $this->setDefinition($this->command->getDefinition());
- $this->setDescription($this->command->getDescription());
-
- $this->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command');
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- return $this->wrapCommand($input->getOption('em'))->execute($input, $output);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function interact(InputInterface $input, OutputInterface $output)
- {
- $this->wrapCommand($input->getOption('em'))->interact($input, $output);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- $this->wrapCommand($input->getOption('em'))->initialize($input, $output);
- }
+ use \Kdyby\StrictObjects\Scream;
+
+ /**
+ * @var \Symfony\Component\Console\Command\Command
+ */
+ protected $command;
+
+ /**
+ * @var CacheCleaner
+ */
+ public $cacheCleaner;
+
+ public function __construct(CacheCleaner $cacheCleaner)
+ {
+ parent::__construct();
+ $this->cacheCleaner = $cacheCleaner;
+ }
+
+ /**
+ * @return \Symfony\Component\Console\Command\Command
+ */
+ abstract protected function createCommand();
+
+ /**
+ * @param string[]|bool|string|null $entityManagerName
+ * @return \Symfony\Component\Console\Command\Command
+ */
+ protected function wrapCommand($entityManagerName)
+ {
+ CommandHelper::setApplicationEntityManager($this->getHelper('container'), $entityManagerName);
+ $this->command->setApplication($this->getApplication());
+ return $this->command;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure()
+ {
+ $this->command = $this->createCommand();
+
+ $this->setName($this->command->getName());
+ $this->setHelp($this->command->getHelp());
+ $this->setDefinition($this->command->getDefinition());
+ $this->setDescription($this->command->getDescription());
+ if (!$this->getDefinition()->hasOption('em')) {
+ $this->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command');
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ return $this->wrapCommand($input->getOption('em'))->execute($input, $output);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $this->wrapCommand($input->getOption('em'))->interact($input, $output);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ $this->wrapCommand($input->getOption('em'))->initialize($input, $output);
+ }
+
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/ConvertMappingCommand.php b/src/Kdyby/Doctrine/Console/Proxy/ConvertMappingCommand.php
index 23e4427b..18cd6a39 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/ConvertMappingCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/ConvertMappingCommand.php
@@ -20,27 +20,16 @@
class ConvertMappingCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/GenerateEntitiesCommand.php b/src/Kdyby/Doctrine/Console/Proxy/GenerateEntitiesCommand.php
index a080b008..c5940119 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/GenerateEntitiesCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/GenerateEntitiesCommand.php
@@ -26,10 +26,6 @@ class GenerateEntitiesCommand extends OrmDelegateCommand
*/
public $cacheCleaner;
- public function __construct()
- {
- parent::__construct();
- }
protected function initialize(InputInterface $input, OutputInterface $output)
{
diff --git a/src/Kdyby/Doctrine/Console/Proxy/GenerateProxiesCommand.php b/src/Kdyby/Doctrine/Console/Proxy/GenerateProxiesCommand.php
index b8905798..e6ae9e2e 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/GenerateProxiesCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/GenerateProxiesCommand.php
@@ -20,16 +20,6 @@
class GenerateProxiesCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
protected function initialize(InputInterface $input, OutputInterface $output)
{
diff --git a/src/Kdyby/Doctrine/Console/Proxy/InfoCommand.php b/src/Kdyby/Doctrine/Console/Proxy/InfoCommand.php
index 9918be6a..4de076bf 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/InfoCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/InfoCommand.php
@@ -20,27 +20,16 @@
class InfoCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\InfoCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\InfoCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/SchemaCreateCommand.php b/src/Kdyby/Doctrine/Console/Proxy/SchemaCreateCommand.php
index 70fbc9c3..643f9cdb 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/SchemaCreateCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/SchemaCreateCommand.php
@@ -20,27 +20,16 @@
class SchemaCreateCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/SchemaDropCommand.php b/src/Kdyby/Doctrine/Console/Proxy/SchemaDropCommand.php
index 34b24350..7896e977 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/SchemaDropCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/SchemaDropCommand.php
@@ -20,27 +20,16 @@
class SchemaDropCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/SchemaUpdateCommand.php b/src/Kdyby/Doctrine/Console/Proxy/SchemaUpdateCommand.php
index d4071c2a..6da35460 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/SchemaUpdateCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/SchemaUpdateCommand.php
@@ -20,27 +20,16 @@
class SchemaUpdateCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/Console/Proxy/ValidateSchemaCommand.php b/src/Kdyby/Doctrine/Console/Proxy/ValidateSchemaCommand.php
index a4eebcbb..a198249a 100644
--- a/src/Kdyby/Doctrine/Console/Proxy/ValidateSchemaCommand.php
+++ b/src/Kdyby/Doctrine/Console/Proxy/ValidateSchemaCommand.php
@@ -20,27 +20,16 @@
class ValidateSchemaCommand extends OrmDelegateCommand
{
- /**
- * @var \Kdyby\Doctrine\Tools\CacheCleaner
- * @inject
- */
- public $cacheCleaner;
-
- public function __construct()
- {
- parent::__construct();
- }
-
- protected function initialize(InputInterface $input, OutputInterface $output)
- {
- parent::initialize($input, $output);
-
- $this->cacheCleaner->invalidate();
- }
-
- protected function createCommand()
- {
- return new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand();
- }
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ parent::initialize($input, $output);
+
+ $this->cacheCleaner->invalidate();
+ }
+
+ protected function createCommand()
+ {
+ return new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand();
+ }
}
diff --git a/src/Kdyby/Doctrine/DI/OrmExtension.php b/src/Kdyby/Doctrine/DI/OrmExtension.php
index daa84659..1d11298b 100644
--- a/src/Kdyby/Doctrine/DI/OrmExtension.php
+++ b/src/Kdyby/Doctrine/DI/OrmExtension.php
@@ -28,6 +28,7 @@
use Kdyby\Annotations\DI\AnnotationsExtension;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
+use Kdyby\Doctrine\Console\ContainerHelper;
/**
* @author Filip Procházka
@@ -35,864 +36,835 @@
class OrmExtension extends Nette\DI\CompilerExtension
{
- const ANNOTATION_DRIVER = 'annotations';
- const PHP_NAMESPACE = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff\\\\]*';
- const TAG_CONNECTION = 'doctrine.connection';
- const TAG_ENTITY_MANAGER = 'doctrine.entityManager';
- const TAG_BIND_TO_MANAGER = 'doctrine.bindToManager';
- const TAG_REPOSITORY_ENTITY = 'doctrine.repositoryEntity';
- const DEFAULT_PROXY_NAMESPACE = 'Kdyby\GeneratedProxy';
- const KDYBY_METADATA_NAMESPACE = 'Kdyby\Doctrine';
-
- /**
- * @var array
- */
- public $managerDefaults = [
- 'metadataCache' => 'default',
- 'queryCache' => 'default',
- 'resultCache' => 'default',
- 'hydrationCache' => 'default',
- 'secondLevelCache' => [
- 'enabled' => FALSE,
- 'factoryClass' => Doctrine\ORM\Cache\DefaultCacheFactory::class,
- 'driver' => 'default',
- 'regions' => [
- 'defaultLifetime' => 3600,
- 'defaultLockLifetime' => 60,
- ],
- 'fileLockRegionDirectory' => '%tempDir%/cache/Doctrine.Cache.Locks', // todo fix
- 'logging' => '%debugMode%',
- ],
- 'classMetadataFactory' => Kdyby\Doctrine\Mapping\ClassMetadataFactory::class,
- 'defaultRepositoryClassName' => Kdyby\Doctrine\EntityRepository::class,
- 'repositoryFactoryClassName' => Kdyby\Doctrine\RepositoryFactory::class,
- 'queryBuilderClassName' => Kdyby\Doctrine\QueryBuilder::class,
- 'autoGenerateProxyClasses' => '%debugMode%',
- 'namingStrategy' => Doctrine\ORM\Mapping\UnderscoreNamingStrategy::class,
- 'quoteStrategy' => Doctrine\ORM\Mapping\DefaultQuoteStrategy::class,
- 'entityListenerResolver' => Kdyby\Doctrine\Mapping\EntityListenerResolver::class,
- 'proxyDir' => '%tempDir%/proxies',
- 'proxyNamespace' => self::DEFAULT_PROXY_NAMESPACE,
- 'dql' => ['string' => [], 'numeric' => [], 'datetime' => [], 'hints' => []],
- 'hydrators' => [],
- 'metadata' => [],
- 'filters' => [],
- 'namespaceAlias' => [],
- 'targetEntityMappings' => [],
- ];
-
- /**
- * @var array
- */
- public $connectionDefaults = [
- 'dbname' => NULL,
- 'host' => '127.0.0.1',
- 'port' => NULL,
- 'user' => NULL,
- 'password' => NULL,
- 'charset' => 'UTF8',
- 'driver' => 'pdo_mysql',
- 'driverClass' => NULL,
- 'options' => NULL,
- 'path' => NULL,
- 'memory' => NULL,
- 'unix_socket' => NULL,
- 'logging' => '%debugMode%',
- 'platformService' => NULL,
- 'defaultTableOptions' => [],
- 'resultCache' => 'default',
- 'types' => [],
- 'schemaFilter' => NULL,
- ];
-
- /**
- * @var array
- */
- public $metadataDriverClasses = [
- self::ANNOTATION_DRIVER => Doctrine\ORM\Mapping\Driver\AnnotationDriver::class,
- 'static' => Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver::class,
- 'yml' => Doctrine\ORM\Mapping\Driver\YamlDriver::class,
- 'yaml' => Doctrine\ORM\Mapping\Driver\YamlDriver::class,
- 'xml' => Doctrine\ORM\Mapping\Driver\XmlDriver::class,
- 'db' => Doctrine\ORM\Mapping\Driver\DatabaseDriver::class,
- ];
-
- /**
- * @var array
- */
- private $proxyAutoloaders = [];
-
- /**
- * @var array
- */
- private $targetEntityMappings = [];
-
- /**
- * @var array
- */
- private $configuredManagers = [];
-
- /**
- * @var array
- */
- private $managerConfigs = [];
-
- /**
- * @var array
- */
- private $configuredConnections = [];
-
-
-
- public function loadConfiguration()
- {
- $this->proxyAutoloaders =
- $this->targetEntityMappings =
- $this->configuredConnections =
- $this->managerConfigs =
- $this->configuredManagers = [];
-
- if (!$this->compiler->getExtensions(AnnotationsExtension::class)) {
- throw new Nette\Utils\AssertionException(sprintf("You should register %s before %s.", AnnotationsExtension::class, get_class($this)));
- }
-
- $builder = $this->getContainerBuilder();
- $config = $this->getConfig();
-
- $builder->parameters[$this->prefix('debug')] = !empty($config['debug']);
- if (isset($config['dbname']) || isset($config['driver']) || isset($config['connection'])) {
- $config = ['default' => $config];
- $defaults = ['debug' => $builder->parameters['debugMode']];
-
- } else {
- $defaults = array_intersect_key($config, $this->managerDefaults)
- + array_intersect_key($config, $this->connectionDefaults)
- + ['debug' => $builder->parameters['debugMode']];
-
- $config = array_diff_key($config, $defaults);
- }
-
- if (empty($config)) {
- throw new Kdyby\Doctrine\UnexpectedValueException("Please configure the Doctrine extensions using the section '{$this->name}:' in your config file.");
- }
-
- foreach ($config as $name => $emConfig) {
- if (!is_array($emConfig) || (empty($emConfig['dbname']) && empty($emConfig['driver']))) {
- throw new Kdyby\Doctrine\UnexpectedValueException("Please configure the Doctrine extensions using the section '{$this->name}:' in your config file.");
- }
-
- /** @var mixed[] $emConfig */
- $emConfig = Nette\DI\Config\Helpers::merge($emConfig, $defaults);
- $this->processEntityManager($name, $emConfig);
- }
-
- if ($this->targetEntityMappings) {
- if (!$this->isKdybyEventsPresent()) {
- throw new Nette\Utils\AssertionException('The option \'targetEntityMappings\' requires \'Kdyby\Events\DI\EventsExtension\'.', E_USER_NOTICE);
- }
-
- $listener = $builder->addDefinition($this->prefix('resolveTargetEntityListener'))
- ->setClass(Kdyby\Doctrine\Tools\ResolveTargetEntityListener::class)
- ->addTag(Kdyby\Events\DI\EventsExtension::TAG_SUBSCRIBER);
-
- foreach ($this->targetEntityMappings as $originalEntity => $mapping) {
- $listener->addSetup('addResolveTargetEntity', [$originalEntity, $mapping['targetEntity'], $mapping]);
- }
- }
-
- $this->loadConsole();
-
- $builder->addDefinition($this->prefix('registry'))
- ->setFactory(Kdyby\Doctrine\Registry::class, [
- $this->configuredConnections,
- $this->configuredManagers,
- $builder->parameters[$this->name]['dbal']['defaultConnection'],
- $builder->parameters[$this->name]['orm']['defaultEntityManager'],
- ]);
- }
-
-
-
- protected function loadConsole()
- {
- $builder = $this->getContainerBuilder();
-
- foreach ($this->loadFromFile(__DIR__ . '/console.neon') as $i => $command) {
- $cli = $builder->addDefinition($this->prefix('cli.' . $i))
- ->addTag(Kdyby\Console\DI\ConsoleExtension::TAG_COMMAND)
- ->addTag(Nette\DI\Extensions\InjectExtension::TAG_INJECT, FALSE); // lazy injects
-
- if (is_string($command)) {
- $cli->setClass($command);
-
- } else {
- throw new Kdyby\Doctrine\NotSupportedException;
- }
- }
- }
-
-
-
- protected function processEntityManager($name, array $defaults)
- {
- $builder = $this->getContainerBuilder();
- $config = $this->resolveConfig($defaults, $this->managerDefaults, $this->connectionDefaults);
-
- if ($isDefault = !isset($builder->parameters[$this->name]['orm']['defaultEntityManager'])) {
- $builder->parameters[$this->name]['orm']['defaultEntityManager'] = $name;
- }
-
- $metadataDriver = $builder->addDefinition($this->prefix($name . '.metadataDriver'))
- ->setClass(Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain::class)
- ->setAutowired(FALSE);
- /** @var \Nette\DI\ServiceDefinition $metadataDriver */
-
- Validators::assertField($config, 'metadata', 'array');
- Validators::assertField($config, 'targetEntityMappings', 'array');
- $config['targetEntityMappings'] = $this->normalizeTargetEntityMappings($config['targetEntityMappings']);
- foreach ($this->compiler->getExtensions() as $extension) {
- if ($extension instanceof IEntityProvider) {
- $metadata = $extension->getEntityMappings();
- Validators::assert($metadata, 'array');
- foreach ($metadata as $namespace => $nsConfig) {
- if (array_key_exists($namespace, $config['metadata'])) {
- throw new Nette\Utils\AssertionException(sprintf('The namespace %s is already configured, provider cannot change it', $namespace));
- }
- $config['metadata'][$namespace] = $nsConfig;
- }
- }
-
- if ($extension instanceof ITargetEntityProvider) {
- $targetEntities = $extension->getTargetEntityMappings();
- Validators::assert($targetEntities, 'array');
- $config['targetEntityMappings'] = Nette\Utils\Arrays::mergeTree($config['targetEntityMappings'], $this->normalizeTargetEntityMappings($targetEntities));
- }
-
- if ($extension instanceof IDatabaseTypeProvider) {
- $providedTypes = $extension->getDatabaseTypes();
- Validators::assert($providedTypes, 'array');
-
- if (!isset($defaults['types'])) {
- $defaults['types'] = [];
- }
-
- $defaults['types'] = array_merge($defaults['types'], $providedTypes);
- }
- }
-
- foreach (self::natSortKeys($config['metadata']) as $namespace => $driver) {
- $this->processMetadataDriver($metadataDriver, $namespace, $driver, $name);
- }
-
- $this->processMetadataDriver($metadataDriver, self::KDYBY_METADATA_NAMESPACE, __DIR__ . '/../Entities', $name);
-
- if (empty($config['metadata'])) {
- $metadataDriver->addSetup('setDefaultDriver', [
- new Statement($this->metadataDriverClasses[self::ANNOTATION_DRIVER], [
- '@' . Doctrine\Common\Annotations\Reader::class,
- [Nette\DI\Helpers::expand('%appDir%', $builder->parameters)]
- ])
- ]);
- }
-
- if ($config['repositoryFactoryClassName'] === 'default') {
- $config['repositoryFactoryClassName'] = DefaultRepositoryFactory::class;
- }
- $builder->addDefinition($this->prefix($name . '.repositoryFactory'))
- ->setClass($config['repositoryFactoryClassName'])
- ->setAutowired(FALSE);
-
- Validators::assertField($config, 'namespaceAlias', 'array');
- Validators::assertField($config, 'hydrators', 'array');
- Validators::assertField($config, 'dql', 'array');
- Validators::assertField($config['dql'], 'string', 'array');
- Validators::assertField($config['dql'], 'numeric', 'array');
- Validators::assertField($config['dql'], 'datetime', 'array');
- Validators::assertField($config['dql'], 'hints', 'array');
-
- $autoGenerateProxyClasses = is_bool($config['autoGenerateProxyClasses'])
- ? ($config['autoGenerateProxyClasses'] ? AbstractProxyFactory::AUTOGENERATE_ALWAYS : AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS)
- : $config['autoGenerateProxyClasses'];
-
- $configuration = $builder->addDefinition($this->prefix($name . '.ormConfiguration'))
- ->setClass(Kdyby\Doctrine\Configuration::class)
- ->addSetup('setMetadataCacheImpl', [$this->processCache($config['metadataCache'], $name . '.metadata')])
- ->addSetup('setQueryCacheImpl', [$this->processCache($config['queryCache'], $name . '.query')])
- ->addSetup('setResultCacheImpl', [$this->processCache($config['resultCache'], $name . '.ormResult')])
- ->addSetup('setHydrationCacheImpl', [$this->processCache($config['hydrationCache'], $name . '.hydration')])
- ->addSetup('setMetadataDriverImpl', [$this->prefix('@' . $name . '.metadataDriver')])
- ->addSetup('setClassMetadataFactoryName', [$config['classMetadataFactory']])
- ->addSetup('setDefaultRepositoryClassName', [$config['defaultRepositoryClassName']])
- ->addSetup('setQueryBuilderClassName', [$config['queryBuilderClassName']])
- ->addSetup('setRepositoryFactory', [$this->prefix('@' . $name . '.repositoryFactory')])
- ->addSetup('setProxyDir', [$config['proxyDir']])
- ->addSetup('setProxyNamespace', [$config['proxyNamespace']])
- ->addSetup('setAutoGenerateProxyClasses', [$autoGenerateProxyClasses])
- ->addSetup('setEntityNamespaces', [$config['namespaceAlias']])
- ->addSetup('setCustomHydrationModes', [$config['hydrators']])
- ->addSetup('setCustomStringFunctions', [$config['dql']['string']])
- ->addSetup('setCustomNumericFunctions', [$config['dql']['numeric']])
- ->addSetup('setCustomDatetimeFunctions', [$config['dql']['datetime']])
- ->addSetup('setDefaultQueryHints', [$config['dql']['hints']])
- ->addSetup('setNamingStrategy', CacheHelpers::filterArgs($config['namingStrategy']))
- ->addSetup('setQuoteStrategy', CacheHelpers::filterArgs($config['quoteStrategy']))
- ->addSetup('setEntityListenerResolver', CacheHelpers::filterArgs($config['entityListenerResolver']))
- ->setAutowired(FALSE);
- /** @var Nette\DI\ServiceDefinition $configuration */
-
- $this->proxyAutoloaders[$config['proxyNamespace']] = $config['proxyDir'];
-
- $this->processSecondLevelCache($name, $config['secondLevelCache'], $isDefault);
-
- Validators::assertField($config, 'filters', 'array');
- foreach ($config['filters'] as $filterName => $filterClass) {
- $configuration->addSetup('addFilter', [$filterName, $filterClass]);
- }
-
- if ($config['targetEntityMappings']) {
- $configuration->addSetup('setTargetEntityMap', [array_map(function ($mapping) {
- return $mapping['targetEntity'];
- }, $config['targetEntityMappings'])]);
- $this->targetEntityMappings = Nette\Utils\Arrays::mergeTree($this->targetEntityMappings, $config['targetEntityMappings']);
- }
-
- if ($this->isKdybyEventsPresent()) {
- $builder->addDefinition($this->prefix($name . '.evm'))
- ->setFactory(Kdyby\Events\NamespacedEventManager::class, [Kdyby\Doctrine\Events::NS . '::'])
- ->addSetup('$dispatchGlobalEvents', [TRUE]) // for BC
- ->setAutowired(FALSE);
-
- } else {
- $builder->addDefinition($this->prefix($name . '.evm'))
- ->setClass('Doctrine\Common\EventManager')
- ->setAutowired(FALSE);
- }
-
- // entity manager
- $entityManager = $builder->addDefinition($managerServiceId = $this->prefix($name . '.entityManager'))
- ->setClass(Kdyby\Doctrine\EntityManager::class)
- ->setFactory(Kdyby\Doctrine\EntityManager::class . '::create', [
- $connectionService = $this->processConnection($name, $defaults, $isDefault),
- $this->prefix('@' . $name . '.ormConfiguration'),
- $this->prefix('@' . $name . '.evm'),
- ])
- ->addTag(self::TAG_ENTITY_MANAGER)
- ->addTag('kdyby.doctrine.entityManager')
- ->setAutowired($isDefault);
-
- if ($this->isTracyPresent()) {
- $entityManager->addSetup('?->bindEntityManager(?)', [$this->prefix('@' . $name . '.diagnosticsPanel'), '@self']);
- }
-
- $builder->addFactoryDefinition($this->prefix('repositoryFactory.' . $name . '.defaultRepositoryFactory'))
- ->setImplement(IRepositoryFactory::class)
- ->setParameters([EntityManagerInterface::class . ' entityManager', Doctrine\ORM\Mapping\ClassMetadata::class . ' classMetadata'])
- ->getResultDefinition()
- ->setFactory($config['defaultRepositoryClassName'])
- ->setArguments([new Code\PhpLiteral('$entityManager'), new Code\PhpLiteral('$classMetadata')])
- ->setAutowired(FALSE);
-
- $builder->addDefinition($this->prefix($name . '.schemaValidator'))
- ->setFactory(Doctrine\ORM\Tools\SchemaValidator::class, ['@' . $managerServiceId])
- ->setAutowired($isDefault);
-
- $builder->addDefinition($this->prefix($name . '.schemaTool'))
- ->setFactory(Doctrine\ORM\Tools\SchemaTool::class, ['@' . $managerServiceId])
- ->setAutowired($isDefault);
-
- $cacheCleaner = $builder->addDefinition($this->prefix($name . '.cacheCleaner'))
- ->setFactory(Kdyby\Doctrine\Tools\CacheCleaner::class, ['@' . $managerServiceId])
- ->setAutowired($isDefault);
-
- $builder->addDefinition($this->prefix($name . '.schemaManager'))
- ->setClass(AbstractSchemaManager::class)
- ->setFactory('@' . Kdyby\Doctrine\Connection::class . '::getSchemaManager')
- ->setAutowired($isDefault);
-
- foreach ($this->compiler->getExtensions(AnnotationsExtension::class) as $extension) {
- /** @var AnnotationsExtension $extension */
- $cacheCleaner->addSetup('addCacheStorage', [$extension->prefix('@cache.annotations')]);
- }
-
- if ($isDefault) {
- $builder->addDefinition($this->prefix('helper.entityManager'))
- ->setFactory(EntityManagerHelper::class, ['@' . $managerServiceId])
- ->addTag(Kdyby\Console\DI\ConsoleExtension::HELPER_TAG, 'em');
-
- $builder->addDefinition($this->prefix('helper.connection'))
- ->setFactory(ConnectionHelper::class, [$connectionService])
- ->addTag(Kdyby\Console\DI\ConsoleExtension::HELPER_TAG, 'db');
-
- $builder->addAlias($this->prefix('schemaValidator'), $this->prefix($name . '.schemaValidator'));
- $builder->addAlias($this->prefix('schemaTool'), $this->prefix($name . '.schemaTool'));
- $builder->addAlias($this->prefix('cacheCleaner'), $this->prefix($name . '.cacheCleaner'));
- $builder->addAlias($this->prefix('schemaManager'), $this->prefix($name . '.schemaManager'));
- }
-
- $this->configuredManagers[$name] = $managerServiceId;
- $this->managerConfigs[$name] = $config;
- }
-
-
-
- protected function processSecondLevelCache($name, array $config, $isDefault)
- {
- if (!$config['enabled']) {
- return;
- }
-
- $builder = $this->getContainerBuilder();
-
- $cacheFactory = $builder->addDefinition($this->prefix($name . '.cacheFactory'))
- ->setClass(Doctrine\ORM\Cache\CacheFactory::class)
- ->setFactory($config['factoryClass'], [
- $this->prefix('@' . $name . '.cacheRegionsConfiguration'),
- $this->processCache($config['driver'], $name . '.secondLevel'),
- ])
- ->setAutowired($isDefault);
-
- if ($config['factoryClass'] === $this->managerDefaults['secondLevelCache']['factoryClass']
- || is_subclass_of($config['factoryClass'], $this->managerDefaults['secondLevelCache']['factoryClass'])
- ) {
- $cacheFactory->addSetup('setFileLockRegionDirectory', [$config['fileLockRegionDirectory']]);
- }
-
- $builder->addDefinition($this->prefix($name . '.cacheRegionsConfiguration'))
- ->setClass(Doctrine\ORM\Cache\RegionsConfiguration::class, [
- $config['regions']['defaultLifetime'],
- $config['regions']['defaultLockLifetime'],
- ])
- ->setAutowired($isDefault);
-
- $logger = $builder->addDefinition($this->prefix($name . '.cacheLogger'))
- ->setClass(Doctrine\ORM\Cache\Logging\CacheLogger::class)
- ->setFactory(Doctrine\ORM\Cache\Logging\CacheLoggerChain::class)
- ->setAutowired(FALSE);
-
- if ($config['logging']) {
- $logger->addSetup('setLogger', [
- 'statistics',
- new Statement(Doctrine\ORM\Cache\Logging\StatisticsCacheLogger::class)
- ]);
- }
-
- $builder->addDefinition($cacheConfigName = $this->prefix($name . '.ormCacheConfiguration'))
- ->setClass(Doctrine\ORM\Cache\CacheConfiguration::class)
- ->addSetup('setCacheFactory', [$this->prefix('@' . $name . '.cacheFactory')])
- ->addSetup('setCacheLogger', [$this->prefix('@' . $name . '.cacheLogger')])
- ->setAutowired($isDefault);
-
- $this->getServiceDefinition($builder, $this->prefix($name . '.ormConfiguration'))
- ->addSetup('setSecondLevelCacheEnabled')
- ->addSetup('setSecondLevelCacheConfiguration', ['@' . $cacheConfigName]);
- }
-
-
-
- protected function processConnection($name, array $defaults, $isDefault = FALSE)
- {
- $builder = $this->getContainerBuilder();
- $config = $this->resolveConfig($defaults, $this->connectionDefaults, $this->managerDefaults);
-
- if ($isDefault) {
- $builder->parameters[$this->name]['dbal']['defaultConnection'] = $name;
- }
-
- if (isset($defaults['connection'])) {
- return $this->prefix('@' . $defaults['connection'] . '.connection');
- }
-
- // config
- $configuration = $builder->addDefinition($this->prefix($name . '.dbalConfiguration'))
- ->setClass(Doctrine\DBAL\Configuration::class)
- ->addSetup('setResultCacheImpl', [$this->processCache($config['resultCache'], $name . '.dbalResult')])
- ->addSetup('setSQLLogger', [new Statement(Doctrine\DBAL\Logging\LoggerChain::class)])
- ->addSetup('setFilterSchemaAssetsExpression', [$config['schemaFilter']])
- ->setAutowired(FALSE);
-
- // types
- Validators::assertField($config, 'types', 'array');
- $schemaTypes = $dbalTypes = [];
- foreach ($config['types'] as $dbType => $className) {
- /** @var Doctrine\DBAL\Types\Type $typeInst */
- $typeInst = Code\Helpers::createObject($className, []);
- $dbalTypes[$typeInst->getName()] = $className;
- $schemaTypes[$dbType] = $typeInst->getName();
- }
-
- // tracy panel
- if ($this->isTracyPresent()) {
- $builder->addDefinition($this->prefix($name . '.diagnosticsPanel'))
- ->setClass(Kdyby\Doctrine\Diagnostics\Panel::class)
- ->setAutowired(FALSE);
- }
-
- // connection
- $options = array_diff_key($config, array_flip(['types', 'resultCache', 'connection', 'logging']));
- $connection = $builder->addDefinition($connectionServiceId = $this->prefix($name . '.connection'))
- ->setClass(Kdyby\Doctrine\Connection::class)
- ->setFactory(Kdyby\Doctrine\Connection::class . '::create', [
- $options,
- $this->prefix('@' . $name . '.dbalConfiguration'),
- $this->prefix('@' . $name . '.evm'),
- ])
- ->addSetup('setSchemaTypes', [$schemaTypes])
- ->addSetup('setDbalTypes', [$dbalTypes])
- ->addTag(self::TAG_CONNECTION)
- ->addTag('kdyby.doctrine.connection')
- ->setAutowired($isDefault);
-
- if ($this->isTracyPresent()) {
- $connection->addSetup('$panel = ?->bindConnection(?)', [$this->prefix('@' . $name . '.diagnosticsPanel'), '@self']);
- }
-
- /** @var Nette\DI\ServiceDefinition $connection */
-
- $this->configuredConnections[$name] = $connectionServiceId;
-
- if (!is_bool($config['logging'])) {
- $fileLogger = new Statement(Kdyby\Doctrine\Diagnostics\FileLogger::class, [Nette\DI\Helpers::expand($config['logging'], $builder->parameters)]);
- $configuration->addSetup('$service->getSQLLogger()->addLogger(?)', [$fileLogger]);
-
- } elseif ($config['logging']) {
- $connection->addSetup('?->enableLogging()', [new Code\PhpLiteral('$panel')]);
- }
-
- return $this->prefix('@' . $name . '.connection');
- }
-
-
-
- /**
- * @param \Nette\DI\ServiceDefinition $metadataDriver
- * @param string $namespace
- * @param string|array|\stdClass $driver
- * @param string $prefix
- * @throws \Nette\Utils\AssertionException
- * @return string
- */
- protected function processMetadataDriver(Nette\DI\ServiceDefinition $metadataDriver, $namespace, $driver, $prefix)
- {
- if (!is_string($namespace) || !Strings::match($namespace, '#^' . self::PHP_NAMESPACE . '\z#')) {
- throw new Nette\Utils\AssertionException("The metadata namespace expects to be valid namespace, $namespace given.");
- }
- $namespace = ltrim($namespace, '\\');
-
- if (is_string($driver) && strpos($driver, '@') === 0) { // service reference
- $metadataDriver->addSetup('addDriver', [$driver, $namespace]);
- return $driver;
- }
-
- if (is_string($driver) || is_array($driver)) {
- $paths = is_array($driver) ? $driver : [$driver];
- foreach ($paths as $path) {
- if (!file_exists($path)) {
- throw new Nette\Utils\AssertionException("The metadata path expects to be an existing directory, $path given.");
- }
- }
-
- $driver = new Statement(self::ANNOTATION_DRIVER, is_array($paths) ? $paths : [$paths]);
- }
-
- $impl = $driver instanceof \stdClass ? $driver->value : ($driver instanceof Statement ? $driver->getEntity() : (string) $driver);
- list($driver) = CacheHelpers::filterArgs($driver);
- /** @var Statement $driver */
-
- /** @var string $impl */
- if (isset($this->metadataDriverClasses[$impl])) {
- $driver = new Statement($this->metadataDriverClasses[$impl], $driver->arguments);
- }
-
- if (is_string($driver->getEntity()) && substr($driver->getEntity(), 0, 1) === '@') {
- $metadataDriver->addSetup('addDriver', [$driver->getEntity(), $namespace]);
- return $driver->getEntity();
- }
-
- if ($impl === self::ANNOTATION_DRIVER) {
- $driver->arguments = [
- '@' . Doctrine\Common\Annotations\Reader::class,
- Nette\Utils\Arrays::flatten($driver->arguments)
- ];
- }
-
- $serviceName = $this->prefix($prefix . '.driver.' . str_replace('\\', '_', $namespace) . '.' . str_replace('\\', '_', $impl) . 'Impl');
-
- $this->getContainerBuilder()->addDefinition($serviceName)
- ->setClass(Doctrine\Common\Persistence\Mapping\Driver\MappingDriver::class)
- ->setFactory($driver->getEntity(), $driver->arguments)
- ->setAutowired(FALSE);
-
- $metadataDriver->addSetup('addDriver', ['@' . $serviceName, $namespace]);
- return '@' . $serviceName;
- }
-
-
-
- /**
- * @param string|\stdClass $cache
- * @param string $suffix
- * @return string
- */
- protected function processCache($cache, $suffix)
- {
- return CacheHelpers::processCache($this, $cache, $suffix, $this->getContainerBuilder()->parameters[$this->prefix('debug')]);
- }
-
-
-
- public function beforeCompile()
- {
- $this->processRepositories();
- $this->processEventManagers();
- }
-
-
-
- protected function processRepositories()
- {
- $builder = $this->getContainerBuilder();
-
- $disabled = TRUE;
- foreach ($this->configuredManagers as $managerName => $_) {
- $factoryClassName = $builder->getDefinition($this->prefix($managerName . '.repositoryFactory'))->getClass();
- if ($factoryClassName === Kdyby\Doctrine\RepositoryFactory::class || in_array(Kdyby\Doctrine\RepositoryFactory::class, class_parents($factoryClassName), TRUE)) {
- $disabled = FALSE;
- }
- }
-
- if ($disabled) {
- return;
- }
-
- if (!method_exists($builder, 'findByType')) {
- foreach ($this->configuredManagers as $managerName => $_) {
- $this->getServiceDefinition($builder, $this->prefix($managerName . '.repositoryFactory'))
- ->addSetup('setServiceIdsMap', [[], $this->prefix('repositoryFactory.' . $managerName . '.defaultRepositoryFactory')]);
- }
-
- return;
- }
-
- $serviceMap = array_fill_keys(array_keys($this->configuredManagers), []);
-
- /**
- * @var Nette\DI\ServiceDefinition $originalDef
- */
- foreach ($builder->findByType(Doctrine\ORM\EntityRepository::class) as $originalServiceName => $originalDef) {
- if (strpos($originalServiceName, $this->name . '.') === 0) {
- continue; // ignore
- }
-
- $originalDefFactory = $originalDef->getFactory();
- $factory = !empty($originalDefFactory) ? $originalDefFactory->getEntity() : $originalDef->getClass();
-
- if ((is_string($factory) && stripos($factory, '::getRepository') !== FALSE)
- || (is_array($factory) && array_search('::getRepository', $factory) === FALSE)) {
- continue; // ignore
- }
- $factoryServiceName = $this->prefix('repositoryFactory.' . $originalServiceName);
- $factoryDef = $builder->addFactoryDefinition($factoryServiceName)
- ->setImplement(IRepositoryFactory::class)
- ->setParameters([Doctrine\ORM\EntityManagerInterface::class . ' entityManager', Doctrine\ORM\Mapping\ClassMetadata::class . ' classMetadata'])
- ->setAutowired(FALSE)
- ->getResultDefinition()
- ->setFactory($originalDef->getFactory());
- $factoryStatement = $originalDef->getFactory() ?: new Statement($originalDef->getFactory());
- $factoryStatement->arguments[0] = new Code\PhpLiteral('$entityManager');
- $factoryStatement->arguments[1] = new Code\PhpLiteral('$classMetadata');
- $boundManagers = $this->getServiceBoundManagers($originalDef);
- Validators::assert($boundManagers, 'list:1', 'bound manager');
-
- if ($boundEntity = $originalDef->getTag(self::TAG_REPOSITORY_ENTITY)) {
- if (!is_string($boundEntity) || !class_exists($boundEntity)) {
- throw new Nette\Utils\AssertionException(sprintf('The entity "%s" for repository "%s" cannot be autoloaded.', $boundEntity, $originalDef->getClass()));
- }
- $entityArgument = $boundEntity;
-
- } else {
- throw new Nette\Utils\AssertionException(sprintf(
- 'The magic auto-detection of entity for repository %s for %s was removed from Kdyby.' .
- 'You have to specify %s tag with classname of the related entity in order to use this feature.',
- $originalDef->getClass(),
- IRepositoryFactory::class,
- self::TAG_REPOSITORY_ENTITY
- ));
- }
- $builder->removeDefinition($originalServiceName);
- $builder->addDefinition($originalServiceName)
- ->setClass($originalDef->getClass())
- ->setFactory(sprintf('@%s::getRepository', $this->configuredManagers[$boundManagers[0]]), [$entityArgument]);
-
- $serviceMap[$boundManagers[0]][$originalDef->getClass()] = $factoryServiceName;
- }
-
- foreach ($this->configuredManagers as $managerName => $_) {
-
- $this->getServiceDefinition($builder, $this->prefix($managerName . '.repositoryFactory'))
- ->addSetup('setServiceIdsMap', [
- $serviceMap[$managerName],
- $this->prefix('repositoryFactory.' . $managerName . '.defaultRepositoryFactory')
- ]);
- }
- }
-
-
-
- protected function processEventManagers()
- {
- $builder = $this->getContainerBuilder();
- $customEvmService = $builder->getByType(\Doctrine\Common\EventManager::class);
- if ($this->isKdybyEventsPresent() || !$customEvmService) {
- return;
- }
-
- foreach ($this->configuredManagers as $managerName => $_) {
-
- $this->getServiceDefinition($builder, $this->prefix($managerName . '.evm'))
- ->setFactory('@' . $customEvmService);
- }
- }
-
-
-
- /**
- * @param Nette\DI\ServiceDefinition $def
- * @return string[]
- */
- protected function getServiceBoundManagers(Nette\DI\ServiceDefinition $def)
- {
- $builder = $this->getContainerBuilder();
- $boundManagers = $def->getTag(self::TAG_BIND_TO_MANAGER);
-
- return is_array($boundManagers) ? $boundManagers : [$builder->parameters[$this->name]['orm']['defaultEntityManager']];
- }
-
-
-
- public function afterCompile(Code\ClassType $class)
- {
- $init = $class->getMethod('initialize');
-
- if ($this->isTracyPresent()) {
- $init->addBody('?::registerBluescreen($this);', [new Code\PhpLiteral(Kdyby\Doctrine\Diagnostics\Panel::class)]);
- $this->addCollapsePathsToTracy($init);
- }
-
- foreach ($this->proxyAutoloaders as $namespace => $dir) {
- $originalInitialize = $init->getBody();
- $init->setBody('?::create(?, ?)->register();', [new Code\PhpLiteral(Kdyby\Doctrine\Proxy\ProxyAutoloader::class), $dir, $namespace]);
- $init->addBody((string) $originalInitialize);
- }
- }
-
-
-
- /**
+ const ANNOTATION_DRIVER = 'annotations';
+ const PHP_NAMESPACE = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff\\\\]*';
+ const TAG_CONNECTION = 'doctrine.connection';
+ const TAG_ENTITY_MANAGER = 'doctrine.entityManager';
+ const TAG_BIND_TO_MANAGER = 'doctrine.bindToManager';
+ const TAG_REPOSITORY_ENTITY = 'doctrine.repositoryEntity';
+ const DEFAULT_PROXY_NAMESPACE = 'Kdyby\GeneratedProxy';
+ const KDYBY_METADATA_NAMESPACE = 'Kdyby\Doctrine';
+
+ /**
+ * @var array
+ */
+ public $consoleCommands = [
+ 'orm:clear-cache:region:collection' => 'Kdyby\Doctrine\Console\Proxy\CacheClearCollectionRegionCommand',
+ 'orm:clear-cache:region:entity' => 'Kdyby\Doctrine\Console\Proxy\CacheClearEntityRegionCommand',
+ 'orm:clear-cache:metadata' => 'Kdyby\Doctrine\Console\Proxy\CacheClearMetadataCommand',
+ 'orm:clear-cache:query' => 'Kdyby\Doctrine\Console\Proxy\CacheClearQueryCommand',
+ 'orm:clear-cache:region:query' => 'Kdyby\Doctrine\Console\Proxy\CacheClearQueryRegionCommand',
+ 'orm:clear-cache:result' => 'Kdyby\Doctrine\Console\Proxy\CacheClearResultCommand',
+ 'orm:convert-mapping' => 'Kdyby\Doctrine\Console\Proxy\ConvertMappingCommand',
+ 'orm:generate-entities' => 'Kdyby\Doctrine\Console\Proxy\GenerateEntitiesCommand',
+ 'orm:generate-proxies' => 'Kdyby\Doctrine\Console\Proxy\GenerateProxiesCommand',
+ 'dbal:import' => 'Kdyby\Doctrine\Console\Proxy\ImportCommand',
+ 'orm:info' => 'Kdyby\Doctrine\Console\Proxy\InfoCommand',
+ 'orm:mapping:describe' => 'Kdyby\Doctrine\Console\Proxy\MappingDescribeCommand',
+ 'dbal:reserved-words' => 'Kdyby\Doctrine\Console\Proxy\ReservedWordsCommand',
+ 'orm:schema-tool:create' => 'Kdyby\Doctrine\Console\Proxy\SchemaCreateCommand',
+ 'orm:schema-tool:update' => 'Kdyby\Doctrine\Console\Proxy\SchemaUpdateCommand',
+ 'orm:schema-tool:drop' => 'Kdyby\Doctrine\Console\Proxy\SchemaDropCommand',
+ 'orm:validate-schema' => 'Kdyby\Doctrine\Console\Proxy\ValidateSchemaCommand',
+ ];
+
+ /**
+ * @var array
+ */
+ public $managerDefaults = [
+ 'metadataCache' => 'default',
+ 'queryCache' => 'default',
+ 'resultCache' => 'default',
+ 'hydrationCache' => 'default',
+ 'secondLevelCache' => [
+ 'enabled' => FALSE,
+ 'factoryClass' => Doctrine\ORM\Cache\DefaultCacheFactory::class,
+ 'driver' => 'default',
+ 'regions' => [
+ 'defaultLifetime' => 3600,
+ 'defaultLockLifetime' => 60,
+ ],
+ 'fileLockRegionDirectory' => '%tempDir%/cache/Doctrine.Cache.Locks', // todo fix
+ 'logging' => '%debugMode%',
+ ],
+ 'classMetadataFactory' => Kdyby\Doctrine\Mapping\ClassMetadataFactory::class,
+ 'defaultRepositoryClassName' => Kdyby\Doctrine\EntityRepository::class,
+ 'repositoryFactoryClassName' => Kdyby\Doctrine\RepositoryFactory::class,
+ 'queryBuilderClassName' => Kdyby\Doctrine\QueryBuilder::class,
+ 'autoGenerateProxyClasses' => '%debugMode%',
+ 'namingStrategy' => Doctrine\ORM\Mapping\UnderscoreNamingStrategy::class,
+ 'quoteStrategy' => Doctrine\ORM\Mapping\DefaultQuoteStrategy::class,
+ 'entityListenerResolver' => Kdyby\Doctrine\Mapping\EntityListenerResolver::class,
+ 'proxyDir' => '%tempDir%/proxies',
+ 'proxyNamespace' => self::DEFAULT_PROXY_NAMESPACE,
+ 'dql' => ['string' => [], 'numeric' => [], 'datetime' => [], 'hints' => []],
+ 'hydrators' => [],
+ 'metadata' => [],
+ 'filters' => [],
+ 'namespaceAlias' => [],
+ 'targetEntityMappings' => [],
+ ];
+
+ /**
+ * @var array
+ */
+ public $connectionDefaults = [
+ 'dbname' => NULL,
+ 'host' => '127.0.0.1',
+ 'port' => NULL,
+ 'user' => NULL,
+ 'password' => NULL,
+ 'charset' => 'UTF8',
+ 'driver' => 'pdo_mysql',
+ 'driverClass' => NULL,
+ 'options' => NULL,
+ 'path' => NULL,
+ 'memory' => NULL,
+ 'unix_socket' => NULL,
+ 'logging' => '%debugMode%',
+ 'platformService' => NULL,
+ 'defaultTableOptions' => [],
+ 'resultCache' => 'default',
+ 'types' => [],
+ 'schemaFilter' => NULL,
+ ];
+
+ /**
+ * @var array
+ */
+ public $metadataDriverClasses = [
+ self::ANNOTATION_DRIVER => Doctrine\ORM\Mapping\Driver\AnnotationDriver::class,
+ 'static' => Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver::class,
+ 'yml' => Doctrine\ORM\Mapping\Driver\YamlDriver::class,
+ 'yaml' => Doctrine\ORM\Mapping\Driver\YamlDriver::class,
+ 'xml' => Doctrine\ORM\Mapping\Driver\XmlDriver::class,
+ 'db' => Doctrine\ORM\Mapping\Driver\DatabaseDriver::class,
+ ];
+
+ /**
+ * @var array
+ */
+ private $proxyAutoloaders = [];
+
+ /**
+ * @var array
+ */
+ private $targetEntityMappings = [];
+
+ /**
+ * @var array
+ */
+ private $configuredManagers = [];
+
+ /**
+ * @var array
+ */
+ private $managerConfigs = [];
+
+ /**
+ * @var array
+ */
+ private $configuredConnections = [];
+
+ public function loadConfiguration()
+ {
+ $this->proxyAutoloaders = $this->targetEntityMappings = $this->configuredConnections = $this->managerConfigs = $this->configuredManagers = [];
+
+ if (!$this->compiler->getExtensions(AnnotationsExtension::class)) {
+ throw new Nette\Utils\AssertionException(sprintf("You should register %s before %s.", AnnotationsExtension::class, get_class($this)));
+ }
+
+ $builder = $this->getContainerBuilder();
+ $config = $this->getConfig();
+
+ $builder->parameters[$this->prefix('debug')] = !empty($config['debug']);
+ if (isset($config['dbname']) || isset($config['driver']) || isset($config['connection'])) {
+ $config = ['default' => $config];
+ $defaults = ['debug' => $builder->parameters['debugMode']];
+ } else {
+ $defaults = array_intersect_key($config, $this->managerDefaults) + array_intersect_key($config, $this->connectionDefaults) + ['debug' => $builder->parameters['debugMode']];
+
+ $config = array_diff_key($config, $defaults);
+ }
+
+ if (empty($config)) {
+ throw new Kdyby\Doctrine\UnexpectedValueException("Please configure the Doctrine extensions using the section '{$this->name}:' in your config file.");
+ }
+
+ foreach ($config as $name => $emConfig) {
+ if (!is_array($emConfig) || (empty($emConfig['dbname']) && empty($emConfig['driver']))) {
+ throw new Kdyby\Doctrine\UnexpectedValueException("Please configure the Doctrine extensions using the section '{$this->name}:' in your config file.");
+ }
+
+ /** @var mixed[] $emConfig */
+ $emConfig = Nette\DI\Config\Helpers::merge($emConfig, $defaults);
+ $this->processEntityManager($name, $emConfig);
+ }
+
+ if ($this->targetEntityMappings) {
+ if (!$this->isKdybyEventsPresent()) {
+ throw new Nette\Utils\AssertionException('The option \'targetEntityMappings\' requires \'Kdyby\Events\DI\EventsExtension\'.', E_USER_NOTICE);
+ }
+
+ $listener = $builder->addDefinition($this->prefix('resolveTargetEntityListener'))
+ ->setClass(Kdyby\Doctrine\Tools\ResolveTargetEntityListener::class)
+ ->addTag(Kdyby\Events\DI\EventsExtension::TAG_SUBSCRIBER);
+
+ foreach ($this->targetEntityMappings as $originalEntity => $mapping) {
+ $listener->addSetup('addResolveTargetEntity', [$originalEntity, $mapping['targetEntity'], $mapping]);
+ }
+ }
+
+ $this->loadConsole();
+
+ $builder->addDefinition($this->prefix('registry'))
+ ->setFactory(Kdyby\Doctrine\Registry::class, [
+ $this->configuredConnections,
+ $this->configuredManagers,
+ $builder->parameters[$this->name]['dbal']['defaultConnection'],
+ $builder->parameters[$this->name]['orm']['defaultEntityManager'],
+ ]);
+ }
+
+ protected function loadConsole()
+ {
+ $builder = $this->getContainerBuilder();
+ $consoleApplDef = $builder->getDefinition('console.application');
+ $consoleApplDef->addSetup('?->getHelperSet()->set(?)', ['@self', new Statement(ContainerHelper::class)]);
+
+ foreach ($this->consoleCommands as $name => $command) {
+ $cli = $builder->addDefinition($this->prefix(str_replace([':', '-', '_'], ['', '', ''], $name)))
+ ->addTag('console.command', $name)
+ ->setAutowired(false)
+ ->addTag(Nette\DI\Extensions\InjectExtension::TAG_INJECT, FALSE); // lazy injects
+
+ if (is_string($command)) {
+ $cli->setClass($command);
+ } else {
+ throw new Kdyby\Doctrine\NotSupportedException;
+ }
+ }
+ }
+
+ protected function processEntityManager($name, array $defaults)
+ {
+ $builder = $this->getContainerBuilder();
+ $config = $this->resolveConfig($defaults, $this->managerDefaults, $this->connectionDefaults);
+
+ if ($isDefault = !isset($builder->parameters[$this->name]['orm']['defaultEntityManager'])) {
+ $builder->parameters[$this->name]['orm']['defaultEntityManager'] = $name;
+ }
+
+ $metadataDriver = $builder->addDefinition($this->prefix($name . '.metadataDriver'))
+ ->setClass(Doctrine\Persistence\Mapping\Driver\MappingDriverChain::class)
+ ->setAutowired(FALSE);
+ /** @var \Nette\DI\ServiceDefinition $metadataDriver */
+ Validators::assertField($config, 'metadata', 'array');
+ Validators::assertField($config, 'targetEntityMappings', 'array');
+ $config['targetEntityMappings'] = $this->normalizeTargetEntityMappings($config['targetEntityMappings']);
+ foreach ($this->compiler->getExtensions() as $extension) {
+ if ($extension instanceof IEntityProvider) {
+ $metadata = $extension->getEntityMappings();
+ Validators::assert($metadata, 'array');
+ foreach ($metadata as $namespace => $nsConfig) {
+ if (array_key_exists($namespace, $config['metadata'])) {
+ throw new Nette\Utils\AssertionException(sprintf('The namespace %s is already configured, provider cannot change it', $namespace));
+ }
+ $config['metadata'][$namespace] = $nsConfig;
+ }
+ }
+
+ if ($extension instanceof ITargetEntityProvider) {
+ $targetEntities = $extension->getTargetEntityMappings();
+ Validators::assert($targetEntities, 'array');
+ $config['targetEntityMappings'] = Nette\Utils\Arrays::mergeTree($config['targetEntityMappings'], $this->normalizeTargetEntityMappings($targetEntities));
+ }
+
+ if ($extension instanceof IDatabaseTypeProvider) {
+ $providedTypes = $extension->getDatabaseTypes();
+ Validators::assert($providedTypes, 'array');
+
+ if (!isset($defaults['types'])) {
+ $defaults['types'] = [];
+ }
+
+ $defaults['types'] = array_merge($defaults['types'], $providedTypes);
+ }
+ }
+
+ foreach (self::natSortKeys($config['metadata']) as $namespace => $driver) {
+ $this->processMetadataDriver($metadataDriver, $namespace, $driver, $name);
+ }
+
+ $this->processMetadataDriver($metadataDriver, self::KDYBY_METADATA_NAMESPACE, __DIR__ . '/../Entities', $name);
+
+ if (empty($config['metadata'])) {
+ $metadataDriver->addSetup('setDefaultDriver', [
+ new Statement($this->metadataDriverClasses[self::ANNOTATION_DRIVER], [
+ '@' . Doctrine\Common\Annotations\Reader::class,
+ [Nette\DI\Helpers::expand('%appDir%', $builder->parameters)]
+ ])
+ ]);
+ }
+
+ if ($config['repositoryFactoryClassName'] === 'default') {
+ $config['repositoryFactoryClassName'] = DefaultRepositoryFactory::class;
+ }
+ $builder->addDefinition($this->prefix($name . '.repositoryFactory'))
+ ->setClass($config['repositoryFactoryClassName'])
+ ->setAutowired(FALSE);
+
+ Validators::assertField($config, 'namespaceAlias', 'array');
+ Validators::assertField($config, 'hydrators', 'array');
+ Validators::assertField($config, 'dql', 'array');
+ Validators::assertField($config['dql'], 'string', 'array');
+ Validators::assertField($config['dql'], 'numeric', 'array');
+ Validators::assertField($config['dql'], 'datetime', 'array');
+ Validators::assertField($config['dql'], 'hints', 'array');
+
+ $autoGenerateProxyClasses = is_bool($config['autoGenerateProxyClasses']) ? ($config['autoGenerateProxyClasses'] ? AbstractProxyFactory::AUTOGENERATE_ALWAYS : AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS) : $config['autoGenerateProxyClasses'];
+
+ $configuration = $builder->addDefinition($this->prefix($name . '.ormConfiguration'))
+ ->setClass(Kdyby\Doctrine\Configuration::class)
+ ->addSetup('setMetadataCacheImpl', [$this->processCache($config['metadataCache'], $name . '.metadata')])
+ ->addSetup('setQueryCacheImpl', [$this->processCache($config['queryCache'], $name . '.query')])
+ ->addSetup('setResultCacheImpl', [$this->processCache($config['resultCache'], $name . '.ormResult')])
+ ->addSetup('setHydrationCacheImpl', [$this->processCache($config['hydrationCache'], $name . '.hydration')])
+ ->addSetup('setMetadataDriverImpl', [$this->prefix('@' . $name . '.metadataDriver')])
+ ->addSetup('setClassMetadataFactoryName', [$config['classMetadataFactory']])
+ ->addSetup('setDefaultRepositoryClassName', [$config['defaultRepositoryClassName']])
+ ->addSetup('setQueryBuilderClassName', [$config['queryBuilderClassName']])
+ ->addSetup('setRepositoryFactory', [$this->prefix('@' . $name . '.repositoryFactory')])
+ ->addSetup('setProxyDir', [$config['proxyDir']])
+ ->addSetup('setProxyNamespace', [$config['proxyNamespace']])
+ ->addSetup('setAutoGenerateProxyClasses', [$autoGenerateProxyClasses])
+ ->addSetup('setEntityNamespaces', [$config['namespaceAlias']])
+ ->addSetup('setCustomHydrationModes', [$config['hydrators']])
+ ->addSetup('setCustomStringFunctions', [$config['dql']['string']])
+ ->addSetup('setCustomNumericFunctions', [$config['dql']['numeric']])
+ ->addSetup('setCustomDatetimeFunctions', [$config['dql']['datetime']])
+ ->addSetup('setDefaultQueryHints', [$config['dql']['hints']])
+ ->addSetup('setNamingStrategy', CacheHelpers::filterArgs($config['namingStrategy']))
+ ->addSetup('setQuoteStrategy', CacheHelpers::filterArgs($config['quoteStrategy']))
+ ->addSetup('setEntityListenerResolver', CacheHelpers::filterArgs($config['entityListenerResolver']))
+ ->setAutowired(FALSE);
+ /** @var Nette\DI\ServiceDefinition $configuration */
+ $this->proxyAutoloaders[$config['proxyNamespace']] = $config['proxyDir'];
+
+ $this->processSecondLevelCache($name, $config['secondLevelCache'], $isDefault);
+
+ Validators::assertField($config, 'filters', 'array');
+ foreach ($config['filters'] as $filterName => $filterClass) {
+ $configuration->addSetup('addFilter', [$filterName, $filterClass]);
+ }
+
+ if ($config['targetEntityMappings']) {
+ $configuration->addSetup('setTargetEntityMap', [array_map(function ($mapping)
+ {
+ return $mapping['targetEntity'];
+ }, $config['targetEntityMappings'])]);
+ $this->targetEntityMappings = Nette\Utils\Arrays::mergeTree($this->targetEntityMappings, $config['targetEntityMappings']);
+ }
+
+ if ($this->isKdybyEventsPresent()) {
+ $builder->addDefinition($this->prefix($name . '.evm'))
+ ->setFactory(Kdyby\Events\NamespacedEventManager::class, [Kdyby\Doctrine\Events::NS . '::'])
+ ->addSetup('$dispatchGlobalEvents', [TRUE]) // for BC
+ ->setAutowired(FALSE);
+ } else {
+ $builder->addDefinition($this->prefix($name . '.evm'))
+ ->setClass('Doctrine\Common\EventManager')
+ ->setAutowired(FALSE);
+ }
+
+ // entity manager
+ $entityManager = $builder->addDefinition($managerServiceId = $this->prefix($name . '.entityManager'))
+ ->setClass(Kdyby\Doctrine\EntityManager::class)
+ ->setFactory(Kdyby\Doctrine\EntityManager::class . '::create', [
+ $connectionService = $this->processConnection($name, $defaults, $isDefault),
+ $this->prefix('@' . $name . '.ormConfiguration'),
+ $this->prefix('@' . $name . '.evm'),
+ ])
+ ->addTag(self::TAG_ENTITY_MANAGER)
+ ->addTag('kdyby.doctrine.entityManager')
+ ->setAutowired($isDefault);
+
+ if ($this->isTracyPresent()) {
+ $entityManager->addSetup('?->bindEntityManager(?)', [$this->prefix('@' . $name . '.diagnosticsPanel'), '@self']);
+ }
+
+ $builder->addFactoryDefinition($this->prefix('repositoryFactory.' . $name . '.defaultRepositoryFactory'))
+ ->setImplement(IRepositoryFactory::class)
+ ->setParameters([EntityManagerInterface::class . ' entityManager', Doctrine\ORM\Mapping\ClassMetadata::class . ' classMetadata'])
+ ->getResultDefinition()
+ ->setFactory($config['defaultRepositoryClassName'])
+ ->setArguments([new Code\PhpLiteral('$entityManager'), new Code\PhpLiteral('$classMetadata')])
+ ->setAutowired(FALSE);
+
+ $builder->addDefinition($this->prefix($name . '.schemaValidator'))
+ ->setFactory(Doctrine\ORM\Tools\SchemaValidator::class, ['@' . $managerServiceId])
+ ->setAutowired($isDefault);
+
+ $builder->addDefinition($this->prefix($name . '.schemaTool'))
+ ->setFactory(Doctrine\ORM\Tools\SchemaTool::class, ['@' . $managerServiceId])
+ ->setAutowired($isDefault);
+
+ $cacheCleaner = $builder->addDefinition($this->prefix($name . '.cacheCleaner'))
+ ->setFactory(Kdyby\Doctrine\Tools\CacheCleaner::class, ['@' . $managerServiceId])
+ ->setAutowired($isDefault);
+
+ $builder->addDefinition($this->prefix($name . '.schemaManager'))
+ ->setClass(AbstractSchemaManager::class)
+ ->setFactory('@' . Kdyby\Doctrine\Connection::class . '::getSchemaManager')
+ ->setAutowired($isDefault);
+
+ foreach ($this->compiler->getExtensions(AnnotationsExtension::class) as $extension) {
+ /** @var AnnotationsExtension $extension */
+ $cacheCleaner->addSetup('addCacheStorage', [$extension->prefix('@cache.annotations')]);
+ }
+
+ if ($isDefault) {
+ $builder->addDefinition($this->prefix('helper.entityManager'))
+ ->setFactory(EntityManagerHelper::class, ['@' . $managerServiceId])
+ ->addTag('console.helpers', 'em');
+
+ $builder->addDefinition($this->prefix('helper.connection'))
+ ->setFactory(ConnectionHelper::class, [$connectionService])
+ ->addTag('console.helpers', 'db');
+
+ $builder->addAlias($this->prefix('schemaValidator'), $this->prefix($name . '.schemaValidator'));
+ $builder->addAlias($this->prefix('schemaTool'), $this->prefix($name . '.schemaTool'));
+ $builder->addAlias($this->prefix('cacheCleaner'), $this->prefix($name . '.cacheCleaner'));
+ $builder->addAlias($this->prefix('schemaManager'), $this->prefix($name . '.schemaManager'));
+ }
+
+ $this->configuredManagers[$name] = $managerServiceId;
+ $this->managerConfigs[$name] = $config;
+ }
+
+ protected function processSecondLevelCache($name, array $config, $isDefault)
+ {
+ if (!$config['enabled']) {
+ return;
+ }
+
+ $builder = $this->getContainerBuilder();
+
+ $cacheFactory = $builder->addDefinition($this->prefix($name . '.cacheFactory'))
+ ->setClass(Doctrine\ORM\Cache\CacheFactory::class)
+ ->setFactory($config['factoryClass'], [
+ $this->prefix('@' . $name . '.cacheRegionsConfiguration'),
+ $this->processCache($config['driver'], $name . '.secondLevel'),
+ ])
+ ->setAutowired($isDefault);
+
+ if ($config['factoryClass'] === $this->managerDefaults['secondLevelCache']['factoryClass'] || is_subclass_of($config['factoryClass'], $this->managerDefaults['secondLevelCache']['factoryClass'])
+ ) {
+ $cacheFactory->addSetup('setFileLockRegionDirectory', [$config['fileLockRegionDirectory']]);
+ }
+
+ $builder->addDefinition($this->prefix($name . '.cacheRegionsConfiguration'))
+ ->setClass(Doctrine\ORM\Cache\RegionsConfiguration::class, [
+ $config['regions']['defaultLifetime'],
+ $config['regions']['defaultLockLifetime'],
+ ])
+ ->setAutowired($isDefault);
+
+ $logger = $builder->addDefinition($this->prefix($name . '.cacheLogger'))
+ ->setClass(Doctrine\ORM\Cache\Logging\CacheLogger::class)
+ ->setFactory(Doctrine\ORM\Cache\Logging\CacheLoggerChain::class)
+ ->setAutowired(FALSE);
+
+ if ($config['logging']) {
+ $logger->addSetup('setLogger', [
+ 'statistics',
+ new Statement(Doctrine\ORM\Cache\Logging\StatisticsCacheLogger::class)
+ ]);
+ }
+
+ $builder->addDefinition($cacheConfigName = $this->prefix($name . '.ormCacheConfiguration'))
+ ->setClass(Doctrine\ORM\Cache\CacheConfiguration::class)
+ ->addSetup('setCacheFactory', [$this->prefix('@' . $name . '.cacheFactory')])
+ ->addSetup('setCacheLogger', [$this->prefix('@' . $name . '.cacheLogger')])
+ ->setAutowired($isDefault);
+
+ $this->getServiceDefinition($builder, $this->prefix($name . '.ormConfiguration'))
+ ->addSetup('setSecondLevelCacheEnabled')
+ ->addSetup('setSecondLevelCacheConfiguration', ['@' . $cacheConfigName]);
+ }
+
+ protected function processConnection($name, array $defaults, $isDefault = FALSE)
+ {
+ $builder = $this->getContainerBuilder();
+ $config = $this->resolveConfig($defaults, $this->connectionDefaults, $this->managerDefaults);
+
+ if ($isDefault) {
+ $builder->parameters[$this->name]['dbal']['defaultConnection'] = $name;
+ }
+
+ if (isset($defaults['connection'])) {
+ return $this->prefix('@' . $defaults['connection'] . '.connection');
+ }
+
+ // config
+ $configuration = $builder->addDefinition($this->prefix($name . '.dbalConfiguration'))
+ ->setClass(Doctrine\DBAL\Configuration::class)
+ ->addSetup('setResultCacheImpl', [$this->processCache($config['resultCache'], $name . '.dbalResult')])
+ ->addSetup('setSQLLogger', [new Statement(Doctrine\DBAL\Logging\LoggerChain::class)])
+ ->addSetup('setFilterSchemaAssetsExpression', [$config['schemaFilter']])
+ ->setAutowired(FALSE);
+
+ // types
+ Validators::assertField($config, 'types', 'array');
+ $schemaTypes = $dbalTypes = [];
+ foreach ($config['types'] as $dbType => $className) {
+ /** @var Doctrine\DBAL\Types\Type $typeInst */
+ $typeInst = Code\Helpers::createObject($className, []);
+ $dbalTypes[$typeInst->getName()] = $className;
+ $schemaTypes[$dbType] = $typeInst->getName();
+ }
+
+ // tracy panel
+ if ($this->isTracyPresent()) {
+ $builder->addDefinition($this->prefix($name . '.diagnosticsPanel'))
+ ->setClass(Kdyby\Doctrine\Diagnostics\Panel::class)
+ ->setAutowired(FALSE);
+ }
+
+ // connection
+ $options = array_diff_key($config, array_flip(['types', 'resultCache', 'connection', 'logging']));
+ $connection = $builder->addDefinition($connectionServiceId = $this->prefix($name . '.connection'))
+ ->setClass(Kdyby\Doctrine\Connection::class)
+ ->setFactory(Kdyby\Doctrine\Connection::class . '::create', [
+ $options,
+ $this->prefix('@' . $name . '.dbalConfiguration'),
+ $this->prefix('@' . $name . '.evm'),
+ ])
+ ->addSetup('setSchemaTypes', [$schemaTypes])
+ ->addSetup('setDbalTypes', [$dbalTypes])
+ ->addTag(self::TAG_CONNECTION)
+ ->addTag('kdyby.doctrine.connection')
+ ->setAutowired($isDefault);
+
+ if ($this->isTracyPresent()) {
+ $connection->addSetup('$panel = ?->bindConnection(?)', [$this->prefix('@' . $name . '.diagnosticsPanel'), '@self']);
+ }
+
+ /** @var Nette\DI\ServiceDefinition $connection */
+ $this->configuredConnections[$name] = $connectionServiceId;
+
+ if (!is_bool($config['logging'])) {
+ $fileLogger = new Statement(Kdyby\Doctrine\Diagnostics\FileLogger::class, [Nette\DI\Helpers::expand($config['logging'], $builder->parameters)]);
+ $configuration->addSetup('$service->getSQLLogger()->addLogger(?)', [$fileLogger]);
+ } elseif ($config['logging']) {
+ $connection->addSetup('?->enableLogging()', [new Code\PhpLiteral('$panel')]);
+ }
+
+ return $this->prefix('@' . $name . '.connection');
+ }
+
+ /**
+ * @param \Nette\DI\ServiceDefinition $metadataDriver
+ * @param string $namespace
+ * @param string|array|\stdClass $driver
+ * @param string $prefix
+ * @throws \Nette\Utils\AssertionException
+ * @return string
+ */
+ protected function processMetadataDriver(Nette\DI\ServiceDefinition $metadataDriver, $namespace, $driver, $prefix)
+ {
+ if (!is_string($namespace) || !Strings::match($namespace, '#^' . self::PHP_NAMESPACE . '\z#')) {
+ throw new Nette\Utils\AssertionException("The metadata namespace expects to be valid namespace, $namespace given.");
+ }
+ $namespace = ltrim($namespace, '\\');
+
+ if (is_string($driver) && strpos($driver, '@') === 0) { // service reference
+ $metadataDriver->addSetup('addDriver', [$driver, $namespace]);
+ return $driver;
+ }
+
+ if (is_string($driver) || is_array($driver)) {
+ $paths = is_array($driver) ? $driver : [$driver];
+ foreach ($paths as $path) {
+ if (!file_exists($path)) {
+ throw new Nette\Utils\AssertionException("The metadata path expects to be an existing directory, $path given.");
+ }
+ }
+
+ $driver = new Statement(self::ANNOTATION_DRIVER, is_array($paths) ? $paths : [$paths]);
+ }
+
+ $impl = $driver instanceof \stdClass ? $driver->value : ($driver instanceof Statement ? $driver->getEntity() : (string) $driver);
+ list($driver) = CacheHelpers::filterArgs($driver);
+ /** @var Statement $driver */
+ /** @var string $impl */
+ if (isset($this->metadataDriverClasses[$impl])) {
+ $driver = new Statement($this->metadataDriverClasses[$impl], $driver->arguments);
+ }
+
+ if (is_string($driver->getEntity()) && substr($driver->getEntity(), 0, 1) === '@') {
+ $metadataDriver->addSetup('addDriver', [$driver->getEntity(), $namespace]);
+ return $driver->getEntity();
+ }
+
+ if ($impl === self::ANNOTATION_DRIVER) {
+ $driver->arguments = [
+ '@' . Doctrine\Common\Annotations\Reader::class,
+ Nette\Utils\Arrays::flatten($driver->arguments)
+ ];
+ }
+
+ $serviceName = $this->prefix($prefix . '.driver.' . str_replace('\\', '_', $namespace) . '.' . str_replace('\\', '_', $impl) . 'Impl');
+
+ $this->getContainerBuilder()->addDefinition($serviceName)
+ ->setClass(Doctrine\Persistence\Mapping\Driver\MappingDriver::class)
+ ->setFactory($driver->getEntity(), $driver->arguments)
+ ->setAutowired(FALSE);
+
+ $metadataDriver->addSetup('addDriver', ['@' . $serviceName, $namespace]);
+ return '@' . $serviceName;
+ }
+
+ /**
+ * @param string|\stdClass $cache
+ * @param string $suffix
+ * @return string
+ */
+ protected function processCache($cache, $suffix)
+ {
+ return CacheHelpers::processCache($this, $cache, $suffix, $this->getContainerBuilder()->parameters[$this->prefix('debug')]);
+ }
+
+ public function beforeCompile()
+ {
+ $this->processRepositories();
+ $this->processEventManagers();
+ }
+
+ protected function processRepositories()
+ {
+ $builder = $this->getContainerBuilder();
+
+ $disabled = TRUE;
+ foreach ($this->configuredManagers as $managerName => $_) {
+ $factoryClassName = $builder->getDefinition($this->prefix($managerName . '.repositoryFactory'))->getClass();
+ if ($factoryClassName === Kdyby\Doctrine\RepositoryFactory::class || in_array(Kdyby\Doctrine\RepositoryFactory::class, class_parents($factoryClassName), TRUE)) {
+ $disabled = FALSE;
+ }
+ }
+
+ if ($disabled) {
+ return;
+ }
+
+ if (!method_exists($builder, 'findByType')) {
+ foreach ($this->configuredManagers as $managerName => $_) {
+ $this->getServiceDefinition($builder, $this->prefix($managerName . '.repositoryFactory'))
+ ->addSetup('setServiceIdsMap', [[], $this->prefix('repositoryFactory.' . $managerName . '.defaultRepositoryFactory')]);
+ }
+
+ return;
+ }
+
+ $serviceMap = array_fill_keys(array_keys($this->configuredManagers), []);
+
+ /**
+ * @var Nette\DI\ServiceDefinition $originalDef
+ */
+ foreach ($builder->findByType(Doctrine\ORM\EntityRepository::class) as $originalServiceName => $originalDef) {
+ if (strpos($originalServiceName, $this->name . '.') === 0) {
+ continue; // ignore
+ }
+
+ $originalDefFactory = $originalDef->getFactory();
+ $factory = !empty($originalDefFactory) ? $originalDefFactory->getEntity() : $originalDef->getClass();
+
+ if ((is_string($factory) && stripos($factory, '::getRepository') !== FALSE) || (is_array($factory) && array_search('::getRepository', $factory) === FALSE)) {
+ continue; // ignore
+ }
+ $factoryServiceName = $this->prefix('repositoryFactory.' . $originalServiceName);
+ $factoryDef = $builder->addFactoryDefinition($factoryServiceName)
+ ->setImplement(IRepositoryFactory::class)
+ ->setParameters([Doctrine\ORM\EntityManagerInterface::class . ' entityManager', Doctrine\ORM\Mapping\ClassMetadata::class . ' classMetadata'])
+ ->setAutowired(FALSE)
+ ->getResultDefinition()
+ ->setFactory($originalDef->getFactory());
+ $factoryStatement = $originalDef->getFactory() ?: new Statement($originalDef->getFactory());
+ $factoryStatement->arguments[0] = new Code\PhpLiteral('$entityManager');
+ $factoryStatement->arguments[1] = new Code\PhpLiteral('$classMetadata');
+ $boundManagers = $this->getServiceBoundManagers($originalDef);
+ Validators::assert($boundManagers, 'list:1', 'bound manager');
+
+ if ($boundEntity = $originalDef->getTag(self::TAG_REPOSITORY_ENTITY)) {
+ if (!is_string($boundEntity) || !class_exists($boundEntity)) {
+ throw new Nette\Utils\AssertionException(sprintf('The entity "%s" for repository "%s" cannot be autoloaded.', $boundEntity, $originalDef->getClass()));
+ }
+ $entityArgument = $boundEntity;
+ } else {
+ throw new Nette\Utils\AssertionException(sprintf(
+ 'The magic auto-detection of entity for repository %s for %s was removed from Kdyby.' .
+ 'You have to specify %s tag with classname of the related entity in order to use this feature.',
+ $originalDef->getClass(),
+ IRepositoryFactory::class,
+ self::TAG_REPOSITORY_ENTITY
+ ));
+ }
+ $builder->removeDefinition($originalServiceName);
+ $builder->addDefinition($originalServiceName)
+ ->setClass($originalDef->getClass())
+ ->setFactory(sprintf('@%s::getRepository', $this->configuredManagers[$boundManagers[0]]), [$entityArgument]);
+
+ $serviceMap[$boundManagers[0]][$originalDef->getClass()] = $factoryServiceName;
+ }
+
+ foreach ($this->configuredManagers as $managerName => $_) {
+
+ $this->getServiceDefinition($builder, $this->prefix($managerName . '.repositoryFactory'))
+ ->addSetup('setServiceIdsMap', [
+ $serviceMap[$managerName],
+ $this->prefix('repositoryFactory.' . $managerName . '.defaultRepositoryFactory')
+ ]);
+ }
+ }
+
+ protected function processEventManagers()
+ {
+ $builder = $this->getContainerBuilder();
+ $customEvmService = $builder->getByType(\Doctrine\Common\EventManager::class);
+ if ($this->isKdybyEventsPresent() || !$customEvmService) {
+ return;
+ }
+
+ foreach ($this->configuredManagers as $managerName => $_) {
+
+ $this->getServiceDefinition($builder, $this->prefix($managerName . '.evm'))
+ ->setFactory('@' . $customEvmService);
+ }
+ }
+
+ /**
+ * @param Nette\DI\ServiceDefinition $def
+ * @return string[]
+ */
+ protected function getServiceBoundManagers(Nette\DI\ServiceDefinition $def)
+ {
+ $builder = $this->getContainerBuilder();
+ $boundManagers = $def->getTag(self::TAG_BIND_TO_MANAGER);
+
+ return is_array($boundManagers) ? $boundManagers : [$builder->parameters[$this->name]['orm']['defaultEntityManager']];
+ }
+
+ public function afterCompile(Code\ClassType $class)
+ {
+ $init = $class->getMethod('initialize');
+
+ if ($this->isTracyPresent()) {
+ $init->addBody('?::registerBluescreen($this);', [new Code\PhpLiteral(Kdyby\Doctrine\Diagnostics\Panel::class)]);
+ $this->addCollapsePathsToTracy($init);
+ }
+
+ foreach ($this->proxyAutoloaders as $namespace => $dir) {
+ $originalInitialize = $init->getBody();
+ $init->setBody('?::create(?, ?)->register();', [new Code\PhpLiteral(Kdyby\Doctrine\Proxy\ProxyAutoloader::class), $dir, $namespace]);
+ $init->addBody((string) $originalInitialize);
+ }
+ }
+
+ /**
* @param array $provided
* @param array $defaults
* @param array $diff
- * @return array
- */
- private function resolveConfig(array $provided, array $defaults, array $diff = [])
- {
- return Nette\DI\Helpers::expand(Nette\DI\Config\Helpers::merge(
- array_diff_key($provided, array_diff_key($diff, $defaults)),
- $defaults
- ), $this->compiler->getContainerBuilder()->parameters);
- }
-
-
- /**
- * @param array $targetEntityMappings
- * @return array
- */
- private function normalizeTargetEntityMappings(array $targetEntityMappings)
- {
- $normalized = [];
- foreach ($targetEntityMappings as $originalEntity => $targetEntity) {
- $originalEntity = ltrim($originalEntity, '\\');
- Validators::assert($targetEntity, 'array|string');
- if (is_array($targetEntity)) {
- Validators::assertField($targetEntity, 'targetEntity', 'string');
- $mapping = array_merge($targetEntity, [
- 'targetEntity' => ltrim($targetEntity['targetEntity'], '\\')
- ]);
-
- } else {
- $mapping = [
- 'targetEntity' => ltrim($targetEntity, '\\'),
- ];
- }
- $normalized[$originalEntity] = $mapping;
- }
- return $normalized;
- }
-
-
-
- /**
- * @return bool
- */
- private function isTracyPresent()
- {
- return interface_exists(\Tracy\IBarPanel::class);
- }
-
-
-
- /**
- * @return bool
- */
- private function isKdybyEventsPresent()
- {
- return (bool) $this->compiler->getExtensions(\Kdyby\Events\DI\EventsExtension::class);
- }
-
-
-
- private function addCollapsePathsToTracy(Method $init)
- {
- $blueScreen = \Tracy\Debugger::class . '::getBlueScreen()';
- $commonDirname = dirname(Nette\Reflection\ClassType::from(Doctrine\Common\Version::class)->getFileName());
-
- $init->addBody($blueScreen . '->collapsePaths[] = ?;', [dirname(Nette\Reflection\ClassType::from(Kdyby\Doctrine\Exception::class)->getFileName())]);
- $init->addBody($blueScreen . '->collapsePaths[] = ?;', [dirname(dirname(dirname(dirname($commonDirname))))]); // this should be vendor/doctrine
- foreach ($this->proxyAutoloaders as $dir) {
- $init->addBody($blueScreen . '->collapsePaths[] = ?;', [$dir]);
- }
- }
-
-
-
- /**
- * @param \Nette\Configurator $configurator
- */
- public static function register(Nette\Configurator $configurator)
- {
- $configurator->onCompile[] = function ($config, Nette\DI\Compiler $compiler) {
- $compiler->addExtension('doctrine', new OrmExtension());
- };
- }
-
-
-
- /**
- * @param array $array
- */
- private static function natSortKeys(array &$array)
- {
- $keys = array_keys($array);
- natsort($keys);
- $keys = array_flip(array_reverse($keys, TRUE));
- $array = array_merge($keys, $array);
- return $array;
- }
-
- private function getServiceDefinition(ContainerBuilder $builder, string $name): ServiceDefinition
- {
- $definition = $builder->getDefinition($name);
- assert($definition instanceof ServiceDefinition);
- return $definition;
- }
+ * @return array
+ */
+ private function resolveConfig(array $provided, array $defaults, array $diff = [])
+ {
+ return Nette\DI\Helpers::expand(Nette\DI\Config\Helpers::merge(
+ array_diff_key($provided, array_diff_key($diff, $defaults)),
+ $defaults
+ ), $this->compiler->getContainerBuilder()->parameters);
+ }
+
+ /**
+ * @param array $targetEntityMappings
+ * @return array
+ */
+ private function normalizeTargetEntityMappings(array $targetEntityMappings)
+ {
+ $normalized = [];
+ foreach ($targetEntityMappings as $originalEntity => $targetEntity) {
+ $originalEntity = ltrim($originalEntity, '\\');
+ Validators::assert($targetEntity, 'array|string');
+ if (is_array($targetEntity)) {
+ Validators::assertField($targetEntity, 'targetEntity', 'string');
+ $mapping = array_merge($targetEntity, [
+ 'targetEntity' => ltrim($targetEntity['targetEntity'], '\\')
+ ]);
+ } else {
+ $mapping = [
+ 'targetEntity' => ltrim($targetEntity, '\\'),
+ ];
+ }
+ $normalized[$originalEntity] = $mapping;
+ }
+ return $normalized;
+ }
+
+ /**
+ * @return bool
+ */
+ private function isTracyPresent()
+ {
+ return interface_exists(\Tracy\IBarPanel::class);
+ }
+
+ /**
+ * @return bool
+ */
+ private function isKdybyEventsPresent()
+ {
+ return (bool) $this->compiler->getExtensions(\Kdyby\Events\DI\EventsExtension::class);
+ }
+
+ private function addCollapsePathsToTracy(Method $init)
+ {
+ $blueScreen = \Tracy\Debugger::class . '::getBlueScreen()';
+ $commonDirname = dirname((new \ReflectionClass(\Doctrine\Common\CommonException::class))->getFileName());
+
+ $init->addBody($blueScreen . '->collapsePaths[] = ?;', [dirname((new \ReflectionClass(Kdyby\Doctrine\Exception::class))->getFileName())]);
+ $init->addBody($blueScreen . '->collapsePaths[] = ?;', [dirname(dirname(dirname(dirname($commonDirname))))]); // this should be vendor/doctrine
+ foreach ($this->proxyAutoloaders as $dir) {
+ $init->addBody($blueScreen . '->collapsePaths[] = ?;', [$dir]);
+ }
+ }
+
+ /**
+ * @param \Nette\Configurator $configurator
+ */
+ public static function register(Nette\Configurator $configurator)
+ {
+ $configurator->onCompile[] = function ($config, Nette\DI\Compiler $compiler)
+ {
+ $compiler->addExtension('doctrine', new OrmExtension());
+ };
+ }
+
+ /**
+ * @param array $array
+ */
+ private static function natSortKeys(array &$array)
+ {
+ $keys = array_keys($array);
+ natsort($keys);
+ $keys = array_flip(array_reverse($keys, TRUE));
+ $array = array_merge($keys, $array);
+ return $array;
+ }
+
+ private function getServiceDefinition(ContainerBuilder $builder, string $name): ServiceDefinition
+ {
+ $definition = $builder->getDefinition($name);
+ assert($definition instanceof ServiceDefinition);
+ return $definition;
+ }
}
diff --git a/src/Kdyby/Doctrine/DI/console.neon b/src/Kdyby/Doctrine/DI/console.neon
deleted file mode 100644
index af70cdac..00000000
--- a/src/Kdyby/Doctrine/DI/console.neon
+++ /dev/null
@@ -1,17 +0,0 @@
-- Kdyby\Doctrine\Console\Proxy\CacheClearCollectionRegionCommand
-- Kdyby\Doctrine\Console\Proxy\CacheClearEntityRegionCommand
-- Kdyby\Doctrine\Console\Proxy\CacheClearMetadataCommand
-- Kdyby\Doctrine\Console\Proxy\CacheClearQueryCommand
-- Kdyby\Doctrine\Console\Proxy\CacheClearQueryRegionCommand
-- Kdyby\Doctrine\Console\Proxy\CacheClearResultCommand
-- Kdyby\Doctrine\Console\Proxy\ConvertMappingCommand
-- Kdyby\Doctrine\Console\Proxy\GenerateEntitiesCommand
-- Kdyby\Doctrine\Console\Proxy\GenerateProxiesCommand
-- Kdyby\Doctrine\Console\Proxy\ImportCommand
-- Kdyby\Doctrine\Console\Proxy\InfoCommand
-- Kdyby\Doctrine\Console\Proxy\MappingDescribeCommand
-- Kdyby\Doctrine\Console\Proxy\ReservedWordsCommand
-- Kdyby\Doctrine\Console\Proxy\SchemaCreateCommand
-- Kdyby\Doctrine\Console\Proxy\SchemaUpdateCommand
-- Kdyby\Doctrine\Console\Proxy\SchemaDropCommand
-- Kdyby\Doctrine\Console\Proxy\ValidateSchemaCommand
diff --git a/src/Kdyby/Doctrine/Mapping/RuntimeReflectionService.php b/src/Kdyby/Doctrine/Mapping/RuntimeReflectionService.php
index fece83bc..94be530d 100644
--- a/src/Kdyby/Doctrine/Mapping/RuntimeReflectionService.php
+++ b/src/Kdyby/Doctrine/Mapping/RuntimeReflectionService.php
@@ -20,36 +20,13 @@
/**
* @author Filip Procházka
*/
-class RuntimeReflectionService extends Doctrine\Common\Persistence\Mapping\RuntimeReflectionService
+class RuntimeReflectionService extends Doctrine\Persistence\Mapping\RuntimeReflectionService
{
- /**
- * Return a reflection class instance or null
- *
- * @param string $class
- * @return \Nette\Reflection\ClassType
- */
- public function getClass($class)
- {
- return new Reflection\ClassType($class);
- }
-
-
-
- /**
- * Return an accessible property (setAccessible(true)) or null.
- *
- * @param string $class
- * @param string $property
- * @return \Nette\Reflection\Property|NULL
- */
public function getAccessibleProperty($class, $property)
{
try {
- $property = new Reflection\Property($class, $property);
- $property->setAccessible(TRUE);
-
- return $property;
+ return parent::getAccessibleProperty($class, $property);
} catch (\ReflectionException $e) {
return NULL;
diff --git a/src/Kdyby/Doctrine/Registry.php b/src/Kdyby/Doctrine/Registry.php
index bb3c0e8a..e8c1398e 100644
--- a/src/Kdyby/Doctrine/Registry.php
+++ b/src/Kdyby/Doctrine/Registry.php
@@ -10,7 +10,7 @@
namespace Kdyby\Doctrine;
-use Doctrine\Common\Persistence\AbstractManagerRegistry;
+use Doctrine\Persistence\AbstractManagerRegistry;
use Doctrine\ORM\ORMException;
use Kdyby;
use Nette;
diff --git a/tests/KdybyTests/Doctrine/Console/CommandTestCase.php b/tests/KdybyTests/Doctrine/Console/CommandTestCase.php
index 99b21680..635ec876 100644
--- a/tests/KdybyTests/Doctrine/Console/CommandTestCase.php
+++ b/tests/KdybyTests/Doctrine/Console/CommandTestCase.php
@@ -83,12 +83,12 @@ protected function executeCommand($command, array $input = [], array $options =
/**
- * @return Kdyby\Console\Application
+ * @return Contributte\Console\Application
*/
protected function getApplication()
{
- /** @var \Kdyby\Console\Application $application */
- $application = $this->getServiceLocator()->getByType(\Kdyby\Console\Application::class);
+ /** @var \Contributte\Console\Application $application */
+ $application = $this->getServiceLocator()->getByType(\Contributte\Console\Application::class);
$application->setAutoExit(FALSE);
return $application;
}
diff --git a/tests/KdybyTests/Doctrine/Extension.phpt b/tests/KdybyTests/Doctrine/Extension.phpt
index 24e6791f..e2220d82 100644
--- a/tests/KdybyTests/Doctrine/Extension.phpt
+++ b/tests/KdybyTests/Doctrine/Extension.phpt
@@ -179,10 +179,12 @@ class ExtensionTest extends Tester\TestCase
$env['SESSION_ID'] = $sessionId = $compileOutput[1];
$storeOutput = self::runExternalScript(__DIR__ . '/proxies-sessions-test/run.php', ['store'], $env);
- Assert::match(\Kdyby\Doctrine\DI\OrmExtension::DEFAULT_PROXY_NAMESPACE . '\__CG__\\' . \KdybyTests\Doctrine\CmsOrder::class . ' %A%id => 1%A%status => "new"%A%', $storeOutput);
+// Assert::match(\Kdyby\Doctrine\DI\OrmExtension::DEFAULT_PROXY_NAMESPACE . '\__CG__\\' . \KdybyTests\Doctrine\CmsOrder::class . ' %A%id => 1%A%status => "new"%A%', $storeOutput);
+ Assert::match(preg_replace('/#\w+/', '', file_get_contents(__DIR__ . '/proxies-sessions-test/data/expected-tracy-dump-store')), preg_replace('/#\w+/', '', $storeOutput));
$runOutput = self::runExternalScript(__DIR__ . '/proxies-sessions-test/run.php', ['read'], $env);
- Assert::match(\Kdyby\Doctrine\DI\OrmExtension::DEFAULT_PROXY_NAMESPACE . '\__CG__\\' . \KdybyTests\Doctrine\CmsOrder::class . ' %A%id => 1%A%status => "new"%A%', $runOutput);
+// Assert::match(\Kdyby\Doctrine\DI\OrmExtension::DEFAULT_PROXY_NAMESPACE . '\__CG__\\' . \KdybyTests\Doctrine\CmsOrder::class . ' %A%id => 1%A%status => "new"%A%', $runOutput);
+ Assert::match(preg_replace('/#\w+/', '', file_get_contents(__DIR__ . '/proxies-sessions-test/data/expected-tracy-dump-read')), preg_replace('/#\w+/', '', $runOutput));
}
diff --git a/tests/KdybyTests/Doctrine/config/proxiesSessionAutoloading.neon b/tests/KdybyTests/Doctrine/config/proxiesSessionAutoloading.neon
index f7e75f57..a91c40be 100644
--- a/tests/KdybyTests/Doctrine/config/proxiesSessionAutoloading.neon
+++ b/tests/KdybyTests/Doctrine/config/proxiesSessionAutoloading.neon
@@ -1,6 +1,3 @@
-kdyby.console:
- disabled: true
-
kdyby.doctrine:
driver: pdo_sqlite
path: %tempDir%/db.sqlite
diff --git a/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-read b/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-read
new file mode 100644
index 00000000..a00acee1
--- /dev/null
+++ b/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-read
@@ -0,0 +1,6 @@
+Kdyby\GeneratedProxy\__CG__\KdybyTests\Doctrine\CmsOrder #16
+ __initializer__: null
+ __cloner__: null
+ __isInitialized__: true
+ id: 1
+ status: 'new'
\ No newline at end of file
diff --git a/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-store b/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-store
new file mode 100644
index 00000000..3f32c311
--- /dev/null
+++ b/tests/KdybyTests/Doctrine/proxies-sessions-test/data/expected-tracy-dump-store
@@ -0,0 +1,6 @@
+Kdyby\GeneratedProxy\__CG__\KdybyTests\Doctrine\CmsOrder #117
+ __initializer__: null
+ __cloner__: null
+ __isInitialized__: true
+ id: 1
+ status: 'new'
\ No newline at end of file
diff --git a/tests/KdybyTests/nette-reset.neon b/tests/KdybyTests/nette-reset.neon
index 725e12bc..06ab6e23 100644
--- a/tests/KdybyTests/nette-reset.neon
+++ b/tests/KdybyTests/nette-reset.neon
@@ -3,7 +3,7 @@ php:
extensions:
- kdyby.console: Kdyby\Console\DI\ConsoleExtension
+ console: Contributte\Console\DI\ConsoleExtension(%consoleMode%)
kdyby.annotations: Kdyby\Annotations\DI\AnnotationsExtension
kdyby.doctrine: Kdyby\Doctrine\DI\OrmExtension
@@ -15,8 +15,6 @@ kdyby.doctrine:
hydrationCache: array
-kdyby.console:
- url: http://www.kdyby.org/
http: