Loading module/Substitution/config/module.config.php +14 −0 Changes for module/Substitution/config/module.config.php: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ return [ 'action' => [ 'accueil', 'lister', 'lister-enregistrements-lies', ], 'privileges' => [ SubstitutionPrivileges::SUBSTITUTION_CONSULTER, Loading Loading @@ -306,6 +307,19 @@ return [ ], ], ], 'lister-enregistrements-lies' => [ 'type' => Segment::class, 'options' => [ 'route' => '/lister-enregistrements-lies/:type/:id', 'constraints' => [ 'type' => Constants::TYPES_REGEXP_CONSTRAINT, 'id' => '\d+', ], 'defaults' => [ 'action' => 'lister-enregistrements-lies', ], ], ], ], ], 'trigger' => [ Loading module/Substitution/src/Substitution/Controller/ForeignKeyController.php +26 −0 Changes for module/Substitution/src/Substitution/Controller/ForeignKeyController.php: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger; use Laminas\View\Model\ViewModel; use Substitution\Service\ForeignKey\ForeignKeyServiceAwareTrait; use Substitution\TypeAwareTrait; use Webmozart\Assert\Assert; /** * @method FlashMessenger flashMessenger() Loading Loading @@ -36,4 +37,29 @@ class ForeignKeyController extends AbstractActionController ]); } /** * @throws \Doctrine\DBAL\Exception */ public function listerEnregistrementsLiesAction(): ViewModel { $type = $this->getRequestedType(); $substituantId = $this->getRequestedId(); $result = $this->foreignKeyService->findAllRelatedRecordsForTypeAndForeignKeyValue($type, $substituantId); return new ViewModel([ 'type' => $type, 'substituantId' => $substituantId, 'result' => $result, ]); } protected function getRequestedId(): int { $id = $this->params()->fromRoute('id'); Assert::notNull($id, "Un id doit être spécifié dans la requête."); return $id; } } No newline at end of file module/Substitution/src/Substitution/Service/ForeignKey/ForeignKeyService.php +26 −0 Changes for module/Substitution/src/Substitution/Service/ForeignKey/ForeignKeyService.php: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -24,6 +24,32 @@ class ForeignKeyService return <<<EOS select * from v_substit_foreign_keys_{$type} order by source_table, fk_column EOS; } /** * @throws \Doctrine\DBAL\Exception */ public function findAllRelatedRecordsForTypeAndForeignKeyValue(string $type, int $substituantId): Result { $sql = $this->entityManager->getConnection()->executeQuery( $this->generateSqlToFindAllRelatedRecords($type, $substituantId) )->fetchOne(); $sql .= ' order by source_table, id'; return $this->entityManager->getConnection()->executeQuery($sql); } private function generateSqlToFindAllRelatedRecords(string $type, int $substituantId): string { return <<<EOS select string_agg( 'select '''||source_table||''' source_table, '''||fk_column||' = {$substituantId}'', '||source_table||'.id id, '||source_table||'::text data '|| 'from '||source_table||' where '||fk_column||' = {$substituantId}', ' UNION '||chr(10) ) from v_substit_foreign_keys_{$type} EOS; } } No newline at end of file module/Substitution/view/substitution/foreign-key/lister-enregistrements-lies.phtml 0 → 100644 +49 −0 Changes for module/Substitution/view/substitution/foreign-key/lister-enregistrements-lies.phtml: 49 added lines, 0 removed lines. Original line number Diff line number Diff line <?php use Application\View\Renderer\PhpRenderer; /** * @var PhpRenderer $this * @var string $type * @var string $substituantId * @var \Doctrine\DBAL\Result $result * * @see \Substitution\Controller\ForeignKeyController::listerEnregistrementsLiesAction() */ ?> <?php $this->headTitle($this->translate("Enregistrements liés : $type $substituantId")) ?> <h1 class="page-header"> <span class="fas fa-key"></span> <?php echo $this->translate("Enregistrements liés") ?> <span class="badge bg-primary text-uppercase p-1"><?php echo $type ?></span> <?php echo $substituantId ?> </h1> <?php echo $this->messenger()->addMessagesFromFlashMessengerWithNoNamespace(); ?> <p class="lead"> TODO : Voici la liste des clés étrangères prises en charge par le mécanisme de substitution automatique. Lorsqu'une substitution est créée, ces clés étrangères sont mises à jour automatiquement : tous les id des substitués sont remplacés par l'id du substituant. </p> <?php if ($count = $result->rowCount()): ?> <p><?php echo $count ?> enregistrements liés trouvés.</p> <table class="table table-bordered table-extra-condensed"> <tr> <th>Table</th> <th>Id</th> <th>Aperçu</th> </tr> <?php while ($row = $result->fetchAssociative()): ?> <tr> <td><?php echo $row['source_table'] ?></td> <td><?php echo $row['id'] ?></td> <td><?php echo $row['data'] ?></td> </tr> <?php endwhile ?> </table> <?php else: ?> <p>Aucun.</p> <?php endif ?> module/Substitution/view/substitution/substitution/_partial/substituant.phtml +3 −0 Changes for module/Substitution/view/substitution/substitution/_partial/substituant.phtml: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ $attributeToGetterFilter = new UnderscoreToCamelCase(); <div class="card substituant"> <div class="card-header"> <a href="<?php echo $this->url('substitution/foreign-key/lister-enregistrements-lies', ['type' => $type, 'id' => $substituant->getId()]) ?>" title="Voir les enregistrements liés à ce substituant (d'après les clés étrangères configurées)" class="btn btn-outline-secondary float-end">Voir ses enregistrements liés...</span></a> <h3 class="card-title"> Substituant<br><?php echo $substituant->getId() ?> </h3> Loading Loading
module/Substitution/config/module.config.php +14 −0 Changes for module/Substitution/config/module.config.php: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ return [ 'action' => [ 'accueil', 'lister', 'lister-enregistrements-lies', ], 'privileges' => [ SubstitutionPrivileges::SUBSTITUTION_CONSULTER, Loading Loading @@ -306,6 +307,19 @@ return [ ], ], ], 'lister-enregistrements-lies' => [ 'type' => Segment::class, 'options' => [ 'route' => '/lister-enregistrements-lies/:type/:id', 'constraints' => [ 'type' => Constants::TYPES_REGEXP_CONSTRAINT, 'id' => '\d+', ], 'defaults' => [ 'action' => 'lister-enregistrements-lies', ], ], ], ], ], 'trigger' => [ Loading
module/Substitution/src/Substitution/Controller/ForeignKeyController.php +26 −0 Changes for module/Substitution/src/Substitution/Controller/ForeignKeyController.php: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger; use Laminas\View\Model\ViewModel; use Substitution\Service\ForeignKey\ForeignKeyServiceAwareTrait; use Substitution\TypeAwareTrait; use Webmozart\Assert\Assert; /** * @method FlashMessenger flashMessenger() Loading Loading @@ -36,4 +37,29 @@ class ForeignKeyController extends AbstractActionController ]); } /** * @throws \Doctrine\DBAL\Exception */ public function listerEnregistrementsLiesAction(): ViewModel { $type = $this->getRequestedType(); $substituantId = $this->getRequestedId(); $result = $this->foreignKeyService->findAllRelatedRecordsForTypeAndForeignKeyValue($type, $substituantId); return new ViewModel([ 'type' => $type, 'substituantId' => $substituantId, 'result' => $result, ]); } protected function getRequestedId(): int { $id = $this->params()->fromRoute('id'); Assert::notNull($id, "Un id doit être spécifié dans la requête."); return $id; } } No newline at end of file
module/Substitution/src/Substitution/Service/ForeignKey/ForeignKeyService.php +26 −0 Changes for module/Substitution/src/Substitution/Service/ForeignKey/ForeignKeyService.php: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -24,6 +24,32 @@ class ForeignKeyService return <<<EOS select * from v_substit_foreign_keys_{$type} order by source_table, fk_column EOS; } /** * @throws \Doctrine\DBAL\Exception */ public function findAllRelatedRecordsForTypeAndForeignKeyValue(string $type, int $substituantId): Result { $sql = $this->entityManager->getConnection()->executeQuery( $this->generateSqlToFindAllRelatedRecords($type, $substituantId) )->fetchOne(); $sql .= ' order by source_table, id'; return $this->entityManager->getConnection()->executeQuery($sql); } private function generateSqlToFindAllRelatedRecords(string $type, int $substituantId): string { return <<<EOS select string_agg( 'select '''||source_table||''' source_table, '''||fk_column||' = {$substituantId}'', '||source_table||'.id id, '||source_table||'::text data '|| 'from '||source_table||' where '||fk_column||' = {$substituantId}', ' UNION '||chr(10) ) from v_substit_foreign_keys_{$type} EOS; } } No newline at end of file
module/Substitution/view/substitution/foreign-key/lister-enregistrements-lies.phtml 0 → 100644 +49 −0 Changes for module/Substitution/view/substitution/foreign-key/lister-enregistrements-lies.phtml: 49 added lines, 0 removed lines. Original line number Diff line number Diff line <?php use Application\View\Renderer\PhpRenderer; /** * @var PhpRenderer $this * @var string $type * @var string $substituantId * @var \Doctrine\DBAL\Result $result * * @see \Substitution\Controller\ForeignKeyController::listerEnregistrementsLiesAction() */ ?> <?php $this->headTitle($this->translate("Enregistrements liés : $type $substituantId")) ?> <h1 class="page-header"> <span class="fas fa-key"></span> <?php echo $this->translate("Enregistrements liés") ?> <span class="badge bg-primary text-uppercase p-1"><?php echo $type ?></span> <?php echo $substituantId ?> </h1> <?php echo $this->messenger()->addMessagesFromFlashMessengerWithNoNamespace(); ?> <p class="lead"> TODO : Voici la liste des clés étrangères prises en charge par le mécanisme de substitution automatique. Lorsqu'une substitution est créée, ces clés étrangères sont mises à jour automatiquement : tous les id des substitués sont remplacés par l'id du substituant. </p> <?php if ($count = $result->rowCount()): ?> <p><?php echo $count ?> enregistrements liés trouvés.</p> <table class="table table-bordered table-extra-condensed"> <tr> <th>Table</th> <th>Id</th> <th>Aperçu</th> </tr> <?php while ($row = $result->fetchAssociative()): ?> <tr> <td><?php echo $row['source_table'] ?></td> <td><?php echo $row['id'] ?></td> <td><?php echo $row['data'] ?></td> </tr> <?php endwhile ?> </table> <?php else: ?> <p>Aucun.</p> <?php endif ?>
module/Substitution/view/substitution/substitution/_partial/substituant.phtml +3 −0 Changes for module/Substitution/view/substitution/substitution/_partial/substituant.phtml: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ $attributeToGetterFilter = new UnderscoreToCamelCase(); <div class="card substituant"> <div class="card-header"> <a href="<?php echo $this->url('substitution/foreign-key/lister-enregistrements-lies', ['type' => $type, 'id' => $substituant->getId()]) ?>" title="Voir les enregistrements liés à ce substituant (d'après les clés étrangères configurées)" class="btn btn-outline-secondary float-end">Voir ses enregistrements liés...</span></a> <h3 class="card-title"> Substituant<br><?php echo $substituant->getId() ?> </h3> Loading