diff --git a/app/src/Sonata/Admin/UserMigrationAdmin.php b/app/src/Sonata/Admin/UserMigrationAdmin.php new file mode 100644 index 000000000..c64d493f1 --- /dev/null +++ b/app/src/Sonata/Admin/UserMigrationAdmin.php @@ -0,0 +1,19 @@ + UserMigration::class, + 'label' => 'User Migration', + ] +)] +class UserMigrationAdmin extends BaseEntityMigrationAdmin +{ +} diff --git a/composer.json b/composer.json index 90f39442f..e4ba33171 100644 --- a/composer.json +++ b/composer.json @@ -248,6 +248,7 @@ "php bin/console messenger:setup-transports --no-interaction", "php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration --quiet", "php bin/console doctrine:fixtures:load --no-interaction", + "php bin/console draw:entity-migrator:setup --no-interaction", "php bin/console draw:application:update-deployed-version --no-interaction" ], "linter": [ diff --git a/config/packages/draw_sonata_integration.yaml b/config/packages/draw_sonata_integration.yaml index 7da2ee77d..5e58860e5 100644 --- a/config/packages/draw_sonata_integration.yaml +++ b/config/packages/draw_sonata_integration.yaml @@ -7,6 +7,8 @@ draw_sonata_integration: commandName: 'app:null' label: 'Null' + entity_migrator: ~ + messenger: queue_names: ['default', 'failed'] diff --git a/packages/entity-migrator/Entity/BaseEntityMigration.php b/packages/entity-migrator/Entity/BaseEntityMigration.php index 7317cbb59..e22a90524 100644 --- a/packages/entity-migrator/Entity/BaseEntityMigration.php +++ b/packages/entity-migrator/Entity/BaseEntityMigration.php @@ -9,7 +9,7 @@ #[ ORM\UniqueConstraint(name: 'entity_migration', fields: ['entity', 'migration']) ] -abstract class BaseEntityMigration implements EntityMigrationInterface +abstract class BaseEntityMigration implements EntityMigrationInterface, \Stringable { #[ ORM\Id, @@ -48,6 +48,11 @@ public function __construct(MigrationTargetEntityInterface $entity, Migration $m $this->createdAt = new \DateTimeImmutable(); } + public function getId(): ?int + { + return $this->id; + } + public function getEntity(): MigrationTargetEntityInterface { return $this->entity; @@ -100,4 +105,9 @@ public function getTransitionLogs(): array { return $this->transitionLogs; } + + public function __toString(): string + { + return $this->migration.' --> '.$this->entity; + } } diff --git a/packages/entity-migrator/Entity/Migration.php b/packages/entity-migrator/Entity/Migration.php index d46ddbbfa..95b0e4c55 100644 --- a/packages/entity-migrator/Entity/Migration.php +++ b/packages/entity-migrator/Entity/Migration.php @@ -9,7 +9,7 @@ ORM\Table(name: 'draw_entity_migrator__migration'), ORM\UniqueConstraint(name: 'name', columns: ['name']) ] -class Migration +class Migration implements \Stringable { #[ ORM\Id, @@ -68,4 +68,9 @@ public function isPaused(): bool { return 'paused' === $this->state; } + + public function __toString(): string + { + return $this->name; + } } diff --git a/packages/entity-migrator/MigrationTargetEntityInterface.php b/packages/entity-migrator/MigrationTargetEntityInterface.php index 01f865457..ab6eca780 100644 --- a/packages/entity-migrator/MigrationTargetEntityInterface.php +++ b/packages/entity-migrator/MigrationTargetEntityInterface.php @@ -4,7 +4,7 @@ use Draw\Component\EntityMigrator\Entity\BaseEntityMigration; -interface MigrationTargetEntityInterface +interface MigrationTargetEntityInterface extends \Stringable { /** * @return class-string diff --git a/packages/sonata-integration-bundle/DependencyInjection/Configuration.php b/packages/sonata-integration-bundle/DependencyInjection/Configuration.php index 73c9bcbd9..178242ea1 100644 --- a/packages/sonata-integration-bundle/DependencyInjection/Configuration.php +++ b/packages/sonata-integration-bundle/DependencyInjection/Configuration.php @@ -11,6 +11,7 @@ use Draw\Bundle\UserBundle\Entity\UserLock; use Draw\Component\Application\Configuration\Entity\Config; use Draw\Component\Console\Entity\Execution; +use Draw\Component\EntityMigrator\Entity\Migration; use Draw\Component\Messenger\Broker\Broker; use Sonata\AdminBundle\Datagrid\ListMapper; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; @@ -26,6 +27,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->append($this->createConfigurationNode()) ->append($this->createConsoleNode()) + ->append($this->createEntityMigratorNode()) ->append($this->createMessengerNode()) ->append($this->createUserNode()) ->end(); @@ -81,6 +83,18 @@ private function createConsoleNode(): ArrayNodeDefinition ->end(); } + private function createEntityMigratorNode(): ArrayNodeDefinition + { + return (new ArrayNodeDefinition('entity_migrator')) + ->canBeEnabled() + ->append( + (new SonataAdminNodeConfiguration(Migration::class, 'Entity Migrator', 'admin')) + ->addDefaultsIfNotSet() + ->labelDefaultValue('Migration') + ->iconDefaultValue('fa fa-cogs') + ); + } + private function createMessengerNode(): ArrayNodeDefinition { return $this->canBe(Broker::class, new ArrayNodeDefinition('messenger')) diff --git a/packages/sonata-integration-bundle/DependencyInjection/DrawSonataIntegrationExtension.php b/packages/sonata-integration-bundle/DependencyInjection/DrawSonataIntegrationExtension.php index f64695e0d..4b2eceb93 100644 --- a/packages/sonata-integration-bundle/DependencyInjection/DrawSonataIntegrationExtension.php +++ b/packages/sonata-integration-bundle/DependencyInjection/DrawSonataIntegrationExtension.php @@ -7,6 +7,7 @@ use Draw\Bundle\SonataIntegrationBundle\Console\Admin\ExecutionAdmin; use Draw\Bundle\SonataIntegrationBundle\Console\Command; use Draw\Bundle\SonataIntegrationBundle\Console\CommandRegistry; +use Draw\Bundle\SonataIntegrationBundle\EntityMigrator\Admin\MigrationAdmin; use Draw\Bundle\SonataIntegrationBundle\Messenger\Admin\MessengerMessageAdmin; use Draw\Bundle\SonataIntegrationBundle\Messenger\EventListener\FinalizeContextQueueCountEventListener; use Draw\Bundle\SonataIntegrationBundle\Messenger\Security\CanShowMessageVoter; @@ -43,6 +44,7 @@ public function load(array $configs, ContainerBuilder $container): void $this->configureConfiguration($config['configuration'], $loader, $container); $this->configureConsole($config['console'], $loader, $container); + $this->configureEntityMigrator($config['entity_migrator'], $loader, $container); $this->configureMessenger($config['messenger'], $loader, $container); $this->configureUser($config['user'], $loader, $container); } @@ -161,6 +163,24 @@ private function configureMessenger(array $config, Loader\FileLoader $loader, Co } } + private function configureEntityMigrator(array $config, Loader\FileLoader $loader, ContainerBuilder $container): void + { + if (!$config['enabled']) { + return; + } + + $container + ->setDefinition( + MigrationAdmin::class, + SonataAdminNodeConfiguration::configureFromConfiguration( + new Definition(MigrationAdmin::class), + $config['admin'] + ) + ) + ->setAutowired(true) + ->setAutoconfigured(true); + } + private function configureUser(array $config, Loader\FileLoader $loader, ContainerBuilder $container): void { if (!$config['enabled']) { diff --git a/packages/sonata-integration-bundle/EntityMigrator/Admin/BaseEntityMigrationAdmin.php b/packages/sonata-integration-bundle/EntityMigrator/Admin/BaseEntityMigrationAdmin.php new file mode 100644 index 000000000..1baa4eb26 --- /dev/null +++ b/packages/sonata-integration-bundle/EntityMigrator/Admin/BaseEntityMigrationAdmin.php @@ -0,0 +1,49 @@ + 'orm', + 'pager_type' => 'simple', + 'group' => 'Entity Migrator', + 'icon' => 'fas fa-cogs', + ]; + + protected function configureListFields(ListMapper $list): void + { + $list + ->addIdentifier('id') + ->add('entity') + ->add('migration') + ->add('state'); + } + + protected function configureShowFields(ShowMapper $show): void + { + $show + ->add('id') + ->add('entity') + ->add('migration') + ->add('state') + ->add( + 'transitionLogs', + fieldDescriptionOptions: [ + 'template' => '@DrawSonataIntegration/EntityMigrator/BaseEntityMigration/show_transition_logs.html.twig', + ] + ) + ->add('createdAt'); + } + + protected function configureRoutes(RouteCollectionInterface $collection): void + { + $collection + ->remove('edit'); + } +} diff --git a/packages/sonata-integration-bundle/EntityMigrator/Admin/MigrationAdmin.php b/packages/sonata-integration-bundle/EntityMigrator/Admin/MigrationAdmin.php new file mode 100644 index 000000000..52113e86b --- /dev/null +++ b/packages/sonata-integration-bundle/EntityMigrator/Admin/MigrationAdmin.php @@ -0,0 +1,35 @@ +addIdentifier('id') + ->add('name') + ->add('state'); + } + + protected function configureShowFields(ShowMapper $show): void + { + $show + ->add('id') + ->add('name') + ->add('state'); + } + + protected function configureRoutes(RouteCollectionInterface $collection): void + { + $collection + ->remove('edit') + ->remove('create') + ->remove('delete'); + } +} diff --git a/packages/sonata-integration-bundle/Resources/views/EntityMigrator/BaseEntityMigration/show_transition_logs.html.twig b/packages/sonata-integration-bundle/Resources/views/EntityMigrator/BaseEntityMigration/show_transition_logs.html.twig new file mode 100644 index 000000000..e87ae1b82 --- /dev/null +++ b/packages/sonata-integration-bundle/Resources/views/EntityMigrator/BaseEntityMigration/show_transition_logs.html.twig @@ -0,0 +1,33 @@ +{% extends '@SonataAdmin/CRUD/base_show_field.html.twig' %} + +{% block field %} + + + + + + + + + + + + + {% for entry in value %} + + + + + + + + + {% set previousCreatedAt = entry['createdAt'] %} + {% endfor %} + +
Created ByFromTransitionToCreated AtDelay
{{ entry['createdBy'] }}{{ entry['from'] }}{{ entry['transition'] }}{{ entry['to'] }}{{ entry['createdAt']|date }} + {% if previousCreatedAt is defined %} + {{ entry['createdAt']|date('U') - previousCreatedAt|date('U') }} seconds + {% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/packages/sonata-integration-bundle/Tests/DependencyInjection/ConfigurationTest.php b/packages/sonata-integration-bundle/Tests/DependencyInjection/ConfigurationTest.php index c97721e09..0bc981f7f 100644 --- a/packages/sonata-integration-bundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/packages/sonata-integration-bundle/Tests/DependencyInjection/ConfigurationTest.php @@ -10,6 +10,7 @@ use Draw\Bundle\UserBundle\Entity\UserLock; use Draw\Component\Application\Configuration\Entity\Config; use Draw\Component\Console\Entity\Execution; +use Draw\Component\EntityMigrator\Entity\Migration; use Draw\Component\Tester\DependencyInjection\ConfigurationTestCase; use Sonata\AdminBundle\Datagrid\ListMapper; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -49,6 +50,18 @@ public function getDefaultConfiguration(): array ], 'commands' => [], ], + 'entity_migrator' => [ + 'enabled' => false, + 'admin' => [ + 'group' => 'Entity Migrator', + 'entity_class' => Migration::class, + 'controller_class' => 'sonata.admin.controller.crud', + 'icon' => 'fa fa-cogs', + 'label' => 'Migration', + 'pager_type' => 'default', + 'show_in_dashboard' => true, + ], + ], 'messenger' => [ 'enabled' => true, 'queue_names' => [],