Skip to content

Commit

Permalink
#37 Refactor models to allow overriding:
Browse files Browse the repository at this point in the history
- replace php annotated entities by xml mapping/validations. Add Interfaces.
- add class entries on configuration for models
- rework install documentation with a Doctrine ORM Configuration chapter
- rework repositories and other services using model classNames & Interfaces
  • Loading branch information
njoubert-cleverage committed Feb 10, 2025
1 parent e575297 commit 2f13e7e
Show file tree
Hide file tree
Showing 39 changed files with 714 additions and 270 deletions.
21 changes: 21 additions & 0 deletions config/doctrine/LogRecord.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">
<mapped-superclass name="CleverAge\UiProcessBundle\Entity\LogRecord">
<indexes>
<index name="idx_log_record_level" columns="level" />
<index name="idx_log_record_created_at" columns="created_at" />
</indexes>

<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="channel" type="string" length="64" />
<field name="level" type="integer" />
<field name="message" type="string" length="512" />
<field name="context" type="json" />
<field name="createdAt" type="datetime_immutable" />
<many-to-one field="processExecution" target-entity="CleverAge\UiProcessBundle\Entity\ProcessExecutionInterface">
<join-column name="process_execution_id" referenced-column-name="id" on-delete="CASCADE" nullable="false" />
</many-to-one>
</mapped-superclass>
</doctrine-mapping>
20 changes: 20 additions & 0 deletions config/doctrine/ProcessExecution.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">
<mapped-superclass name="CleverAge\UiProcessBundle\Entity\ProcessExecution">
<indexes>
<index name="idx_process_execution_code" columns="code" />
<index name="idx_process_execution_start_date" columns="start_date" />
</indexes>

<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="code" type="string" length="255" />
<field name="startDate" type="datetime_immutable"/>
<field name="endDate" type="datetime_immutable" nullable="true" />
<field name="status" type="string" enum-type="CleverAge\UiProcessBundle\Entity\Enum\ProcessExecutionStatus" />
<field name="report" type="json" />
<field name="context" type="json" nullable="true" />
<field name="logFilename" type="string" length="255" />
</mapped-superclass>
</doctrine-mapping>
13 changes: 13 additions & 0 deletions config/doctrine/ProcessSchedule.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">
<mapped-superclass name="CleverAge\UiProcessBundle\Entity\ProcessSchedule">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="process" type="string" length="255" />
<field name="type" type="string" length="6" enum-type="CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType" />
<field name="expression" type="string" length="255" />
<field name="input" type="text" nullable="true" />
<field name="context" type="json" />
</mapped-superclass>
</doctrine-mapping>
20 changes: 20 additions & 0 deletions config/doctrine/User.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">
<mapped-superclass name="CleverAge\UiProcessBundle\Entity\User" table="process_user">
<indexes>
<index name="idx_process_user_email" columns="email" />
</indexes>

<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="email" type="string" length="255" unique="true" />
<field name="firstname" type="string" length="255" nullable="true" />
<field name="lastname" type="string" length="255" nullable="true" />
<field name="roles" type="json" />
<field name="password" type="string" length="255" nullable="true" />
<field name="timezone" type="string" length="255" nullable="true" />
<field name="locale" type="string" length="255" nullable="true" />
<field name="token" type="string" length="255" nullable="true" />
</mapped-superclass>
</doctrine-mapping>
1 change: 1 addition & 0 deletions config/services/command.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
1 change: 1 addition & 0 deletions config/services/event_subscriber.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
1 change: 1 addition & 0 deletions config/services/monolog_handler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 10 additions & 1 deletion config/services/repository.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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%'
2 changes: 1 addition & 1 deletion config/services/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ services:
class: CleverAge\UiProcessBundle\Security\HttpProcessExecutionAuthenticator
public: false
arguments:
- '@doctrine.orm.entity_manager'
- '@cleverage_ui_process.repository.user'

22 changes: 22 additions & 0 deletions config/validation/ProcessSchedule.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping">
<class name="CleverAge\UiProcessBundle\Entity\ProcessSchedule">
<property name="process">
<constraint name="CleverAge\UiProcessBundle\Validator\IsValidProcessCode" />
</property>
<property name="expression">
<constraint name="When">
<option name="expression">this.getType().value == "cron"</option>
<option name="constraints">
<constraint name="CleverAge\UiProcessBundle\Validator\CronExpression" />
</option>
</constraint>
<constraint name="When">
<option name="expression">this.getType().value == "every"</option>
<option name="constraints">
<constraint name="CleverAge\UiProcessBundle\Validator\EveryExpression" />
</option>
</constraint>
</property>
</class>
</constraint-mapping>
78 changes: 76 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,89 @@ 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
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
Expand Down
10 changes: 10 additions & 0 deletions src/CleverAgeUiProcessBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -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__);
Expand Down
9 changes: 7 additions & 2 deletions src/Command/UserCreateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,7 +35,11 @@
)]
class UserCreateCommand extends Command
{
/**
* @param class-string<UserInterface> $userClassName
*/
public function __construct(
private readonly string $userClassName,
private readonly ValidatorInterface $validator,
private readonly UserPasswordHasherInterface $passwordEncoder,
private readonly EntityManagerInterface $em,
Expand All @@ -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));
Expand Down
6 changes: 3 additions & 3 deletions src/Controller/Admin/Process/LaunchAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 5 additions & 6 deletions src/Controller/Admin/ProcessExecutionCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,7 +36,7 @@
class ProcessExecutionCrudController extends AbstractCrudController
{
public function __construct(
private readonly ProcessExecutionRepository $processExecutionRepository,
private readonly ProcessExecutionRepositoryInterface $processExecutionRepository,
private readonly string $logDirectory,
) {
}
Expand Down Expand Up @@ -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);
Expand All @@ -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
;
}
Expand Down
6 changes: 6 additions & 0 deletions src/DependencyInjection/CleverAgeUiProcessExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}

/**
Expand Down
Loading

0 comments on commit 2f13e7e

Please sign in to comment.