diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml
index 8c87214..cc71f36 100644
--- a/.github/workflows/test-application.yaml
+++ b/.github/workflows/test-application.yaml
@@ -48,10 +48,16 @@ jobs:
- php-version: '8.4'
storage: doctrine
- composer-flags: --ignore-platform-reqs
- php-version: '8.4'
storage: array
+
+ - php-version: '8.5'
+ storage: doctrine
+ composer-flags: --ignore-platform-reqs
+ - php-version: '8.5'
+ storage: array
composer-flags: --ignore-platform-reqs
+
steps:
- name: Checkout project
uses: actions/checkout@v2
diff --git a/composer.json b/composer.json
index 5495911..8edb283 100644
--- a/composer.json
+++ b/composer.json
@@ -12,24 +12,24 @@
"require": {
"php": "^8.0",
"php-task/php-task": "^3.0.1",
- "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0",
- "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
- "symfony/expression-language": "^5.4 || ^6.0 || ^7.0",
- "symfony/config": "^5.4 || ^6.0 || ^7.0",
- "symfony/console": "^5.4 || ^6.0 || ^7.0",
- "symfony/process": "^5.4 || ^6.0 || ^7.0",
+ "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/expression-language": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/config": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/process": "^5.4 || ^6.0 || ^7.0 || ^8.0",
"doctrine/orm": "^2.5.3 || ^3.0"
},
"require-dev": {
- "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
- "symfony/finder": "^5.4 || ^6.0 || ^7.0",
- "symfony/yaml": "^5.4 || ^6.0 || ^7.0",
- "doctrine/doctrine-bundle": "^1.5 || ^2.0",
- "doctrine/data-fixtures": "^1.3.3",
+ "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/finder": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/yaml": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "doctrine/doctrine-bundle": "^1.5 || ^2.0 || ^3.0",
+ "doctrine/data-fixtures": "^1.3.3 || ^2.0",
"phpunit/phpunit": "^9.6.5 || ^10",
"phpspec/prophecy": "^1.14",
"phpspec/prophecy-phpunit": "^2.0",
- "symfony/var-exporter": "^5.4 || ^6.4 || ^7.0"
+ "symfony/var-exporter": "^5.4 || ^6.4 || ^7.0 || ^8.0"
},
"autoload": {
"psr-4": {
diff --git a/src/Command/DebugTasksCommand.php b/src/Command/DebugTasksCommand.php
index 3cbd9dc..c15eabb 100644
--- a/src/Command/DebugTasksCommand.php
+++ b/src/Command/DebugTasksCommand.php
@@ -78,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$execution->getHandlerClass(),
$execution->getScheduleTime()->format(\DateTimeImmutable::RFC3339),
!$execution->getEndTime() ? '' : $execution->getEndTime()->format(\DateTimeImmutable::RFC3339),
- (round($execution->getDuration(), 6) * 1000000) . 'ms',
+ (round($execution->getDuration() ?? 0.0, 6) * 1000000) . 'ms',
]
);
}
diff --git a/src/DependencyInjection/HandlerCompilerPass.php b/src/DependencyInjection/HandlerCompilerPass.php
index f8f9284..baea178 100644
--- a/src/DependencyInjection/HandlerCompilerPass.php
+++ b/src/DependencyInjection/HandlerCompilerPass.php
@@ -27,7 +27,7 @@ class HandlerCompilerPass implements CompilerPassInterface
/**
* {@inheritdoc}
*/
- public function process(ContainerBuilder $container)
+ public function process(ContainerBuilder $container): void
{
if (!$container->has(self::REGISTRY_ID)) {
return;
diff --git a/src/DependencyInjection/TaskExtension.php b/src/DependencyInjection/TaskExtension.php
index 8f42697..d5414e4 100644
--- a/src/DependencyInjection/TaskExtension.php
+++ b/src/DependencyInjection/TaskExtension.php
@@ -11,6 +11,7 @@
namespace Task\TaskBundle\DependencyInjection;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
@@ -29,7 +30,7 @@
*/
class TaskExtension extends Extension implements PrependExtensionInterface
{
- public function prepend(ContainerBuilder $container)
+ public function prepend(ContainerBuilder $container): void
{
$configs = $container->getExtensionConfig($this->getAlias());
$configuration = $this->getConfiguration($configs, $container);
@@ -59,7 +60,7 @@ public function prepend(ContainerBuilder $container)
/**
* {@inheritdoc}
*/
- public function load(array $configs, ContainerBuilder $container)
+ public function load(array $configs, ContainerBuilder $container): void
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
@@ -71,15 +72,15 @@ public function load(array $configs, ContainerBuilder $container)
$container->setParameter('task.lock.storages.' . $key, $config['locking']['storages'][$key]);
}
- $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
- $loader->load(sprintf('storage/%s.xml', $config['storage']));
- $loader->load('task_event_listener.xml');
- $loader->load('scheduler.xml');
- $loader->load('command.xml');
- $loader->load('locking/services.xml');
+ $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
+ $loader->load(sprintf('storage/%s.php', $config['storage']));
+ $loader->load('task_event_listener.php');
+ $loader->load('scheduler.php');
+ $loader->load('command.php');
+ $loader->load('locking/services.php');
if ($config['run']['mode'] === 'listener') {
- $loader->load('listener.xml');
+ $loader->load('listener.php');
}
$this->loadDoctrineAdapter($config['adapters']['doctrine'], $container);
@@ -118,10 +119,10 @@ private function loadDoctrineAdapter(array $config, ContainerBuilder $container)
private function loadLockingComponent(array $config, ContainerBuilder $container, LoaderInterface $loader)
{
if (!$config['enabled'] || 'null' === $config['storage']) {
- return $loader->load('locking/null.xml');
+ return $loader->load('locking/null.php');
}
- $loader->load('locking/services.xml');
+ $loader->load('locking/services.php');
$container->setParameter('task.lock.ttl', $config['ttl']);
}
@@ -134,7 +135,7 @@ private function loadLockingComponent(array $config, ContainerBuilder $container
*/
private function loadExecutorComponent(array $config, ContainerBuilder $container, LoaderInterface $loader)
{
- $loader->load('executor/' . $config['type'] . '.xml');
+ $loader->load('executor/' . $config['type'] . '.php');
$container->setAlias('task.executor', 'task.executor.' . $config['type']);
if (!array_key_exists($config['type'], $config)) {
@@ -176,10 +177,10 @@ private function getLockingStorageAliases(ContainerBuilder $container)
/**
* {@inheritdoc}
*/
- public function getConfiguration(array $config, ContainerBuilder $container)
+ public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface
{
- $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
- $loader->load('locking/storages.xml');
+ $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
+ $loader->load('locking/storages.php');
return new Configuration($this->getLockingStorageAliases($container));
}
diff --git a/src/Resources/config/command.php b/src/Resources/config/command.php
new file mode 100644
index 0000000..7745615
--- /dev/null
+++ b/src/Resources/config/command.php
@@ -0,0 +1,67 @@
+services();
+
+ $services->set('task.command.run', RunCommand::class)
+ ->public()
+ ->args([
+ null,
+ service('task.runner'),
+ service('task.scheduler'),
+ // add entity_manager if doctrine storage is enabled
+ ])
+ ->tag('console.command', ['command' => 'task:run']);
+
+ $services->set('task.command.run_handler', RunHandlerCommand::class)
+ ->public()
+ ->args([
+ null,
+ service('task.handler.factory'),
+ ])
+ ->tag('console.command', ['command' => 'task:run:handler']);
+
+ $services->set('task.command.executor', ExecuteCommand::class)
+ ->public()
+ ->args([
+ null,
+ service('task.handler.factory'),
+ service('task.storage.task_execution'),
+ service('event_dispatcher'),
+ ])
+ ->tag('console.command', ['command' => 'task:execute']);
+
+ $services->set('task.command.schedule_task', ScheduleTaskCommand::class)
+ ->public()
+ ->args([
+ null,
+ service('task.scheduler'),
+ // add entity_manager if doctrine storage is enabled
+ ])
+ ->tag('console.command', ['command' => 'task:schedule']);
+
+ $services->set('task.command.debug_tasks', DebugTasksCommand::class)
+ ->public()
+ ->args([
+ null,
+ service('task.storage.task_execution'),
+ ])
+ ->tag('console.command', ['command' => 'debug:tasks']);
+};
diff --git a/src/Resources/config/command.xml b/src/Resources/config/command.xml
deleted file mode 100644
index 935e3c3..0000000
--- a/src/Resources/config/command.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- null
-
-
-
-
-
-
-
-
- null
-
-
-
-
-
-
- null
-
-
-
-
-
-
-
-
- null
-
-
-
-
-
-
-
- null
-
-
-
-
-
-
diff --git a/src/Resources/config/executor/inside.php b/src/Resources/config/executor/inside.php
new file mode 100644
index 0000000..89c92d6
--- /dev/null
+++ b/src/Resources/config/executor/inside.php
@@ -0,0 +1,21 @@
+services()
+ ->set('task.executor.inside', InsideProcessExecutor::class)
+ ->public()
+ ->args([service('task.handler.factory')]);
+};
diff --git a/src/Resources/config/executor/inside.xml b/src/Resources/config/executor/inside.xml
deleted file mode 100644
index 42ab762..0000000
--- a/src/Resources/config/executor/inside.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/Resources/config/executor/separate.php b/src/Resources/config/executor/separate.php
new file mode 100644
index 0000000..666a30c
--- /dev/null
+++ b/src/Resources/config/executor/separate.php
@@ -0,0 +1,35 @@
+services();
+
+ $services->set('task.executor.separate', SeparateProcessExecutor::class)
+ ->public()
+ ->args([
+ service('task.handler.factory'),
+ service('task.storage.task_execution'),
+ service('task.executor.separate.process_factory'),
+ ]);
+
+ $services->set('task.executor.separate.process_factory', ExecutionProcessFactory::class)
+ ->public()
+ ->args([
+ '%task.executor.console_path%',
+ '%task.executor.process_timeout%',
+ '%kernel.environment%',
+ ]);
+};
diff --git a/src/Resources/config/executor/separate.xml b/src/Resources/config/executor/separate.xml
deleted file mode 100644
index 7dc25e7..0000000
--- a/src/Resources/config/executor/separate.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- %task.executor.console_path%
- %task.executor.process_timeout%
- %kernel.environment%
-
-
-
diff --git a/src/Resources/config/listener.php b/src/Resources/config/listener.php
new file mode 100644
index 0000000..916b4f5
--- /dev/null
+++ b/src/Resources/config/listener.php
@@ -0,0 +1,22 @@
+services()
+ ->set('task.event_listener.run', RunListener::class)
+ ->public()
+ ->args([service('task.runner')])
+ ->tag('kernel.event_listener', ['event' => 'kernel.terminate', 'method' => 'run']);
+};
diff --git a/src/Resources/config/listener.xml b/src/Resources/config/listener.xml
deleted file mode 100644
index bec8ecc..0000000
--- a/src/Resources/config/listener.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Resources/config/locking/null.php b/src/Resources/config/locking/null.php
new file mode 100644
index 0000000..cd1d0e4
--- /dev/null
+++ b/src/Resources/config/locking/null.php
@@ -0,0 +1,20 @@
+services()
+ ->set('task.lock', NullLock::class)
+ ->public();
+};
diff --git a/src/Resources/config/locking/null.xml b/src/Resources/config/locking/null.xml
deleted file mode 100644
index aeb6894..0000000
--- a/src/Resources/config/locking/null.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/src/Resources/config/locking/services.php b/src/Resources/config/locking/services.php
new file mode 100644
index 0000000..cbf9bba
--- /dev/null
+++ b/src/Resources/config/locking/services.php
@@ -0,0 +1,24 @@
+services()
+ ->set('task.lock', Lock::class)
+ ->public()
+ ->args([
+ service('task.lock.storage'),
+ '%task.lock.ttl%',
+ ]);
+};
diff --git a/src/Resources/config/locking/services.xml b/src/Resources/config/locking/services.xml
deleted file mode 100644
index 570317b..0000000
--- a/src/Resources/config/locking/services.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
- %task.lock.ttl%
-
-
-
diff --git a/src/Resources/config/locking/storages.php b/src/Resources/config/locking/storages.php
new file mode 100644
index 0000000..8b89068
--- /dev/null
+++ b/src/Resources/config/locking/storages.php
@@ -0,0 +1,22 @@
+services()
+ ->set('task.lock.storage.file', FileLockStorage::class)
+ ->public()
+ ->args([expr("parameter('task.lock.storages.file')['directory']")])
+ ->tag('task.lock.storage', ['alias' => 'file']);
+};
diff --git a/src/Resources/config/locking/storages.xml b/src/Resources/config/locking/storages.xml
deleted file mode 100644
index 47d0aac..0000000
--- a/src/Resources/config/locking/storages.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- parameter('task.lock.storages.file')['directory']
-
-
-
-
-
diff --git a/src/Resources/config/scheduler.php b/src/Resources/config/scheduler.php
new file mode 100644
index 0000000..fae556e
--- /dev/null
+++ b/src/Resources/config/scheduler.php
@@ -0,0 +1,56 @@
+services();
+
+ $services->set('task.builder_factory', TaskBuilderFactory::class)
+ ->public();
+
+ $services->set('task.scheduler', TaskScheduler::class)
+ ->public()
+ ->args([
+ service('task.builder_factory'),
+ service('task.storage.task'),
+ service('task.storage.task_execution'),
+ service('event_dispatcher'),
+ ]);
+
+ $services->set('task.handler.factory', TaskHandlerFactory::class)
+ ->public()
+ ->args([[]]);
+
+ $services->set('task.runner.execution_finder', PendingExecutionFinder::class)
+ ->public()
+ ->args([
+ service('task.storage.task_execution'),
+ service('task.handler.factory'),
+ service('task.lock'),
+ service('logger')->ignoreOnInvalid(),
+ ]);
+
+ $services->set('task.runner', TaskRunner::class)
+ ->public()
+ ->args([
+ service('task.storage.task_execution'),
+ service('task.runner.execution_finder'),
+ service('task.executor'),
+ service('event_dispatcher'),
+ ]);
+};
diff --git a/src/Resources/config/scheduler.xml b/src/Resources/config/scheduler.xml
deleted file mode 100644
index 614399c..0000000
--- a/src/Resources/config/scheduler.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Resources/config/storage/array.php b/src/Resources/config/storage/array.php
new file mode 100644
index 0000000..20e3751
--- /dev/null
+++ b/src/Resources/config/storage/array.php
@@ -0,0 +1,25 @@
+services();
+
+ $services->set('task.storage.task', ArrayTaskRepository::class)
+ ->public();
+
+ $services->set('task.storage.task_execution', ArrayTaskExecutionRepository::class)
+ ->public();
+};
diff --git a/src/Resources/config/storage/array.xml b/src/Resources/config/storage/array.xml
deleted file mode 100644
index 2bd31a7..0000000
--- a/src/Resources/config/storage/array.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/Resources/config/storage/doctrine.php b/src/Resources/config/storage/doctrine.php
new file mode 100644
index 0000000..c67b34e
--- /dev/null
+++ b/src/Resources/config/storage/doctrine.php
@@ -0,0 +1,49 @@
+services();
+
+ $services->set('task.repository.task', TaskRepository::class)
+ ->public()
+ ->factory([service('doctrine.orm.entity_manager'), 'getRepository'])
+ ->args([Task::class]);
+
+ $services->alias('task.storage.task', 'task.repository.task')
+ ->public();
+
+ $services->set('task.repository.task_execution', TaskExecutionRepository::class)
+ ->public()
+ ->factory([service('doctrine.orm.entity_manager'), 'getRepository'])
+ ->args([TaskExecution::class]);
+
+ $services->alias('task.storage.task_execution', 'task.repository.task_execution')
+ ->public();
+
+ $services->set('task.command.schedule_system_tasks', ScheduleSystemTasksCommand::class)
+ ->public()
+ ->args([
+ null,
+ '%task.system_tasks%',
+ service('task.scheduler'),
+ service('task.repository.task'),
+ service('task.storage.task_execution'),
+ ])
+ ->tag('console.command', ['command' => 'task:schedule:system-tasks']);
+};
diff --git a/src/Resources/config/storage/doctrine.xml b/src/Resources/config/storage/doctrine.xml
deleted file mode 100644
index f302fb4..0000000
--- a/src/Resources/config/storage/doctrine.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
- Task\TaskBundle\Entity\Task
-
-
-
-
-
-
- Task\TaskBundle\Entity\TaskExecution
-
-
-
-
- null
- %task.system_tasks%
-
-
-
-
-
-
-
-
diff --git a/src/Resources/config/task_event_listener.php b/src/Resources/config/task_event_listener.php
new file mode 100644
index 0000000..09ad8c1
--- /dev/null
+++ b/src/Resources/config/task_event_listener.php
@@ -0,0 +1,27 @@
+parameters();
+
+ $parameters->set('task.events.create', Events::TASK_CREATE);
+ $parameters->set('task.events.create_execution', Events::TASK_EXECUTION_CREATE);
+ $parameters->set('task.events.before', Events::TASK_BEFORE);
+ $parameters->set('task.events.after', Events::TASK_AFTER);
+ $parameters->set('task.events.finished', Events::TASK_FINISHED);
+ $parameters->set('task.events.passed', Events::TASK_PASSED);
+ $parameters->set('task.events.failed', Events::TASK_FAILED);
+ $parameters->set('task.events.retried', Events::TASK_RETRIED);
+};
diff --git a/src/Resources/config/task_event_listener.xml b/src/Resources/config/task_event_listener.xml
deleted file mode 100644
index 7dad9b1..0000000
--- a/src/Resources/config/task_event_listener.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- Task\Event\Events::TASK_CREATE
- Task\Event\Events::TASK_EXECUTION_CREATE
- Task\Event\Events::TASK_BEFORE
- Task\Event\Events::TASK_AFTER
- Task\Event\Events::TASK_FINISHED
- Task\Event\Events::TASK_PASSED
- Task\Event\Events::TASK_FAILED
- Task\Event\Events::TASK_RETRIED
-
-
-
diff --git a/src/TaskBundle.php b/src/TaskBundle.php
index 36805a5..f89839e 100644
--- a/src/TaskBundle.php
+++ b/src/TaskBundle.php
@@ -11,7 +11,7 @@
*/
class TaskBundle extends Bundle
{
- public function build(ContainerBuilder $container)
+ public function build(ContainerBuilder $container): void
{
parent::build($container);
diff --git a/tests/Functional/BaseCommandTestCase.php b/tests/Functional/BaseCommandTestCase.php
index ffc29d7..127cbc6 100644
--- a/tests/Functional/BaseCommandTestCase.php
+++ b/tests/Functional/BaseCommandTestCase.php
@@ -81,7 +81,11 @@ protected function setUp(): void
$command = $this->getCommand();
$this->application = new Application(self::$kernel);
- $this->application->add($command);
+ if (method_exists($this->application, 'addCommand')) {
+ $this->application->addCommand($command);
+ } else {
+ $this->application->add($command);
+ }
$this->command = $this->application->find($command->getName());
$this->commandTester = new CommandTester($this->command);
diff --git a/tests/app/TestKernel.php b/tests/app/TestKernel.php
index 7295cf6..af03282 100644
--- a/tests/app/TestKernel.php
+++ b/tests/app/TestKernel.php
@@ -14,7 +14,7 @@
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\HttpKernel\Kernel;
use Task\TaskBundle\TaskBundle;
@@ -32,11 +32,23 @@ class TestKernel extends Kernel
*/
public function registerBundles(): array
{
- return [
+ $bundles = [
new FrameworkBundle(),
- new DoctrineBundle(),
new TaskBundle(),
];
+
+ if ('doctrine' === $this->getStorage()) {
+ $bundles[] = new DoctrineBundle();
+ }
+
+ return $bundles;
+ }
+
+ private function getStorage(): string
+ {
+ $storage = getenv(self::STORAGE_VAR_NAME);
+
+ return false === $storage ? 'array' : $storage;
}
/**
@@ -44,13 +56,56 @@ public function registerBundles(): array
*/
public function registerContainerConfiguration(LoaderInterface $loader): void
{
- $this->storage = getenv(self::STORAGE_VAR_NAME);
- if (false === $this->storage) {
- $this->storage = 'array';
- }
+ $this->storage = $this->getStorage();
$loader->load(sprintf('%s/config/config.yml', __DIR__));
$loader->load(sprintf('%s/config/config.%s.yml', __DIR__, $this->storage));
+
+ // The "doctrine.orm.enable_native_lazy_objects" option was only added in
+ // doctrine/doctrine-bundle 2.15 (which requires PHP >= 8.1). Older
+ // doctrine-bundle versions, resolved by Composer on PHP 8.0, reject this
+ // key as unrecognized, so only set it when the installed bundle supports it.
+ if ('doctrine' === $this->storage && $this->doctrineBundleSupportsNativeLazyObjects()) {
+ $loader->load(sprintf('%s/config/config.doctrine_native_lazy_objects.yml', __DIR__));
+ }
+
+ // The "doctrine.orm.auto_generate_proxy_classes" (and "proxy_dir") options
+ // were removed in doctrine/doctrine-bundle 3.0, since ORM 3.4+ no longer
+ // relies on generated proxy classes in the same way. Only set the option
+ // when the installed bundle still recognises it.
+ if ('doctrine' === $this->storage && $this->doctrineBundleSupportsAutoGenerateProxyClasses()) {
+ $loader->load(sprintf('%s/config/config.doctrine_auto_generate_proxy_classes.yml', __DIR__));
+ }
+ }
+
+ private function doctrineBundleSupportsNativeLazyObjects(): bool
+ {
+ if (!class_exists(\Composer\InstalledVersions::class)) {
+ return false;
+ }
+
+ if (!\Composer\InstalledVersions::isInstalled('doctrine/doctrine-bundle')) {
+ return false;
+ }
+
+ $version = \Composer\InstalledVersions::getVersion('doctrine/doctrine-bundle');
+
+ return null !== $version && \version_compare($version, '2.15.0', '>=');
+ }
+
+ private function doctrineBundleSupportsAutoGenerateProxyClasses(): bool
+ {
+ if (!class_exists(\Composer\InstalledVersions::class)) {
+ return true;
+ }
+
+ if (!\Composer\InstalledVersions::isInstalled('doctrine/doctrine-bundle')) {
+ return true;
+ }
+
+ $version = \Composer\InstalledVersions::getVersion('doctrine/doctrine-bundle');
+
+ return null !== $version && \version_compare($version, '3.0.0', '<');
}
/**
@@ -59,11 +114,15 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
protected function buildContainer(): ContainerBuilder
{
$container = parent::buildContainer();
- $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/config'));
- $loader->load('services.xml');
+ $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/config'));
+ $loader->load('services.php');
$container->setParameter('kernel.storage', $this->storage);
$container->setParameter('container.build_id', hash('crc32', 'Abc123423456789'));
+ // Doctrine ORM requires either native lazy objects (PHP 8.4+) or the
+ // (Symfony < 8) VarExporter-based lazy ghost implementation. Only enable
+ // native lazy objects when running on a PHP version that supports them.
+ $container->setParameter('task_test.native_lazy_objects', \PHP_VERSION_ID >= 80400);
return $container;
}
diff --git a/tests/app/config/config.doctrine.yml b/tests/app/config/config.doctrine.yml
index 5f286a8..ebd40a5 100644
--- a/tests/app/config/config.doctrine.yml
+++ b/tests/app/config/config.doctrine.yml
@@ -13,7 +13,6 @@ task:
doctrine:
orm:
- auto_generate_proxy_classes: '%kernel.debug%'
auto_mapping: false
dbal:
driver: pdo_sqlite
diff --git a/tests/app/config/config.doctrine_auto_generate_proxy_classes.yml b/tests/app/config/config.doctrine_auto_generate_proxy_classes.yml
new file mode 100644
index 0000000..d56bef3
--- /dev/null
+++ b/tests/app/config/config.doctrine_auto_generate_proxy_classes.yml
@@ -0,0 +1,3 @@
+doctrine:
+ orm:
+ auto_generate_proxy_classes: '%kernel.debug%'
diff --git a/tests/app/config/config.doctrine_native_lazy_objects.yml b/tests/app/config/config.doctrine_native_lazy_objects.yml
new file mode 100644
index 0000000..a1976d9
--- /dev/null
+++ b/tests/app/config/config.doctrine_native_lazy_objects.yml
@@ -0,0 +1,3 @@
+doctrine:
+ orm:
+ enable_native_lazy_objects: '%task_test.native_lazy_objects%'
diff --git a/tests/app/config/services.php b/tests/app/config/services.php
new file mode 100644
index 0000000..f94f64f
--- /dev/null
+++ b/tests/app/config/services.php
@@ -0,0 +1,25 @@
+services();
+
+ $services->set('test.handler', TestHandler::class)
+ ->tag('task.handler', ['handler-name' => 'test']);
+
+ $services->set('test.fail_handler', FailTestHandler::class)
+ ->tag('task.handler', ['handler-name' => 'test']);
+};
diff --git a/tests/app/config/services.xml b/tests/app/config/services.xml
deleted file mode 100644
index 7af7798..0000000
--- a/tests/app/config/services.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-