Skip to content
Snippets Groups Projects
Commit 7da1c0ad authored by Jean-Philippe Metivier's avatar Jean-Philippe Metivier
Browse files

Preparation des controllers, services, form pour les tableaus de bord

parent 958d1885
No related branches found
No related tags found
No related merge requests found
Pipeline #17314 passed
Showing
with 683 additions and 2 deletions
<?php
use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;
use UnicaenIndicateur\Controller\TableauDeBordController;
use UnicaenIndicateur\Controller\TableauDeBordControllerFactory;
use UnicaenIndicateur\Form\TableauDeBord\TableauDeBordForm;
use UnicaenIndicateur\Form\TableauDeBord\TableauDeBordFormFactory;
use UnicaenIndicateur\Form\TableauDeBord\TableauDeBordHydrator;
use UnicaenIndicateur\Form\TableauDeBord\TableauDeBordHydratorFactory;
use UnicaenIndicateur\Provider\Privilege\IndicateurPrivileges;
use UnicaenIndicateur\Service\TableauDeBord\TableauDeBordService;
use UnicaenIndicateur\Service\TableauDeBord\TableauDeBordServiceFactory;
use UnicaenPrivilege\Guard\PrivilegeController;
return [
'bjyauthorize' => [
'guards' => [
PrivilegeController::class => [
[
'controller' => TableauDeBordController::class,
'action' => [
'index',
'afficher',
],
'privileges' => [
IndicateurPrivileges::AFFICHER,
],
],
],
],
],
'router' => [
'routes' => [
'tableau-de-bord' => [
'type' => Literal::class,
'options' => [
'route' => '/tableau-de-bord',
'defaults' => [
'controller' => TableauDeBordController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'afficher' => [
'type' => Segment::class,
'options' => [
'route' => '/afficher/:tableau-de-bord',
'defaults' => [
'controller' => TableauDeBordController::class,
'action' => 'afficher',
],
],
'may_terminate' => true,
],
],
],
],
],
'service_manager' => [
'factories' => [
TableauDeBordService::class => TableauDeBordServiceFactory::class,
],
],
'controllers' => [
'factories' => [
TableauDeBordController::class => TableauDeBordControllerFactory::class,
],
],
'form_elements' => [
'factories' => [
TableauDeBordForm::class => TableauDeBordFormFactory::class,
],
],
'hydrators' => [
'factories' => [
TableauDeBordHydrator::class => TableauDeBordHydratorFactory::class,
],
]
];
\ No newline at end of file
create table unicaen_indicateur create table unicaen_indicateur_indicateur
( (
id serial constraint indicateur_pk primary key, id serial constraint indicateur_pk primary key,
titre varchar(256) not null, titre varchar(256) not null,
...@@ -20,3 +20,26 @@ create table unicaen_indicateur_abonnement ...@@ -20,3 +20,26 @@ create table unicaen_indicateur_abonnement
create unique index abonnement_id_uindex on unicaen_indicateur_abonnement (id); create unique index abonnement_id_uindex on unicaen_indicateur_abonnement (id);
create unique index indicateur_id_uindex on unicaen_indicateur (id); create unique index indicateur_id_uindex on unicaen_indicateur (id);
create table unicaen_indicateur_tableaudebord
(
id serial constraint unicaen_indicateur_tableaudebord_pk primary key,
titre varchar(1024) default 'Tableau de bord' not null,
description text,
nb_column integer default 1 not null
);
create table unicaen_indicateur_tableau_indicateur
(
tableau_id integer not null
constraint unicaen_indicateur_tableau_indicateur_tableaudebord_null_fk
references unicaen_indicateur_tableaudebord (id)
on delete cascade,
indicateur_id integer not null
constraint unicaen_indicateur_tableau_indicateur_indicateur_null_fk
references unicaen_indicateur_indicateur (id)
on delete cascade,
constraint unicaen_indicateur_tableau_indicateur_pk
primary key (tableau_id, indicateur_id)
);
<?php
namespace UnicaenIndicateur\Controller;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
use UnicaenIndicateur\Service\TableauDeBord\TableauDeBordServiceAwareTrait;
class TableauDeBordController extends AbstractActionController
{
use TableauDeBordServiceAwareTrait;
public function indexAction() : ViewModel
{
$tableaux = $this->getTableauDeBordService()->getTableauxdeBord();
return new ViewModel([
'tableaux' => $tableaux,
]);
}
public function afficherAction() : ViewModel
{
$tableau = $this->getTableauDeBordService()->getRequestedTableauDeBord($this);
return new ViewModel([
'tableau' => $tableau,
]);
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Controller;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use UnicaenIndicateur\Entity\Db\TableauDeBord;
use UnicaenIndicateur\Service\TableauDeBord\TableauDeBordService;
class TableauDeBordControllerFactory {
/**
* @param ContainerInterface $container
* @return TableauDeBordController
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container) : TableauDeBordController
{
/**
* @var TableauDeBordService $tableauService
*/
$tableauService = $container->get(TableauDeBordService::class);
$controller = new TableauDeBordController();
return $controller;
}
}
\ No newline at end of file
...@@ -21,10 +21,12 @@ class Indicateur { ...@@ -21,10 +21,12 @@ class Indicateur {
private ?string $viewId = null; private ?string $viewId = null;
private ?string $entity = null; private ?string $entity = null;
private Collection $abonnements; private Collection $abonnements;
private Collection $tableaux;
public function __construct() public function __construct()
{ {
$this->abonnements = new ArrayCollection(); $this->abonnements = new ArrayCollection();
$this->tableaux = new ArrayCollection();
} }
public function getId() : ?int public function getId() : ?int
...@@ -92,6 +94,8 @@ class Indicateur { ...@@ -92,6 +94,8 @@ class Indicateur {
$this->entity = $entity; $this->entity = $entity;
} }
/** Abonnements **************************************************************** */
/** /**
* @return Abonnement[] * @return Abonnement[]
*/ */
...@@ -114,4 +118,15 @@ class Indicateur { ...@@ -114,4 +118,15 @@ class Indicateur {
{ {
return $this->abonnements->contains($abonnement); return $this->abonnements->contains($abonnement);
} }
/** Tableau *****************************************************************/
/**
* @return TableauDeBord[]
*/
public function getTableauxDeBord() : array
{
return $this->tableaux->toArray();
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="UnicaenIndicateur\Entity\Db\Indicateur" table="unicaen_indicateur"> <entity name="UnicaenIndicateur\Entity\Db\Indicateur" table="unicaen_indicateur_indicateur">
<id name="id" type="integer" column="id"> <id name="id" type="integer" column="id">
<generator strategy="IDENTITY"/> <generator strategy="IDENTITY"/>
...@@ -14,5 +14,16 @@ ...@@ -14,5 +14,16 @@
<field name="entity" type="string" length="255" column="entity" nullable="true"/> <field name="entity" type="string" length="255" column="entity" nullable="true"/>
<one-to-many target-entity="UnicaenIndicateur\Entity\Db\Abonnement" field="abonnements" mapped-by="indicateur" /> <one-to-many target-entity="UnicaenIndicateur\Entity\Db\Abonnement" field="abonnements" mapped-by="indicateur" />
<many-to-many field="tableaux" target-entity="UnicaenIndicateur\Entity\Db\TableauDeBord" inversed-by="tableau" fetch="LAZY">
<join-table name="unicaen_indicateur_tableau_indicateur">
<join-columns>
<join-column name="indicateur_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
<join-column name="tableau_id" referenced-column-name="ID"/>
</inverse-join-columns>
</join-table>
</many-to-many>
</entity> </entity>
</doctrine-mapping> </doctrine-mapping>
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="UnicaenIndicateur\Entity\Db\TableauDeBord" table="unicaen_indicateur_tableaudebord">
<id name="id" type="integer" column="id">
<generator strategy="IDENTITY"/>
</id>
<field name="titre" type="string" length="255" column="titre" nullable="false"/>
<field name="description" type="string" length="2047" column="description" nullable="false"/>
<field name="nbColumn" type="integer" column="nb_column" nullable="false"/>
<many-to-many field="indicateurs" target-entity="UnicaenIndicateur\Entity\Db\Indicateur" inversed-by="indicateur" fetch="LAZY">
<join-table name="unicaen_indicateur_tableau_indicateur">
<join-columns>
<join-column name="tableau_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
<join-column name="indicateur_id" referenced-column-name="ID"/>
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>
<?php
namespace UnicaenIndicateur\Entity\Db;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
class TableauDeBord {
private ?int $id = null;
private ?string $titre = null;
private ?string $description = null;
private ?int $nbColumn = 1;
private Collection $indicateurs;
public function __construct()
{
$this->indicateurs = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitre(): ?string
{
return $this->titre;
}
public function setTitre(?string $titre): void
{
$this->titre = $titre;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): void
{
$this->description = $description;
}
public function getNbColumn(): ?int
{
return $this->nbColumn;
}
public function setNbColumn(?int $nbColumn): void
{
$this->nbColumn = $nbColumn;
}
/**
* @return Indicateur[]
*/
public function getIndicateurs(): array
{
$array = $this->indicateurs->toArray();
return $array;
}
public function addIndicateur(Indicateur $indicateur) : void
{
$this->indicateurs->add($indicateur);
}
public function removeIndicateur(Indicateur $indicateur) : void
{
$this->indicateurs->removeElement($indicateur);
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Form\TableauDeBord;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Number;
use Laminas\Form\Element\Text;
use Laminas\Form\Form;
use Laminas\InputFilter\Factory;
class TableauDeBordForm extends Form {
public function init()
{
// libelle
$this->add([
'type' => Text::class,
'name' => 'libelle',
'options' => [
'label' => "Libelle* :",
],
'attributes' => [
'id' => 'libelle',
],
]);
// description
$this->add([
'name' => 'description',
'type' => 'textarea',
'options' => [
'label' => 'Description : ',
'label_attributes' => [
'class' => 'control-label',
],
],
'attributes' => [
'class' => 'type2 form-control',
]
]);
// nbCOlum
$this->add([
'name' => 'nb_colonne',
'type' => Number::class,
'options' => [
'label' => 'Nombre de colonne : ',
'label_attributes' => [
'class' => 'control-label',
],
],
'attributes' => [
'id' => 'nb_colonne',
'min' => 1,
'max' => 3,
],
]);
// submit
$this->add([
'type' => Button::class,
'name' => 'creer',
'options' => [
'label' => '<i class="fas fa-save"></i> Enregistrer',
'label_options' => [
'disable_html_escape' => true,
],
],
'attributes' => [
'type' => 'submit',
'class' => 'btn btn-primary',
],
]);
$this->setInputFilter((new Factory())->createInputFilter([
'libelle' => [ 'required' => true, ],
'description' => [ 'required' => false, ],
'nb_colonne' => [ 'required' => true, ],
]));
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Form\TableauDeBord;
trait TableauDeBordFormAwareTrait {
private TableauDeBordForm $tableauDeBordForm;
public function getTableauDeBordForm(): TableauDeBordForm
{
return $this->tableauDeBordForm;
}
public function setTableauDeBordForm(TableauDeBordForm $tableauDeBordForm): void
{
$this->tableauDeBordForm = $tableauDeBordForm;
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Form\TableauDeBord;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
class TableauDeBordFormFactory {
/**
* @param ContainerInterface $container
* @return TableauDeBordForm
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container) : TableauDeBordForm
{
/**
* @var TableauDeBordHydrator $hydrator
*/
$hydrator = $container->get('HydratorManager')->get(TableauDeBordHydrator::class);
$form = new TableauDeBordForm();
$form->setHydrator($hydrator);
return $form;
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Form\TableauDeBord;
use Laminas\Hydrator\HydratorInterface;
use UnicaenIndicateur\Entity\Db\TableauDeBord;
class TableauDeBordHydrator implements HydratorInterface {
/**
* @param TableauDeBord $object
* @return array
*/
public function extract(object $object): array
{
$data = [
'libelle' => $object->getTitre(),
'description' => $object->getTitre(),
'nb_colonne' => $object->getTitre(),
];
return $data;
}
/**
* @param array $data
* @param TableauDeBord $object
* @return TableauDeBord
*/
public function hydrate(array $data, object $object) : object
{
$libelle = (isset($data['libelle']) AND trim($data['libelle']) !== '')?trim($data['libelle']):null;
$description = (isset($data['description']) AND trim($data['description']) !== '')?trim($data['description']):null;
$nbColonne = (isset($data['nb_colonne']))?$data['nb_colonne']:null;
$object->setTitre($libelle);
$object->setDescription($description);
$object->setNbColumn($nbColonne);
return $object;
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Form\TableauDeBord;
use Psr\Container\ContainerInterface;
class TableauDeBordHydratorFactory {
public function __invoke(ContainerInterface $container) : TableauDeBordHydrator
{
$hydrator = new TableauDeBordHydrator();
return $hydrator;
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Service\TableauDeBord;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\QueryBuilder;
use DoctrineModule\Persistence\ProvidesObjectManager;
use Laminas\Mvc\Controller\AbstractActionController;
use RuntimeException;
use UnicaenIndicateur\Entity\Db\TableauDeBord;
/**
* @property EntityManager $objectManager
*/
class TableauDeBordService {
use ProvidesObjectManager;
/** GESTION DES ENTITES *****************************************/
public function create(TableauDeBord $tableau) : TableauDeBord
{
try {
$this->getObjectManager()->persist($tableau);
$this->getObjectManager()->flush($tableau);
} catch (ORMException $e) {
throw new RuntimeException("Un problème est survenu en BD", 0 , $e);
}
return $tableau;
}
public function update(TableauDeBord $tableau) : TableauDeBord
{
try {
$this->getObjectManager()->flush($tableau);
} catch (ORMException $e) {
throw new RuntimeException("Un problème est survenu en BD", 0 , $e);
}
return $tableau;
}
public function delete(TableauDeBord $tableau) : TableauDeBord
{
try {
$this->getObjectManager()->remove($tableau);
$this->getObjectManager()->flush($tableau);
} catch (ORMException $e) {
throw new RuntimeException("Un problème est survenu en BD", 0 , $e);
}
return $tableau;
}
/** REQUETAGE ***************************************************/
public function createQueryBuilder() : QueryBuilder
{
$qb = $this->getObjectManager()->getRepository(TableauDeBord::class)->createQueryBuilder('tableau')
->leftJoin('tableau.indicateurs', 'indicateur')->addSelect('indicateur');
return $qb;
}
/**
* @param string $champ
* @param string $ordre
* @return TableauDeBord[]
*/
public function getTableauxdeBord(string $champ = 'id', string $ordre='ASC') : array
{
$qb = $this->createQueryBuilder()
->orderBy('tableau.'.$champ, $ordre);
$result = $qb->getQuery()->getResult();
return $result;
}
public function getTableauDeBord(?int $id) : ?TableauDeBord
{
$qb = $this->createQueryBuilder()
->andWhere('tableau.id = :id')->setParameter('id', $id);
try {
$result = $qb->getQuery()->getOneOrNullResult();
} catch (NonUniqueResultException $e) {
throw new RuntimeException("Plusieurs TableauDeBord partagent le même id [".$id."]");
}
return $result;
}
public function getRequestedTableauDeBord(AbstractActionController $controller, string $param='tableau-de-bord') : ?TableauDeBord
{
$id = $controller->params()->fromRoute($param);
$result = $this->getTableauDeBord($id);
return $result;
}
/** FACADE ******************************************************/
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Service\TableauDeBord;
trait TableauDeBordServiceAwareTrait {
private TableauDeBordService $tableauDeBordService;
public function getTableauDeBordService(): TableauDeBordService
{
return $this->tableauDeBordService;
}
public function setTableauDeBordService(TableauDeBordService $tableauDeBordService): void
{
$this->tableauDeBordService = $tableauDeBordService;
}
}
\ No newline at end of file
<?php
namespace UnicaenIndicateur\Service\TableauDeBord;
use Doctrine\ORM\EntityManager;
use Psr\Container\ContainerInterface;
class TableauDeBordServiceFactory {
public function __invoke(ContainerInterface $container) : TableauDeBordService
{
/** @var EntityManager $entityManager */
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$service = new TableauDeBordService();
$service->setObjectManager($entityManager);
return $service;
}
}
\ No newline at end of file
<?php
use UnicaenIndicateur\Entity\Db\TableauDeBord;
/**
* @see \UnicaenIndicateur\Controller\TableauDeBordController::afficherAction()
* @var TableauDeBord[] $tableaux
*/
$this->headTitle("Index des tableaux de bords");
?>
<div class="row">
<div class="col-md-9">
<h1 class="page-header">
Gestion des tableaux de bord
</h1>
</div>
<div class="col-md-3">
<a href="<?php echo $this->url('indicateurs', [], [], true); ?>"
class="btn btn-secondary">
<span class="icon icon-lister"></span>
Accéder aux indicateurs
</a>
</div>
</div>
<a href=""
class="ajax-modal btn btn-primary">
<span class="icon icon-ajouter"></span>
Créer un tableau de bord
</a>
<?php if (empty($tableaux)) : ?>
<div class="alert alert-info">
<span class="icon icon-information"></span>
Aucun tableau de bord
</div>
<?php else : ?>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>Titre</th>
<th>#indicateurs</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($tableaux as $tableau) : ?>
<tr>
<td>
<?php echo $tableau->getTitre(); ?>
<?php if ($tableau->getDescription()) : ?>
<span class="icon icon-information" data-bs-toggle="tooltip" data-bs-html="true"
title="<?php echo $tableau->getDescription(); ?>"></span>
<?php endif; ?>
</td>
<td>
<?php echo count($tableau->getIndicateurs()); ?>
</td>
<td>
<span class="icon icon-voir"></span>
<span class="icon icon-editer"></span>
<span class="icon icon-unchecked text-danger"></span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment