diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml index b3fd1069..15f49239 100644 --- a/.github/workflows/test-application.yaml +++ b/.github/workflows/test-application.yaml @@ -17,14 +17,10 @@ jobs: fail-fast: false matrix: include: - - php-version: "7.4" - phpunit-version: "8.5" - dependencies: "lowest" - - - php-version: "7.4" - phpunit-version: "8.5" + - php-version: "8.0" + phpunit-version: "9.5" phpunit-flags: "-v --coverage-text" - symfony-version: "^5.4" + symfony-version: "6.0.*" - php-version: "8.0" phpunit-version: "9.5" @@ -36,9 +32,13 @@ jobs: - php-version: "8.2" phpunit-version: "9.5" + - php-version: "8.3" + phpunit-version: "9.5" + symfony-version: "7.*" + steps: - name: "Checkout project" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Install and configure PHP" uses: "shivammathur/setup-php@v2" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5278955d..fc2f4047 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Changelog * Upgrade to phpcr-odm 2.0 * Support jackalope 2.0 +* Drop support for PHP 7 * Replace doctrine cache with PSR-6 cache with the symfony/cache implementation. The configuration of metadata_cache_driver changed. By default, it creates an `array` cache. To configure a service, specify `type: service` and specify your service in the `id` property. diff --git a/composer.json b/composer.json index a5e96197..3370ef85 100644 --- a/composer.json +++ b/composer.json @@ -21,36 +21,39 @@ } ], "require": { - "php": "^7.4 || ^8.0", - "phpcr/phpcr-utils": "^1.3", - "symfony/doctrine-bridge": "^5.4 || ^6.0", - "symfony/framework-bundle": "^5.4 || ^6.0", - "symfony/cache": "^5.4 || ^6.0" + "php": "^8.0", + "phpcr/phpcr-utils": "^1.3 || ^2.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, "conflict": { "doctrine/annotations": "< 1.7.0", "doctrine/doctrine-bundle": "< 2.0.3", "jackalope/jackalope": "< 1.3.1", - "phpcr/phpcr-shell": "< 1.0.0-beta1" + "phpcr/phpcr-shell": "< 1.0.0-beta1", + "symfony/dependency-injection": "< 3", + "symfony/console": "< 4" }, "require-dev": { "doctrine/doctrine-bundle": "^2.0.3", "doctrine/phpcr-odm": "^2.0", - "jackalope/jackalope-doctrine-dbal": "^1.3 || ^2.0", + "doctrine/orm": "^2.0 || ^3.0", + "jackalope/jackalope-doctrine-dbal": "^2.0", "matthiasnoback/symfony-dependency-injection-test": "^4.1", - "symfony/asset": "^5.4 || ^6.0", - "symfony/browser-kit": "^5.4 || ^6.0", - "symfony/css-selector": "^5.4 || ^6.0", + "symfony/asset": "^5.4 || ^6.0 || ^7.0", + "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0", "symfony/error-handler": "^4.4 || ^5.0 || ^6.0", - "symfony/form": "^5.4 || ^6.0", - "symfony/monolog-bridge": "^5.4 || ^6.0", + "symfony/form": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0", "symfony/monolog-bundle": "^3.4", "symfony/phpunit-bridge": "^v6.4.2 || ^v7.0.2", - "symfony/templating": "^5.4 || ^6.0", - "symfony/translation": "^5.4 || ^6.0", - "symfony/twig-bundle": "^5.4 || ^6.0", - "symfony/validator": "^5.4 || ^6.0", - "symfony/web-profiler-bundle": "^5.4 || ^6.0" + "symfony/templating": "^5.4 || ^6.0 || ^7.0", + "symfony/translation": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "burgov/key-value-form-bundle": "to edit assoc multivalue properties. require version 1.0.*", @@ -78,5 +81,6 @@ "Doctrine\\Bundle\\PHPCRBundle\\Tests\\": "tests/" } }, - "minimum-stability": "beta" + "prefer-stable": true, + "minimum-stability": "dev" } diff --git a/src/CacheWarmer/UniqueNodeTypeCacheWarmer.php b/src/CacheWarmer/UniqueNodeTypeCacheWarmer.php index 471430e7..fefceba9 100644 --- a/src/CacheWarmer/UniqueNodeTypeCacheWarmer.php +++ b/src/CacheWarmer/UniqueNodeTypeCacheWarmer.php @@ -29,12 +29,14 @@ public function isOptional(): bool return true; } - public function warmUp($cacheDir): void + public function warmUp($cacheDir): array { $helper = new UniqueNodeTypeHelper(); foreach ($this->registry->getManagers() as $documentManager) { $helper->checkNodeTypeMappings($documentManager); } + + return []; } } diff --git a/src/Command/LoadFixtureCommand.php b/src/Command/LoadFixtureCommand.php index 897eeeb9..77a7b11d 100644 --- a/src/Command/LoadFixtureCommand.php +++ b/src/Command/LoadFixtureCommand.php @@ -4,17 +4,17 @@ use Doctrine\Bundle\PHPCRBundle\DataFixtures\PHPCRExecutor; use Doctrine\Common\DataFixtures\Purger\PHPCRPurger; +use Doctrine\ODM\PHPCR\Tools\Console\Helper\DocumentManagerHelper; use InvalidArgumentException; +use PHPCR\Util\Console\Command\BaseCommand; use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\DialogHelper; -use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\DependencyInjection\ContainerAwareTrait; -use Symfony\Component\HttpKernel\KernelInterface; /** * Command to load PHPCR-ODM fixtures. @@ -24,7 +24,7 @@ * @author Jonathan H. Wage * @author Daniel Leech */ -class LoadFixtureCommand extends Command +class LoadFixtureCommand extends BaseCommand { use ContainerAwareTrait; @@ -65,28 +65,24 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $dmName = $input->getOption('dm'); // defaults to null + $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } DoctrineCommandHelper::setApplicationDocumentManager( - $this->getApplication(), + $application, $dmName ); - $dm = $this->getHelperSet()->get('phpcr')->getDocumentManager(); + $dm = $this->getPhpcrHelper()->getDocumentManager(); $noInitialize = $input->getOption('no-initialize'); if ($input->isInteractive() && !$input->getOption('append')) { $question = 'Careful, database will be purged. Do you want to continue Y/N ?'; - $default = false; - if ($this->getHelperSet()->has('question')) { - /** @var $questionHelper QuestionHelper */ - $questionHelper = $this->getHelperSet()->get('question'); - $question = new ConfirmationQuestion($question, $default); - $result = $questionHelper->ask($input, $output, $question); - } else { - /** @var $dialog DialogHelper */ - $dialog = $this->getHelperSet()->get('dialog'); - $result = $dialog->askConfirmation($output, $question, $default); - } - + $questionHelper = $this->getQuestionHelper(); + $question = new ConfirmationQuestion($question, false); + $result = $questionHelper->ask($input, $output, $question); if (!$result) { return 0; } @@ -96,8 +92,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($dirOrFile) { $paths = \is_array($dirOrFile) ? $dirOrFile : [$dirOrFile]; } else { - /** @var $kernel KernelInterface */ - $kernel = $this->getApplication()->getKernel(); + $kernel = $application->getKernel(); $projectDir = method_exists($kernel, 'getRootDir') ? $kernel->getRootDir() : $kernel->getProjectDir().'/src'; $paths = [$projectDir.'/DataFixtures/PHPCR']; foreach ($kernel->getBundles() as $bundle) { @@ -137,4 +132,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 0; } + + protected function getPhpcrHelper(): DocumentManagerHelper + { + $helper = parent::getPhpcrHelper(); + \assert($helper instanceof DocumentManagerHelper); + + return $helper; + } } diff --git a/src/Command/MigratorMigrateCommand.php b/src/Command/MigratorMigrateCommand.php index f7402d7a..026d5b21 100644 --- a/src/Command/MigratorMigrateCommand.php +++ b/src/Command/MigratorMigrateCommand.php @@ -2,14 +2,16 @@ namespace Doctrine\Bundle\PHPCRBundle\Command; -use Symfony\Component\Console\Command\Command; +use Doctrine\Bundle\PHPCRBundle\Migrator\MigratorInterface; +use PHPCR\Util\Console\Command\BaseCommand; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; -class MigratorMigrateCommand extends Command +class MigratorMigrateCommand extends BaseCommand { use ContainerAwareTrait; @@ -31,11 +33,16 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { + $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } DoctrineCommandHelper::setApplicationPHPCRSession( - $this->getApplication(), + $application, $input->getOption('session') ); - $session = $this->getHelperSet()->get('phpcr')->getSession(); + $session = $this->getPhpcrSession(); $migrators = $this->container->getParameter('doctrine_phpcr.migrate.migrators'); @@ -53,7 +60,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $migrator = $this->container->get($id); - + if (!$migrator instanceof MigratorInterface) { + throw new \InvalidArgumentException('Looked for a '.MigratorInterface::class.' but found '.($migrator ? \get_class($migrator) : $migrator)); + } $migrator->init($session, $output); $identifier = $input->getOption('identifier'); diff --git a/src/Command/NodeDumpCommand.php b/src/Command/NodeDumpCommand.php index 0267cd2b..d630c204 100644 --- a/src/Command/NodeDumpCommand.php +++ b/src/Command/NodeDumpCommand.php @@ -4,6 +4,7 @@ use PHPCR\Util\Console\Command\NodeDumpCommand as BaseDumpCommand; use PHPCR\Util\Console\Helper\PhpcrConsoleDumperHelper; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -17,7 +18,7 @@ */ class NodeDumpCommand extends BaseDumpCommand implements ContainerAwareInterface { - private ContainerInterface $container; + private ?ContainerInterface $container = null; private PhpcrConsoleDumperHelper $consoleDumper; protected function getContainer(): ContainerInterface @@ -73,4 +74,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int return parent::execute($input, $output); } + + public function getApplication(): Application + { + $application = parent::getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } + + return $application; + } } diff --git a/src/Command/NodeTypeRegisterCommand.php b/src/Command/NodeTypeRegisterCommand.php index ee92080c..71beb62b 100644 --- a/src/Command/NodeTypeRegisterCommand.php +++ b/src/Command/NodeTypeRegisterCommand.php @@ -3,6 +3,7 @@ namespace Doctrine\Bundle\PHPCRBundle\Command; use PHPCR\Util\Console\Command\NodeTypeRegisterCommand as BaseRegisterNodeTypesCommand; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -34,14 +35,19 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { + $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } + DoctrineCommandHelper::setApplicationPHPCRSession( - $this->getApplication(), + $application, $input->getOption('session'), true ); $definitions = $input->getArgument('cnd-file'); - $application = $this->getApplication(); // if no cnd-files, automatically load from bundles if (0 === \count($definitions)) { diff --git a/src/Command/PhpcrShellCommand.php b/src/Command/PhpcrShellCommand.php index 7263fc06..b5aed3a2 100644 --- a/src/Command/PhpcrShellCommand.php +++ b/src/Command/PhpcrShellCommand.php @@ -4,6 +4,8 @@ use PHPCR\Shell\Console\Application\SessionApplication; use PHPCR\Shell\PhpcrShell; +use PHPCR\Util\Console\Command\BaseCommand; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -13,7 +15,7 @@ /** * Wrapper to use this command in the symfony console with multiple sessions. */ -class PhpcrShellCommand extends Command +class PhpcrShellCommand extends BaseCommand { protected function configure(): void { @@ -59,15 +61,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int 'composer.json file to use this command' ); } - + $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } DoctrineCommandHelper::setApplicationPHPCRSession( - $this->getApplication(), + $application, $input->getOption('session') ); $args = $input->getArgument('cmd'); $launchShell = empty($args); - $session = $this->getHelper('phpcr')->getSession(); + $session = $this->getPhpcrSession(); // If no arguments supplied, launch the shell uwith the embedded application if ($launchShell) { @@ -78,8 +84,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int } // else try and run the command using the given input - $application = PhpcrShell::createEmbeddedApplication($session); - $exitCode = $application->runWithStringInput(implode(' ', $args), $output); + $phpcrApplication = PhpcrShell::createEmbeddedApplication($session); + $exitCode = $phpcrApplication->runWithStringInput(implode(' ', $args), $output); // always save the session after running a single command $session->save(); diff --git a/src/DependencyInjection/DoctrinePHPCRExtension.php b/src/DependencyInjection/DoctrinePHPCRExtension.php index a720f823..371ba103 100644 --- a/src/DependencyInjection/DoctrinePHPCRExtension.php +++ b/src/DependencyInjection/DoctrinePHPCRExtension.php @@ -503,7 +503,6 @@ private function loadOdmDocumentManagerMappingInformation(array $documentManager // reset state of drivers and alias map. They are only used by this methods and children. $this->drivers = []; $this->aliasMap = []; - $this->bundleDirs = []; if (!class_exists(Generic::class)) { throw new \RuntimeException('PHPCR ODM is activated in the config but does not seem loadable.'); diff --git a/src/DoctrinePHPCRBundle.php b/src/DoctrinePHPCRBundle.php index 9b69c103..49c70201 100644 --- a/src/DoctrinePHPCRBundle.php +++ b/src/DoctrinePHPCRBundle.php @@ -19,7 +19,6 @@ use Symfony\Component\Console\Application; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\IntrospectableContainerInterface; use Symfony\Component\HttpKernel\Bundle\Bundle; class DoctrinePHPCRBundle extends Bundle @@ -123,10 +122,6 @@ private function clearDocumentManagers(): void } foreach ($this->container->getParameter('doctrine_phpcr.odm.document_managers') as $id) { - if ($this->container instanceof IntrospectableContainerInterface && !$this->container->initialized($id)) { - continue; - } - $this->container->get($id)->clear(); } } @@ -141,10 +136,6 @@ private function closeConnections(): void } foreach ($this->container->getParameter('doctrine_phpcr.sessions') as $id) { - if ($this->container instanceof IntrospectableContainerInterface && !$this->container->initialized($id)) { - continue; - } - $session = $this->container->get($id); if (!$session instanceof Session) { return; diff --git a/src/EventListener/JackalopeDoctrineDbalSchemaListener.php b/src/EventListener/JackalopeDoctrineDbalSchemaListener.php index 5486c0b0..86bd43f7 100644 --- a/src/EventListener/JackalopeDoctrineDbalSchemaListener.php +++ b/src/EventListener/JackalopeDoctrineDbalSchemaListener.php @@ -17,6 +17,9 @@ */ class JackalopeDoctrineDbalSchemaListener { + /** + * @var RepositorySchema + */ private $schema; public function __construct(RepositorySchema $schema) diff --git a/src/Form/PhpcrOdmTypeGuesser.php b/src/Form/PhpcrOdmTypeGuesser.php index 95a15b36..ffe3d5a7 100644 --- a/src/Form/PhpcrOdmTypeGuesser.php +++ b/src/Form/PhpcrOdmTypeGuesser.php @@ -5,7 +5,7 @@ use Doctrine\Bundle\PHPCRBundle\Form\Type\DocumentType; use Doctrine\Bundle\PHPCRBundle\Form\Type\PathType; use Doctrine\Bundle\PHPCRBundle\ManagerRegistryInterface; -use Doctrine\ODM\PHPCR\DocumentManager; +use Doctrine\ODM\PHPCR\DocumentManagerInterface; use Doctrine\ODM\PHPCR\Mapping\ClassMetadata; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -208,15 +208,16 @@ public function guessRequired(string $class, string $property): ?ValueGuess return new ValueGuess(false, Guess::MEDIUM_CONFIDENCE); } - if ($metadata->hasAssociation($property)) { - if ($property === $metadata->parentMapping - && ClassMetadata::GENERATOR_TYPE_ASSIGNED !== $metadata->idGenerator - ) { - return new ValueGuess(true, Guess::HIGH_CONFIDENCE); - } - - return new ValueGuess(false, Guess::LOW_CONFIDENCE); + if (!$metadata->hasAssociation($property)) { + return null; + } + if ($property === $metadata->parentMapping + && ClassMetadata::GENERATOR_TYPE_ASSIGNED !== $metadata->idGenerator + ) { + return new ValueGuess(true, Guess::HIGH_CONFIDENCE); } + + return new ValueGuess(false, Guess::LOW_CONFIDENCE); } public function guessPattern(string $class, string $property): ?ValueGuess @@ -225,7 +226,7 @@ public function guessPattern(string $class, string $property): ?ValueGuess } /** - * @return array{0: ClassMetadata, 1: DocumentManager}|null + * @return array{0: ClassMetadata, 1: DocumentManagerInterface}|null */ private function getMetadata(string $class): ?array { diff --git a/src/Initializer/InitializerManager.php b/src/Initializer/InitializerManager.php index f1b33192..6561d87b 100644 --- a/src/Initializer/InitializerManager.php +++ b/src/Initializer/InitializerManager.php @@ -19,6 +19,11 @@ class InitializerManager private ManagerRegistryInterface $registry; private ?\Closure $loggingClosure = null; + /** + * @var InitializerInterface[] + */ + private array $sortedInitializers; + public function __construct(ManagerRegistryInterface $registry) { $this->registry = $registry; @@ -58,10 +63,10 @@ public function initialize(string $sessionName = null): void // handle specified session if present if ($sessionName) { - if (\in_array(SessionAwareInitializerInterface::class, class_implements($initializer))) { + if ($initializer instanceof SessionAwareInitializerInterface) { $initializer->setSessionName($sessionName); } elseif ($loggingClosure) { - $loggingClosure(sprintf('Initializer "%s" does not implement SessionAwareInitializerInterface, "session" parameter will be ommitted.', $initializer->getName())); + $loggingClosure(sprintf('Initializer "%s" does not implement SessionAwareInitializerInterface, "session" parameter will be omitted.', $initializer->getName())); } } diff --git a/src/ManagerRegistry.php b/src/ManagerRegistry.php index e6f682cc..77ded2a4 100644 --- a/src/ManagerRegistry.php +++ b/src/ManagerRegistry.php @@ -58,22 +58,34 @@ public function getAliasNamespace($alias): string public function getManager($name = null): DocumentManagerInterface { - return parent::getManager($name); + $dm = parent::getManager($name); + \assert($dm instanceof DocumentManagerInterface); + + return $dm; } public function resetManager($name = null): DocumentManagerInterface { - return parent::resetManager($name); + $dm = parent::resetManager($name); + \assert($dm instanceof DocumentManagerInterface); + + return $dm; } public function getManagerForClass($class = null): ?DocumentManagerInterface { - return parent::getManagerForClass($class); + $dm = parent::getManagerForClass($class); + \assert(null === $dm || $dm instanceof DocumentManagerInterface); + + return $dm; } public function getConnection($name = null): SessionInterface { - return parent::getConnection($name); + $conn = parent::getConnection($name); + \assert($conn instanceof SessionInterface); + + return $conn; } /** @@ -92,6 +104,9 @@ public function getAdminConnection(?string $name = null): SessionInterface throw new \InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->getName(), $name)); } - return $this->getService($serviceName); + $connection = $this->getService($serviceName); + \assert($connection instanceof SessionInterface); + + return $connection; } } diff --git a/src/OptionalCommand/Jackalope/InitDoctrineDbalCommand.php b/src/OptionalCommand/Jackalope/InitDoctrineDbalCommand.php index e53c4930..ef6f42d3 100644 --- a/src/OptionalCommand/Jackalope/InitDoctrineDbalCommand.php +++ b/src/OptionalCommand/Jackalope/InitDoctrineDbalCommand.php @@ -4,6 +4,7 @@ use Doctrine\Bundle\PHPCRBundle\Command\DoctrineCommandHelper; use Jackalope\Tools\Console\Command\InitDoctrineDbalCommand as BaseInitDoctrineDbalCommand; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -26,6 +27,11 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } + $sessionName = $input->getOption('session'); if (empty($sessionName)) { $container = $application->getKernel()->getContainer(); diff --git a/src/OptionalCommand/Jackalope/JackrabbitCommand.php b/src/OptionalCommand/Jackalope/JackrabbitCommand.php index c4968cb6..baead9d4 100644 --- a/src/OptionalCommand/Jackalope/JackrabbitCommand.php +++ b/src/OptionalCommand/Jackalope/JackrabbitCommand.php @@ -3,6 +3,7 @@ namespace Doctrine\Bundle\PHPCRBundle\OptionalCommand\Jackalope; use Jackalope\Tools\Console\Command\JackrabbitCommand as BaseJackrabbitCommand; +use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; @@ -15,15 +16,18 @@ */ class JackrabbitCommand extends BaseJackrabbitCommand implements ContainerAwareInterface { - /** - * @var ContainerInterface - */ - private $container; + private ?ContainerInterface $container = null; protected function getContainer(): ContainerInterface { if (null === $this->container) { - $this->container = $this->getApplication()->getKernel()->getContainer(); + $application = $this->getApplication(); + if (!$application instanceof Application) { + throw new \InvalidArgumentException('Expected to find '.Application::class.' but got '. + ($application ? \get_class($application) : null)); + } + + $this->container = $application->getKernel()->getContainer(); } return $this->container;