diff --git a/config/doctrine/LogRecord.orm.xml b/config/doctrine/LogRecord.orm.xml
new file mode 100644
index 0000000..6e24eef
--- /dev/null
+++ b/config/doctrine/LogRecord.orm.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/doctrine/ProcessExecution.orm.xml b/config/doctrine/ProcessExecution.orm.xml
new file mode 100644
index 0000000..829d703
--- /dev/null
+++ b/config/doctrine/ProcessExecution.orm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/doctrine/ProcessSchedule.orm.xml b/config/doctrine/ProcessSchedule.orm.xml
new file mode 100644
index 0000000..ae78b65
--- /dev/null
+++ b/config/doctrine/ProcessSchedule.orm.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/doctrine/User.orm.xml b/config/doctrine/User.orm.xml
new file mode 100644
index 0000000..7d12574
--- /dev/null
+++ b/config/doctrine/User.orm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/services/command.yaml b/config/services/command.yaml
index e8f5c9f..5fa8eb4 100644
--- a/config/services/command.yaml
+++ b/config/services/command.yaml
@@ -5,6 +5,7 @@ services:
tags:
- { name: console.command }
arguments:
+ - '%cleverage_ui_process.entity.user.class%'
- '@validator'
- '@security.user_password_hasher'
- '@doctrine.orm.entity_manager'
diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml
index 1a35949..f1205a0 100644
--- a/config/services/event_subscriber.yaml
+++ b/config/services/event_subscriber.yaml
@@ -5,6 +5,7 @@ services:
tags:
- { name: 'kernel.event_subscriber' }
arguments:
+ - '%cleverage_ui_process.entity.process_execution.class%'
- '@cleverage_ui_process.monolog_handler.process'
- '@cleverage_ui_process.monolog_handler.doctrine_process'
- '@cleverage_ui_process.manager.process_execution'
diff --git a/config/services/monolog_handler.yaml b/config/services/monolog_handler.yaml
index 1bd99b8..c506f49 100644
--- a/config/services/monolog_handler.yaml
+++ b/config/services/monolog_handler.yaml
@@ -5,6 +5,7 @@ services:
calls:
- [ setEntityManager, [ '@doctrine.orm.entity_manager' ] ]
- [ setProcessExecutionManager, [ '@cleverage_ui_process.manager.process_execution' ] ]
+ - [ setLogRecordClassName, [ '%cleverage_ui_process.entity.log_record.class%' ] ]
CleverAge\UiProcessBundle\Monolog\Handler\DoctrineProcessHandler:
alias: cleverage_ui_process.monolog_handler.doctrine_process
diff --git a/config/services/repository.yaml b/config/services/repository.yaml
index 6e8a5bd..f11bf14 100644
--- a/config/services/repository.yaml
+++ b/config/services/repository.yaml
@@ -4,10 +4,19 @@ services:
public: false
arguments:
- '@doctrine.orm.entity_manager'
+ - '%cleverage_ui_process.entity.process_execution.class%'
+ - '%cleverage_ui_process.entity.log_record.class%'
cleverage_ui_process.repository.process_schedule:
class: CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository
public: false
arguments:
- - '@doctrine'
+ - '@doctrine.orm.entity_manager'
+ - '%cleverage_ui_process.entity.process_schedule.class%'
+ cleverage_ui_process.repository.user:
+ class: CleverAge\UiProcessBundle\Repository\UserRepository
+ public: false
+ arguments:
+ - '@doctrine.orm.entity_manager'
+ - '%cleverage_ui_process.entity.user.class%'
diff --git a/config/services/security.yaml b/config/services/security.yaml
index 2eda664..cd2ccbf 100644
--- a/config/services/security.yaml
+++ b/config/services/security.yaml
@@ -3,5 +3,5 @@ services:
class: CleverAge\UiProcessBundle\Security\HttpProcessExecutionAuthenticator
public: false
arguments:
- - '@doctrine.orm.entity_manager'
+ - '@cleverage_ui_process.repository.user'
diff --git a/config/validation/ProcessSchedule.orm.xml b/config/validation/ProcessSchedule.orm.xml
new file mode 100644
index 0000000..faaf797
--- /dev/null
+++ b/config/validation/ProcessSchedule.orm.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/index.md b/docs/index.md
index db90d03..1b7d8e3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -19,6 +19,82 @@ Remember to add the following line to `config/bundles.php` (not required if Symf
CleverAge\UiProcessBundle\CleverAgeUiProcessBundle::class => ['all' => true],
```
+## Doctrine ORM Configuration
+
+Add these in the config mapping definition (or enable [auto_mapping](https://symfony.com/doc/current/reference/configuration/doctrine.html#mapping-configuration)):
+
+```yaml
+# config/packages/doctrine.yaml
+
+doctrine:
+ orm:
+ mappings:
+ CleverAgeUiProcessBundle: ~
+```
+
+And then create the corresponding entities:
+
+```php
+// src/Entity/LogRecord.php
+
+use Doctrine\ORM\Mapping as ORM;
+use CleverAge\UiProcessBundle\Entity\LogRecord as BaseLogRecord;
+
+#[ORM\Entity]
+#[ORM\Table]
+class LogRecord extends BaseLogRecord
+{
+}
+```
+
+```php
+// src/Entity/ProcessExecution.php
+
+use Doctrine\ORM\Mapping as ORM;
+use CleverAge\UiProcessBundle\Entity\ProcessExecution as BaseProcessExecution;
+
+#[ORM\Entity]
+#[ORM\Table]
+class ProcessExecution extends BaseProcessExecution
+{
+}
+```
+
+```php
+// src/Entity/ProcessSchedule.php
+
+use Doctrine\ORM\Mapping as ORM;
+use CleverAge\UiProcessBundle\Entity\ProcessSchedule as BaseProcessSchedule;
+
+#[ORM\Entity]
+#[ORM\Table]
+class ProcessSchedule extends BaseProcessSchedule
+{
+}
+```
+
+```php
+// src/Entity/User.php
+
+use Doctrine\ORM\Mapping as ORM;
+use CleverAge\UiProcessBundle\Entity\User as BaseUser;
+
+#[ORM\Entity]
+#[ORM\Table(name: 'process_user')]
+class User extends BaseUser
+{
+}
+```
+
+So, update your schema:
+
+```bash
+bin/console doctrine:schema:update --force
+```
+or use [DoctrineMigrationsBundle](https://github.com/doctrine/DoctrineMigrationsBundle)
+
+And create a User using `cleverage:ui-process:user-create` console.
+
## Import routes
```yaml
@@ -26,8 +102,6 @@ ui-process-bundle:
resource: '@CleverAgeUiProcessBundle/src/Controller'
type: attribute
```
-* Run doctrine migration
-* Create a user using `cleverage:ui-process:user-create` console.
Now you can access UI Process via http://your-domain.com/process
diff --git a/src/CleverAgeUiProcessBundle.php b/src/CleverAgeUiProcessBundle.php
index 8acf1d7..d507312 100644
--- a/src/CleverAgeUiProcessBundle.php
+++ b/src/CleverAgeUiProcessBundle.php
@@ -13,10 +13,20 @@
namespace CleverAge\UiProcessBundle;
+use CleverAge\UiProcessBundle\DependencyInjection\Compiler\ResolveTargetEntityPass;
+use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CleverAgeUiProcessBundle extends Bundle
{
+ public function build(ContainerBuilder $container)
+ {
+ parent::build($container);
+
+ $container->addCompilerPass(new ResolveTargetEntityPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1000);
+ }
+
public function getPath(): string
{
return \dirname(__DIR__);
diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php
index 806cc0c..c73f056 100644
--- a/src/Command/UserCreateCommand.php
+++ b/src/Command/UserCreateCommand.php
@@ -13,7 +13,7 @@
namespace CleverAge\UiProcessBundle\Command;
-use CleverAge\UiProcessBundle\Entity\User;
+use CleverAge\UiProcessBundle\Entity\UserInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
@@ -35,7 +35,11 @@
)]
class UserCreateCommand extends Command
{
+ /**
+ * @param class-string $userClassName
+ */
public function __construct(
+ private readonly string $userClassName,
private readonly ValidatorInterface $validator,
private readonly UserPasswordHasherInterface $passwordEncoder,
private readonly EntityManagerInterface $em,
@@ -54,7 +58,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output
);
- $user = new User();
+ /** @var UserInterface $user */
+ $user = new $this->userClassName();
$user->setEmail($username);
$user->setRoles(['ROLE_USER', 'ROLE_ADMIN']);
$user->setPassword($this->passwordEncoder->hashPassword($user, $password));
diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php
index 8f6bed5..340a508 100644
--- a/src/Controller/Admin/Process/LaunchAction.php
+++ b/src/Controller/Admin/Process/LaunchAction.php
@@ -14,7 +14,7 @@
namespace CleverAge\UiProcessBundle\Controller\Admin\Process;
use CleverAge\ProcessBundle\Exception\MissingProcessException;
-use CleverAge\UiProcessBundle\Entity\User;
+use CleverAge\UiProcessBundle\Entity\UserInterface;
use CleverAge\UiProcessBundle\Form\Type\LaunchType;
use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager;
use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage;
@@ -130,9 +130,9 @@ protected function dispatch(string $processCode, mixed $input = null, array $con
$this->messageBus->dispatch($message);
}
- protected function getUser(): ?User
+ protected function getUser(): ?UserInterface
{
- /** @var User $user */
+ /** @var UserInterface $user */
$user = parent::getUser();
return $user;
diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php
index 5e60a60..8071bfb 100644
--- a/src/Controller/Admin/ProcessExecutionCrudController.php
+++ b/src/Controller/Admin/ProcessExecutionCrudController.php
@@ -16,7 +16,7 @@
use CleverAge\UiProcessBundle\Admin\Field\ContextField;
use CleverAge\UiProcessBundle\Admin\Field\EnumField;
use CleverAge\UiProcessBundle\Entity\ProcessExecution;
-use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository;
+use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepositoryInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
@@ -36,7 +36,7 @@
class ProcessExecutionCrudController extends AbstractCrudController
{
public function __construct(
- private readonly ProcessExecutionRepository $processExecutionRepository,
+ private readonly ProcessExecutionRepositoryInterface $processExecutionRepository,
private readonly string $logDirectory,
) {
}
@@ -123,9 +123,8 @@ public function showLogs(AdminContext $adminContext): RedirectResponse
return $this->redirect($url);
}
- public function downloadLogFile(
- AdminContext $context,
- ): Response {
+ public function downloadLogFile(AdminContext $context): Response
+ {
/** @var ProcessExecution $processExecution */
$processExecution = $context->getEntity()->getInstance();
$filepath = $this->getLogFilePath($processExecution);
@@ -149,7 +148,7 @@ public function configureFilters(Filters $filters): Filters
private function getLogFilePath(ProcessExecution $processExecution): string
{
return $this->logDirectory.
- \DIRECTORY_SEPARATOR.$processExecution->code.
+ \DIRECTORY_SEPARATOR.$processExecution->getCode().
\DIRECTORY_SEPARATOR.$processExecution->logFilename
;
}
diff --git a/src/DependencyInjection/CleverAgeUiProcessExtension.php b/src/DependencyInjection/CleverAgeUiProcessExtension.php
index 2b7b302..fb0011e 100644
--- a/src/DependencyInjection/CleverAgeUiProcessExtension.php
+++ b/src/DependencyInjection/CleverAgeUiProcessExtension.php
@@ -33,12 +33,18 @@ public function load(array $configs, ContainerBuilder $container): void
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
+
$container->getDefinition(UserCrudController::class)
->setArgument('$roles', array_combine($config['security']['roles'], $config['security']['roles']));
$container->getDefinition('cleverage_ui_process.monolog_handler.process')
->addMethodCall('setReportIncrementLevel', [$config['logs']['report_increment_level']]);
$container->getDefinition(ProcessDashboardController::class)
->setArgument('$logoPath', $config['design']['logo_path']);
+
+ $container->setParameter('cleverage_ui_process.entity.log_record.class', $config['class']['log_record']);
+ $container->setParameter('cleverage_ui_process.entity.process_execution.class', $config['class']['process_execution']);
+ $container->setParameter('cleverage_ui_process.entity.process_schedule.class', $config['class']['process_schedule']);
+ $container->setParameter('cleverage_ui_process.entity.user.class', $config['class']['user']);
}
/**
diff --git a/src/DependencyInjection/Compiler/ResolveTargetEntityPass.php b/src/DependencyInjection/Compiler/ResolveTargetEntityPass.php
new file mode 100644
index 0000000..c8ff1ae
--- /dev/null
+++ b/src/DependencyInjection/Compiler/ResolveTargetEntityPass.php
@@ -0,0 +1,32 @@
+findDefinition('doctrine.orm.listeners.resolve_target_entity')
+ ->addMethodCall(
+ 'addResolveTargetEntity',
+ [ProcessExecutionInterface::class, $container->getParameter('cleverage_ui_process.entity.process_execution.class'), []],
+ )
+ ->addTag('doctrine.event_listener', ['event' => Events::loadClassMetadata])
+ ->addTag('doctrine.event_listener', ['event' => Events::onClassMetadataNotFound])
+ ;
+ }
+}
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 4dd50a6..4b15261 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -25,12 +25,23 @@ public function getConfigTreeBuilder(): TreeBuilder
$tb = new TreeBuilder('clever_age_ui_process');
/** @var ArrayNodeDefinition $rootNode */
$rootNode = $tb->getRootNode();
+ $rootNode
+ ->children()
+ ->arrayNode('class')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('log_record')->defaultValue('App\Entity\LogRecord')->end()
+ ->scalarNode('process_execution')->defaultValue('App\Entity\ProcessExecution')->end()
+ ->scalarNode('process_schedule')->defaultValue('App\Entity\ProcessSchedule')->end()
+ ->scalarNode('user')->defaultValue('App\Entity\User')->end()
+ ->end();
$rootNode
->children()
->arrayNode('security')
->addDefaultsIfNotSet()
->children()
- ->arrayNode('roles')->defaultValue(['ROLE_ADMIN'])->scalarPrototype()->end(); // Roles displayed inside user edit form
+ ->arrayNode('roles')->defaultValue(['ROLE_ADMIN'])->scalarPrototype() // Roles displayed inside user edit form
+ ->end();
$rootNode
->children()
->arrayNode('logs')
diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php
index 2a9c25f..2a46c84 100644
--- a/src/Entity/LogRecord.php
+++ b/src/Entity/LogRecord.php
@@ -13,47 +13,25 @@
namespace CleverAge\UiProcessBundle\Entity;
-use Doctrine\DBAL\Types\Types;
-use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\String\UnicodeString;
-#[ORM\Entity]
-#[ORM\Index(name: 'idx_log_record_level', columns: ['level'])]
-#[ORM\Index(name: 'idx_log_record_created_at', columns: ['created_at'])]
-class LogRecord
+class LogRecord implements LogRecordInterface
{
- #[ORM\Id]
- #[ORM\GeneratedValue]
- #[ORM\Column]
- private ?int $id = null;
+ protected ?int $id = null;
- #[ORM\Column(type: Types::STRING, length: 64)]
public readonly string $channel;
- #[ORM\Column(type: Types::INTEGER)]
public readonly int $level;
- #[ORM\Column(type: Types::STRING, length: 512)]
public readonly string $message;
- /** @var array $context */
- #[ORM\Column(type: Types::JSON)]
+ /** @var array */
public readonly array $context;
- #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
public readonly \DateTimeImmutable $createdAt;
- public function getId(): ?int
+ public function __construct(\Monolog\LogRecord $record, protected readonly ProcessExecutionInterface $processExecution)
{
- return $this->id;
- }
-
- public function __construct(
- \Monolog\LogRecord $record,
- #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])]
- #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE', nullable: false)]
- private readonly ProcessExecution $processExecution,
- ) {
$this->channel = (string) (new UnicodeString($record->channel))->truncate(64);
$this->level = $record->level->value;
$this->message = (string) (new UnicodeString($record->message))->truncate(512);
@@ -61,6 +39,11 @@ public function __construct(
$this->createdAt = \DateTimeImmutable::createFromMutable(new \DateTime());
}
+ public function getId(): ?int
+ {
+ return $this->id;
+ }
+
public function contextIsEmpty(): bool
{
return [] !== $this->context;
diff --git a/src/Entity/LogRecordInterface.php b/src/Entity/LogRecordInterface.php
new file mode 100644
index 0000000..e0954a7
--- /dev/null
+++ b/src/Entity/LogRecordInterface.php
@@ -0,0 +1,19 @@
+
*/
- #[ORM\Column(type: Types::JSON)]
- private array $report = [];
+ protected array $report = [];
/**
* @var array
*/
- #[ORM\Column(type: Types::JSON, nullable: true)]
- private ?array $context = [];
-
- public function getId(): ?int
- {
- return $this->id;
- }
+ protected array $context;
/**
- * @param array $context
+ * @param ?array $context
*/
- public function __construct(
- string $code,
- #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename,
- ?array $context = [],
- ) {
+ public function __construct(string $code, public readonly string $logFilename, ?array $context = [])
+ {
$this->code = (string) (new UnicodeString($code))->truncate(255);
$this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime());
$this->context = $context ?? [];
@@ -75,28 +53,19 @@ public function __toString(): string
return \sprintf('%s (%s)', $this->id, $this->code);
}
- public function setStatus(ProcessExecutionStatus $status): void
- {
- $this->status = $status;
- }
-
- public function end(): void
+ public function getId(): ?int
{
- $this->endDate = \DateTimeImmutable::createFromMutable(new \DateTime());
+ return $this->id;
}
- public function addReport(string $key, mixed $value): void
+ public function getCode(): string
{
- $this->report[$key] = $value;
+ return $this->code;
}
- public function getReport(?string $key = null, mixed $default = null): mixed
+ public function end(): void
{
- if (null === $key) {
- return $this->report;
- }
-
- return $this->report[$key] ?? $default;
+ $this->endDate = \DateTimeImmutable::createFromMutable(new \DateTime());
}
public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string
@@ -109,24 +78,36 @@ public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string
return $diff->format($format);
}
- public function getCode(): string
+ public function setStatus(ProcessExecutionStatus $status): static
{
- return $this->code;
+ $this->status = $status;
+
+ return $this;
}
- /**
- * @return array
- */
- public function getContext(): ?array
+ public function addReport(string $key, mixed $value): void
+ {
+ $this->report[$key] = $value;
+ }
+
+ public function getReport(?string $key = null, mixed $default = null): mixed
+ {
+ if (null === $key) {
+ return $this->report;
+ }
+
+ return $this->report[$key] ?? $default;
+ }
+
+ public function getContext(): array
{
return $this->context;
}
- /**
- * @param array $context
- */
- public function setContext(array $context): void
+ public function setContext(array $context): static
{
$this->context = $context;
+
+ return $this;
}
}
diff --git a/src/Entity/ProcessExecutionInterface.php b/src/Entity/ProcessExecutionInterface.php
new file mode 100644
index 0000000..fd23bbb
--- /dev/null
+++ b/src/Entity/ProcessExecutionInterface.php
@@ -0,0 +1,41 @@
+
+ */
+ public function getContext(): array;
+
+ /**
+ * @param array $context
+ */
+ public function setContext(array $context): static;
+}
diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php
index 8eea928..e8d5045 100644
--- a/src/Entity/ProcessSchedule.php
+++ b/src/Entity/ProcessSchedule.php
@@ -14,45 +14,23 @@
namespace CleverAge\UiProcessBundle\Entity;
use CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType;
-use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository;
-use CleverAge\UiProcessBundle\Validator\CronExpression;
-use CleverAge\UiProcessBundle\Validator\EveryExpression;
-use CleverAge\UiProcessBundle\Validator\IsValidProcessCode;
-use Doctrine\DBAL\Types\Types;
-use Doctrine\ORM\Mapping as ORM;
-use Symfony\Component\Validator\Constraints as Assert;
-
-#[ORM\Entity(repositoryClass: ProcessScheduleRepository::class)]
-class ProcessSchedule
+
+class ProcessSchedule implements ProcessScheduleInterface
{
- #[ORM\Id]
- #[ORM\GeneratedValue]
- #[ORM\Column]
- private ?int $id = null;
-
- #[ORM\Column(length: 255)]
- #[IsValidProcessCode]
- private string $process;
-
- #[ORM\Column(length: 6)]
- private ProcessScheduleType $type;
- #[ORM\Column(length: 255)]
- #[Assert\When(
- expression: 'this.getType().value == "cron"', constraints: [new CronExpression()]
- )]
- #[Assert\When(
- expression: 'this.getType().value == "every"', constraints: [new EveryExpression()]
- )]
- private string $expression;
-
- #[ORM\Column(type: Types::TEXT, nullable: true)]
- private ?string $input = null;
+ protected ?int $id = null;
+
+ protected string $process;
+
+ protected ProcessScheduleType $type;
+
+ protected string $expression;
+
+ protected ?string $input = null;
/**
- * @var string|array
+ * @var array
*/
- #[ORM\Column(type: Types::JSON)]
- private string|array $context = [];
+ protected array $context = [];
public function getId(): ?int
{
@@ -71,22 +49,6 @@ public function setProcess(string $process): static
return $this;
}
- /**
- * @return array
- */
- public function getContext(): array
- {
- return \is_array($this->context) ? $this->context : json_decode($this->context);
- }
-
- /**
- * @param array $context
- */
- public function setContext(array $context): void
- {
- $this->context = $context;
- }
-
public function getNextExecution(): null
{
return null;
@@ -97,7 +59,7 @@ public function getType(): ProcessScheduleType
return $this->type;
}
- public function setType(ProcessScheduleType $type): self
+ public function setType(ProcessScheduleType $type): static
{
$this->type = $type;
@@ -109,7 +71,7 @@ public function getExpression(): ?string
return $this->expression;
}
- public function setExpression(string $expression): self
+ public function setExpression(string $expression): static
{
$this->expression = $expression;
@@ -121,10 +83,22 @@ public function getInput(): ?string
return $this->input;
}
- public function setInput(?string $input): self
+ public function setInput(?string $input): static
{
$this->input = $input;
return $this;
}
+
+ public function getContext(): array
+ {
+ return $this->context;
+ }
+
+ public function setContext(array $context): static
+ {
+ $this->context = $context;
+
+ return $this;
+ }
}
diff --git a/src/Entity/ProcessScheduleInterface.php b/src/Entity/ProcessScheduleInterface.php
new file mode 100644
index 0000000..6187b7b
--- /dev/null
+++ b/src/Entity/ProcessScheduleInterface.php
@@ -0,0 +1,47 @@
+
+ */
+ public function getContext(): array;
+
+ /**
+ * @param array $context
+ */
+ public function setContext(array $context): static;
+}
diff --git a/src/Entity/User.php b/src/Entity/User.php
index 11532f7..84c1df4 100644
--- a/src/Entity/User.php
+++ b/src/Entity/User.php
@@ -13,47 +13,28 @@
namespace CleverAge\UiProcessBundle\Entity;
-use Doctrine\DBAL\Types\Types;
-use Doctrine\ORM\Mapping as ORM;
-use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
-use Symfony\Component\Security\Core\User\UserInterface;
-
-#[ORM\Entity]
-#[ORM\Table(name: 'process_user')]
-#[ORM\Index(name: 'idx_process_user_email', columns: ['email'])]
-class User implements UserInterface, PasswordAuthenticatedUserInterface
+class User implements UserInterface
{
- #[ORM\Id]
- #[ORM\GeneratedValue]
- #[ORM\Column]
- private ?int $id = null;
+ protected ?int $id = null;
- #[ORM\Column(type: Types::STRING, length: 255, unique: true)]
- private string $email;
+ protected string $email;
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $firstname = null;
+ protected ?string $firstname = null;
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $lastname = null;
+ protected ?string $lastname = null;
/**
* @var string[]
*/
- #[ORM\Column(type: Types::JSON)]
- private array $roles = [];
+ protected array $roles = [];
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $password = null;
+ protected ?string $password = null;
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $timezone = null;
+ protected ?string $timezone = null;
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $locale = null;
+ protected ?string $locale = null;
- #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
- private ?string $token = null;
+ protected ?string $token = null;
public function getId(): ?int
{
@@ -65,19 +46,24 @@ public function getEmail(): ?string
return $this->email;
}
- public function setEmail(string $email): self
+ public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
+ public function getUsername(): string
+ {
+ return $this->getUserIdentifier();
+ }
+
public function getFirstname(): ?string
{
return $this->firstname;
}
- public function setFirstname(?string $firstname): self
+ public function setFirstname(?string $firstname): static
{
$this->firstname = $firstname;
@@ -89,74 +75,57 @@ public function getLastname(): ?string
return $this->lastname;
}
- public function setLastname(?string $lastname): self
+ public function setLastname(?string $lastname): static
{
$this->lastname = $lastname;
return $this;
}
- public function getUserIdentifier(): string
- {
- if ('' === $this->email) {
- throw new \LogicException('The User class must have an email.');
- }
-
- return $this->email;
- }
-
- public function getUsername(): string
- {
- return $this->getUserIdentifier();
- }
-
- public function getTimezone(): ?string
+ public function getRoles(): array
{
- return $this->timezone;
+ return array_merge(['ROLE_USER'], $this->roles);
}
- public function setTimezone(?string $timezone): self
+ public function setRoles(array $roles): static
{
- $this->timezone = $timezone;
+ $this->roles = $roles;
return $this;
}
- public function getLocale(): ?string
+ public function getPassword(): ?string
{
- return $this->locale;
+ return $this->password;
}
- public function setLocale(?string $locale): self
+ public function setPassword(string $password): static
{
- $this->locale = $locale;
+ $this->password = $password;
return $this;
}
- public function getRoles(): array
+ public function getTimezone(): ?string
{
- return array_merge(['ROLE_USER'], $this->roles);
+ return $this->timezone;
}
- /**
- * @param array $roles
- */
- public function setRoles(array $roles): self
+ public function setTimezone(?string $timezone): static
{
- $this->roles = $roles;
+ $this->timezone = $timezone;
return $this;
}
- public function getPassword(): ?string
+ public function getLocale(): ?string
{
- return $this->password;
+ return $this->locale;
}
- public function setPassword(string $password): self
+ public function setLocale(?string $locale): static
{
- $this->password = $password;
+ $this->locale = $locale;
return $this;
}
@@ -166,7 +135,7 @@ public function getToken(): ?string
return $this->token;
}
- public function setToken(?string $token): self
+ public function setToken(?string $token): static
{
$this->token = $token;
@@ -178,4 +147,13 @@ public function eraseCredentials(): void
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
+
+ public function getUserIdentifier(): string
+ {
+ if ('' === $this->email) {
+ throw new \LogicException('The User class must have an email.');
+ }
+
+ return $this->email;
+ }
}
diff --git a/src/Entity/UserInterface.php b/src/Entity/UserInterface.php
new file mode 100644
index 0000000..b654054
--- /dev/null
+++ b/src/Entity/UserInterface.php
@@ -0,0 +1,61 @@
+ $roles
+ */
+ public function setRoles(array $roles): static;
+
+ public function getPassword(): ?string;
+
+ public function setPassword(string $password): static;
+
+ public function getTimezone(): ?string;
+
+ public function setTimezone(?string $timezone): static;
+
+ public function getLocale(): ?string;
+
+ public function setLocale(?string $locale): static;
+
+ public function getToken(): ?string;
+
+ public function setToken(?string $token): static;
+
+ public function eraseCredentials(): void;
+
+ public function getUserIdentifier(): string;
+}
diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php
index ed90faa..26e4759 100644
--- a/src/EventSubscriber/ProcessEventSubscriber.php
+++ b/src/EventSubscriber/ProcessEventSubscriber.php
@@ -15,7 +15,7 @@
use CleverAge\ProcessBundle\Event\ProcessEvent;
use CleverAge\UiProcessBundle\Entity\Enum\ProcessExecutionStatus;
-use CleverAge\UiProcessBundle\Entity\ProcessExecution;
+use CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface;
use CleverAge\UiProcessBundle\Manager\ProcessExecutionManager;
use CleverAge\UiProcessBundle\Monolog\Handler\DoctrineProcessHandler;
use CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler;
@@ -24,7 +24,11 @@
final readonly class ProcessEventSubscriber implements EventSubscriberInterface
{
+ /**
+ * @param class-string $processExecutionClassName
+ */
public function __construct(
+ private string $processExecutionClassName,
private ProcessHandler $processHandler,
private DoctrineProcessHandler $doctrineProcessHandler,
private ProcessExecutionManager $processExecutionManager,
@@ -36,8 +40,8 @@ public function onProcessStart(ProcessEvent $event): void
if (false === $this->processHandler->hasFilename()) {
$this->processHandler->setFilename(\sprintf('%s/%s.log', $event->getProcessCode(), Uuid::v4()));
}
- if (!$this->processExecutionManager->getCurrentProcessExecution() instanceof ProcessExecution) {
- $processExecution = new ProcessExecution(
+ if (!$this->processExecutionManager->getCurrentProcessExecution() instanceof ProcessExecutionInterface) {
+ $processExecution = new $this->processExecutionClassName(
$event->getProcessCode(),
basename((string) $this->processHandler->getFilename()),
$event->getProcessContext()
diff --git a/src/Manager/ProcessExecutionManager.php b/src/Manager/ProcessExecutionManager.php
index 84a6041..66e0b37 100644
--- a/src/Manager/ProcessExecutionManager.php
+++ b/src/Manager/ProcessExecutionManager.php
@@ -13,34 +13,34 @@
namespace CleverAge\UiProcessBundle\Manager;
-use CleverAge\UiProcessBundle\Entity\ProcessExecution;
-use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository;
+use CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface;
+use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepositoryInterface;
class ProcessExecutionManager
{
- private ?ProcessExecution $currentProcessExecution = null;
+ private ?ProcessExecutionInterface $currentProcessExecution = null;
- public function __construct(private readonly ProcessExecutionRepository $processExecutionRepository)
+ public function __construct(private readonly ProcessExecutionRepositoryInterface $processExecutionRepository)
{
}
- public function setCurrentProcessExecution(ProcessExecution $processExecution): self
+ public function setCurrentProcessExecution(ProcessExecutionInterface $processExecution): self
{
- if (!$this->currentProcessExecution instanceof ProcessExecution) {
+ if (!$this->currentProcessExecution instanceof ProcessExecutionInterface) {
$this->currentProcessExecution = $processExecution;
}
return $this;
}
- public function getCurrentProcessExecution(): ?ProcessExecution
+ public function getCurrentProcessExecution(): ?ProcessExecutionInterface
{
return $this->currentProcessExecution;
}
public function unsetProcessExecution(string $processCode): self
{
- if ($this->currentProcessExecution?->code === $processCode) {
+ if ($this->currentProcessExecution?->getCode() === $processCode) {
$this->currentProcessExecution = null;
}
@@ -49,7 +49,7 @@ public function unsetProcessExecution(string $processCode): self
public function save(): self
{
- if ($this->currentProcessExecution instanceof ProcessExecution) {
+ if ($this->currentProcessExecution instanceof ProcessExecutionInterface) {
$this->processExecutionRepository->save($this->currentProcessExecution);
}
diff --git a/src/Message/CronProcessMessage.php b/src/Message/CronProcessMessage.php
index 8e94c09..11a0bfe 100644
--- a/src/Message/CronProcessMessage.php
+++ b/src/Message/CronProcessMessage.php
@@ -13,11 +13,11 @@
namespace CleverAge\UiProcessBundle\Message;
-use CleverAge\UiProcessBundle\Entity\ProcessSchedule;
+use CleverAge\UiProcessBundle\Entity\ProcessScheduleInterface;
final readonly class CronProcessMessage
{
- public function __construct(public ProcessSchedule $processSchedule)
+ public function __construct(public ProcessScheduleInterface $processSchedule)
{
}
}
diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php
index 07c4a0a..28c1eef 100644
--- a/src/Monolog/Handler/DoctrineProcessHandler.php
+++ b/src/Monolog/Handler/DoctrineProcessHandler.php
@@ -13,7 +13,8 @@
namespace CleverAge\UiProcessBundle\Monolog\Handler;
-use CleverAge\UiProcessBundle\Entity\ProcessExecution;
+use CleverAge\UiProcessBundle\Entity\LogRecordInterface;
+use CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface;
use CleverAge\UiProcessBundle\Manager\ProcessExecutionManager;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
@@ -27,6 +28,8 @@ class DoctrineProcessHandler extends AbstractProcessingHandler
private ArrayCollection $records;
private ?ProcessExecutionManager $processExecutionManager = null;
private ?EntityManagerInterface $em = null;
+ /** @var string class-string */
+ private string $logRecordClassName;
public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true)
{
@@ -44,6 +47,11 @@ public function setProcessExecutionManager(ProcessExecutionManager $processExecu
$this->processExecutionManager = $processExecutionManager;
}
+ public function setLogRecordClassName(string $logRecordClassName): void
+ {
+ $this->logRecordClassName = $logRecordClassName;
+ }
+
public function __destruct()
{
$this->flush();
@@ -53,8 +61,8 @@ public function __destruct()
public function flush(): void
{
foreach ($this->records as $record) {
- if (($currentProcessExecution = $this->processExecutionManager?->getCurrentProcessExecution()) instanceof ProcessExecution) {
- $entity = new \CleverAge\UiProcessBundle\Entity\LogRecord($record, $currentProcessExecution);
+ if (($currentProcessExecution = $this->processExecutionManager?->getCurrentProcessExecution()) instanceof ProcessExecutionInterface) {
+ $entity = new $this->logRecordClassName($record, $currentProcessExecution);
$this->em?->persist($entity);
}
}
diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php
index e5d09e0..13da738 100644
--- a/src/Repository/ProcessExecutionRepository.php
+++ b/src/Repository/ProcessExecutionRepository.php
@@ -13,33 +13,32 @@
namespace CleverAge\UiProcessBundle\Repository;
-use CleverAge\UiProcessBundle\Entity\LogRecord;
-use CleverAge\UiProcessBundle\Entity\ProcessExecution;
+use CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
- * @extends EntityRepository
+ * @template T of ProcessExecutionInterface
*
- * @method ProcessExecution|null find($id, $lockMode = null, $lockVersion = null)
- * @method ProcessExecution|null findOneBy(mixed[] $criteria, string[] $orderBy = null)
- * @method ProcessExecution[] findAll()
- * @method ProcessExecution[] findBy(mixed[] $criteria, string[] $orderBy = null, $limit = null, $offset = null)
+ * @template-extends EntityRepository
*/
-class ProcessExecutionRepository extends EntityRepository
+class ProcessExecutionRepository extends EntityRepository implements ProcessExecutionRepositoryInterface
{
- public function __construct(EntityManagerInterface $em)
+ /**
+ * @param class-string $className
+ */
+ public function __construct(EntityManagerInterface $em, string $className, private readonly string $logRecordClassName)
{
- parent::__construct($em, $em->getClassMetadata(ProcessExecution::class));
+ parent::__construct($em, $em->getClassMetadata($className));
}
- public function save(ProcessExecution $processExecution): void
+ public function save(ProcessExecutionInterface $processExecution): void
{
$this->getEntityManager()->persist($processExecution);
$this->getEntityManager()->flush();
}
- public function getLastProcessExecution(string $code): ?ProcessExecution
+ public function getLastProcessExecution(string $code): ?ProcessExecutionInterface
{
$qb = $this->createQueryBuilder('pe');
@@ -51,11 +50,11 @@ public function getLastProcessExecution(string $code): ?ProcessExecution
->getOneOrNullResult();
}
- public function hasLogs(ProcessExecution $processExecution): bool
+ public function hasLogs(ProcessExecutionInterface $processExecution): bool
{
$qb = $this->createQueryBuilder('pe')
->select('count(lr.id)')
- ->join(LogRecord::class, 'lr', 'WITH', 'lr.processExecution = pe')
+ ->join($this->logRecordClassName, 'lr', 'WITH', 'lr.processExecution = pe')
->where('pe.id = :id')
->setParameter('id', $processExecution->getId()
);
diff --git a/src/Repository/ProcessExecutionRepositoryInterface.php b/src/Repository/ProcessExecutionRepositoryInterface.php
new file mode 100644
index 0000000..ae980d3
--- /dev/null
+++ b/src/Repository/ProcessExecutionRepositoryInterface.php
@@ -0,0 +1,27 @@
+
+ */
+interface ProcessExecutionRepositoryInterface extends ObjectRepository
+{
+ public function save(ProcessExecutionInterface $processExecution): void;
+
+ public function getLastProcessExecution(string $code): ?ProcessExecutionInterface;
+
+ public function hasLogs(ProcessExecutionInterface $processExecution): bool;
+}
diff --git a/src/Repository/ProcessScheduleRepository.php b/src/Repository/ProcessScheduleRepository.php
index 6c8e3ea..5e6be50 100644
--- a/src/Repository/ProcessScheduleRepository.php
+++ b/src/Repository/ProcessScheduleRepository.php
@@ -13,22 +13,22 @@
namespace CleverAge\UiProcessBundle\Repository;
-use CleverAge\UiProcessBundle\Entity\ProcessSchedule;
-use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
-use Doctrine\Persistence\ManagerRegistry;
+use CleverAge\UiProcessBundle\Entity\ProcessScheduleInterface;
+use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\ORM\EntityRepository;
/**
- * @extends ServiceEntityRepository
+ * @template T of ProcessScheduleInterface
*
- * @method ProcessSchedule|null find($id, $lockMode = null, $lockVersion = null)
- * @method ProcessSchedule|null findOneBy(mixed[] $criteria, string[] $orderBy = null)
- * @method ProcessSchedule[] findAll()
- * @method ProcessSchedule[] findBy(mixed[] $criteria, string[] $orderBy = null, $limit = null, $offset = null)
+ * @template-extends EntityRepository
*/
-class ProcessScheduleRepository extends ServiceEntityRepository
+class ProcessScheduleRepository extends EntityRepository implements ProcessScheduleRepositoryInterface
{
- public function __construct(ManagerRegistry $registry)
+ /**
+ * @param class-string $className
+ */
+ public function __construct(EntityManagerInterface $em, string $className)
{
- parent::__construct($registry, ProcessSchedule::class);
+ parent::__construct($em, $em->getClassMetadata($className));
}
}
diff --git a/src/Repository/ProcessScheduleRepositoryInterface.php b/src/Repository/ProcessScheduleRepositoryInterface.php
new file mode 100644
index 0000000..443a046
--- /dev/null
+++ b/src/Repository/ProcessScheduleRepositoryInterface.php
@@ -0,0 +1,22 @@
+
+ */
+interface ProcessScheduleRepositoryInterface extends ObjectRepository
+{
+}
diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php
new file mode 100644
index 0000000..4a5a9a3
--- /dev/null
+++ b/src/Repository/UserRepository.php
@@ -0,0 +1,34 @@
+
+ */
+class UserRepository extends EntityRepository implements UserRepositoryInterface
+{
+ /**
+ * @param class-string $className
+ */
+ public function __construct(EntityManagerInterface $em, string $className)
+ {
+ parent::__construct($em, $em->getClassMetadata($className));
+ }
+}
diff --git a/src/Repository/UserRepositoryInterface.php b/src/Repository/UserRepositoryInterface.php
new file mode 100644
index 0000000..9fb3f40
--- /dev/null
+++ b/src/Repository/UserRepositoryInterface.php
@@ -0,0 +1,22 @@
+
+ */
+interface UserRepositoryInterface extends ObjectRepository
+{
+}
diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php
index b12fd20..518309d 100644
--- a/src/Scheduler/CronScheduler.php
+++ b/src/Scheduler/CronScheduler.php
@@ -15,7 +15,7 @@
use CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType;
use CleverAge\UiProcessBundle\Message\CronProcessMessage;
-use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository;
+use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepositoryInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;
@@ -25,7 +25,7 @@
readonly class CronScheduler implements ScheduleProviderInterface
{
public function __construct(
- private ProcessScheduleRepository $repository,
+ private ProcessScheduleRepositoryInterface $processScheduleRepository,
private ValidatorInterface $validator,
private LoggerInterface $logger,
) {
@@ -35,7 +35,7 @@ public function getSchedule(): Schedule
{
$schedule = new Schedule();
try {
- foreach ($this->repository->findAll() as $processSchedule) {
+ foreach ($this->processScheduleRepository->findAll() as $processSchedule) {
$violations = $this->validator->validate($processSchedule);
if (0 !== $violations->count()) {
foreach ($violations as $violation) {
diff --git a/src/Security/HttpProcessExecutionAuthenticator.php b/src/Security/HttpProcessExecutionAuthenticator.php
index 85734f9..5ce8962 100644
--- a/src/Security/HttpProcessExecutionAuthenticator.php
+++ b/src/Security/HttpProcessExecutionAuthenticator.php
@@ -13,8 +13,7 @@
namespace CleverAge\UiProcessBundle\Security;
-use CleverAge\UiProcessBundle\Entity\User;
-use Doctrine\ORM\EntityManagerInterface;
+use CleverAge\UiProcessBundle\Repository\UserRepositoryInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -28,7 +27,7 @@
class HttpProcessExecutionAuthenticator extends AbstractAuthenticator
{
- public function __construct(private readonly EntityManagerInterface $entityManager)
+ public function __construct(private readonly UserRepositoryInterface $userRepository)
{
}
@@ -44,7 +43,7 @@ public function authenticate(Request $request): Passport
}
$token = $request->headers->get('Authorization');
$token = str_replace('Bearer ', '', $token ?? '');
- $user = $this->entityManager->getRepository(User::class)->findOneBy(
+ $user = $this->userRepository->findOneBy(
['token' => (new Pbkdf2PasswordHasher())->hash($token)]
);
if (null === $user) {
diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php
index 592f1e4..e0e43fd 100644
--- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php
+++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php
@@ -13,20 +13,20 @@
namespace CleverAge\UiProcessBundle\Twig\Runtime;
-use CleverAge\UiProcessBundle\Entity\ProcessExecution;
+use CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface;
use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager;
-use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository;
+use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepositoryInterface;
use Twig\Extension\RuntimeExtensionInterface;
readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface
{
public function __construct(
- private ProcessExecutionRepository $processExecutionRepository,
+ private ProcessExecutionRepositoryInterface $processExecutionRepository,
private ProcessConfigurationsManager $processConfigurationsManager,
) {
}
- public function getLastExecutionDate(string $code): ?ProcessExecution
+ public function getLastExecutionDate(string $code): ?ProcessExecutionInterface
{
return $this->processExecutionRepository->getLastProcessExecution($code);
}