From 0fa852ee4e9c3060ba7fc0daf4b08a44ea151f7f Mon Sep 17 00:00:00 2001 From: polo Date: Thu, 2 Jul 2026 00:01:31 +0200 Subject: =?UTF-8?q?entit=C3=A9=20Presentation,=20MAJ=20filtre=20ViewContro?= =?UTF-8?q?ller::SPECIAL=5FPAGES,=20table=20node=5Fdata=20non=20all=C3=A9g?= =?UTF-8?q?=C3=A9e=20pour=20l'instant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/ArticleController.php | 7 +- src/controller/PageManagementController.php | 12 ++- src/controller/ViewController.php | 7 +- src/model/Blocks.php | 17 ---- src/model/Model.php | 3 +- src/model/entities/EmailForm.php | 1 - src/model/entities/Node.php | 20 +++-- src/model/entities/NodeData.php | 20 ++--- src/model/entities/Presentation.php | 133 ++++++++++++++++++++++++++++ src/service/Backup.php | 1 + src/service/Router.php | 4 +- src/view/FooterBuilder.php | 2 +- src/view/MainBuilder.php | 8 +- src/view/templates/modify_block.php | 4 +- 14 files changed, 182 insertions(+), 57 deletions(-) delete mode 100644 src/model/Blocks.php create mode 100644 src/model/entities/Presentation.php diff --git a/src/controller/ArticleController.php b/src/controller/ArticleController.php index 7019f5c..0ddb0e1 100644 --- a/src/controller/ArticleController.php +++ b/src/controller/ArticleController.php @@ -5,6 +5,7 @@ declare(strict_types=1); use App\Entity\Node; use App\Entity\Article; +use App\Entity\Presentation; use Doctrine\ORM\EntityManager; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -21,7 +22,7 @@ class ArticleController $model->findNodeById($id); $parent_block = $model->getNode(); - if(Blocks::hasPresentation($parent_block->getName())){ + if(Presentation::hasPresentation($parent_block->getName())){ $get_articles_return = $model->getNextArticles($parent_block, $request); $bulk_data = $get_articles_return[0]; @@ -44,11 +45,11 @@ class ArticleController return new JsonResponse(['success' => true, 'html' => $html, 'truncated' => $get_articles_return[1]]); } else{ - return new JsonResponse(['success' => false, 'error' => 'server side error']); + return new JsonResponse(['success' => false, 'error' => 'server side error'], JsonResponse::HTTP_INTERNAL_SERVER_ERROR); } } else{ - return new JsonResponse(['success' => false, 'error' => 'bad parameters']); + return new JsonResponse(['success' => false, 'error' => 'bad parameters'], JsonResponse::HTTP_BAD_REQUEST); } } diff --git a/src/controller/PageManagementController.php b/src/controller/PageManagementController.php index c575077..bfad474 100644 --- a/src/controller/PageManagementController.php +++ b/src/controller/PageManagementController.php @@ -7,6 +7,7 @@ use App\Entity\Page; use App\Entity\Node; use App\Entity\NodeData; use App\Entity\EmailForm; +use App\Entity\Presentation; //use App\Entity\Image; use Doctrine\ORM\EntityManager; use Symfony\Component\HttpFoundation\InputBag; @@ -131,7 +132,7 @@ class PageManagementController $main = $model->getNode(); $position = count($main->getChildren()) + 1; // position dans la fraterie - if(!in_array($request->request->get("bloc_select"), array_keys(Blocks::$blocks), true)){ // 3è param: contrôle du type + if(!in_array($request->request->get("bloc_select"), array_keys(Presentation::$blocks), true)){ // 3è param: contrôle du type // utiliser une flash error return new RedirectResponse((string)new URL(['page' => $request->query->get('page'), 'error' => 'bad_bloc_type'])); } @@ -146,7 +147,12 @@ class PageManagementController $block = new Node($request->request->get("bloc_select"), $position, $main, $page); - $DataClass = $request->request->get("bloc_select") === 'form' ? EmailForm::class : NodeData::class; // cas particulier avec bloc 'email_form' + $DataClass = match($request->request->get("bloc_select")){ + 'form' => EmailForm::class, + 'post_block', 'news_block' => Presentation::class, + 'calendar' => NodeData::class, + default => throw new InvalidArgumentException("Erreur: type de bloc inconnu"), + }; $data = new $DataClass(['title' => trim(htmlspecialchars($request->request->get("bloc_title")))], $block); // valeurs par défaut @@ -305,7 +311,7 @@ class PageManagementController $model = new Model($entityManager); $model->findNodeById($json['id']); - if(in_array($json['presentation'], array_keys(Blocks::$presentations))){ + if(in_array($json['presentation'], array_keys(Presentation::$presentations))){ $model->getNode()->getNodeData()->setPresentation($json['presentation']); $entityManager->flush(); diff --git a/src/controller/ViewController.php b/src/controller/ViewController.php index 43db6a6..d1aaee7 100644 --- a/src/controller/ViewController.php +++ b/src/controller/ViewController.php @@ -8,8 +8,9 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; -class ViewController -{ +class ViewController{ + const SPECIAL_PAGES = ['article', 'new_page', 'menu_paths', 'user_edit', 'connection', 'emails', 'maintenance']; + static function getWebPage(EntityManager $entityManager, Request $request): Response { /* 1/ 1er contrôle des paramètres */ @@ -17,7 +18,7 @@ class ViewController // mode modification d'une page if(IS_ADMIN && $request->query->has('mode') && $request->query->get('mode') === 'page_modif' - && !in_array(CURRENT_PAGE, ['article', 'new_page', 'menu_paths', 'user_edit', 'connection'])) + && !in_array(CURRENT_PAGE, self::SPECIAL_PAGES)) { MainBuilder::$modif_mode = true; } diff --git a/src/model/Blocks.php b/src/model/Blocks.php deleted file mode 100644 index 786ec74..0000000 --- a/src/model/Blocks.php +++ /dev/null @@ -1,17 +0,0 @@ - 'Articles libres', 'news_block' => 'Actualités', - //'galery' => 'Galerie', - 'calendar' => 'Calendrier', 'form' => 'Formulaire']; - - static public array $presentations = ['fullwidth' => 'Pleine largeur', 'grid' => 'Grille', 'mosaic' => 'Mosaïque' - //, 'carousel' => 'Carrousel' - ]; - - static public function hasPresentation(string $block): bool - { - return in_array($block, ['post_block', 'news_block']) ? true : false; - } -} \ No newline at end of file diff --git a/src/model/Model.php b/src/model/Model.php index 1054d57..15ff12a 100644 --- a/src/model/Model.php +++ b/src/model/Model.php @@ -9,6 +9,7 @@ declare(strict_types=1); use Doctrine\ORM\EntityManager; use App\Entity\Page; use App\Entity\Node; +use App\Entity\Presentation; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpFoundation\Request; @@ -60,7 +61,7 @@ class Model foreach($bulk_data as $parent_block){ // groupes d'articles triés par bloc, permet de paginer par bloc - if(Blocks::hasPresentation($parent_block->getName())){ // = post_block ou news_block + if(Presentation::hasPresentation($parent_block->getName())){ // = post_block ou news_block $bulk_data = array_merge($bulk_data, $this->getNextArticles($parent_block, $request)[0]); } diff --git a/src/model/entities/EmailForm.php b/src/model/entities/EmailForm.php index 466a389..0dcdeec 100644 --- a/src/model/entities/EmailForm.php +++ b/src/model/entities/EmailForm.php @@ -6,7 +6,6 @@ declare(strict_types=1); namespace App\Entity; use Doctrine\ORM\Mapping as ORM; -//use Doctrine\Common\Collections\ArrayCollection; #[ORM\Entity] #[ORM\Table(name: TABLE_PREFIX . "email_form")] diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php index fb2d867..7932efc 100644 --- a/src/model/entities/Node.php +++ b/src/model/entities/Node.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace App\Entity; -use Config; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] @@ -48,6 +47,9 @@ class Node #[ORM\OneToOne(targetEntity: EmailForm::class, mappedBy: "node", cascade: ['persist'])] // pas de remove, les e-mails sont associés au EmailForm private ?EmailForm $email_form = null; + #[ORM\OneToOne(targetEntity: Presentation::class, mappedBy: "node", cascade: ['persist', 'remove'])] + private ?Presentation $presentation = null; + // attributs non destinés à doctrine private array $children = []; // tableau de Node private ?self $adopted = null; // = "new" est un enfant de "main" lorsque la page est "article" @@ -111,11 +113,15 @@ class Node // une interface serait cool! // OU possible un "héritage doctrine", faire en sorte que Node soit la mère de NodeData, EmailForm, Article... - // une seulle instance est matérialisée par plusieurs tables en même temps - public function getNodeData(): NodeData|EmailForm|null - { - // limite du polymorphisme avec doctrine => impossible d'avoir une unique variable $node_data - return $this->name_node === 'form' ? $this->email_form : $this->node_data; + // une seule instance est matérialisée par plusieurs tables en même temps + public function getNodeData(): NodeData|EmailForm|Presentation|null + { + // pour du polymorphisme (une unique variable $node_data): opter pour l'héritage + return match($this->name_node){ + 'form' => $this->email_form, + 'post_block', 'news_block' => $this->presentation, + default => $this->node_data, // inclut 'calendar' + }; } public function getChildren(): array { @@ -134,7 +140,7 @@ class Node { $this->children[] = $child; - if(!\Blocks::hasPresentation($this->getName())){ // post_block et news_block ont leurs enfants ordonnés avec ORDER BY + if(!Presentation::hasPresentation($this->getName())){ // post_block et news_block ont leurs enfants ordonnés avec ORDER BY $this->sortChildren(false); } } diff --git a/src/model/entities/NodeData.php b/src/model/entities/NodeData.php index c55f6a1..f6d6b01 100644 --- a/src/model/entities/NodeData.php +++ b/src/model/entities/NodeData.php @@ -24,7 +24,7 @@ class NodeData // inverseBy fait le lien avec $node_data dans Node (qui a "mappedBy") #[ORM\OneToOne(targetEntity: Node::class, inversedBy: "node_data")] #[ORM\JoinColumn(name: "node_id", referencedColumnName: "id_node", onDelete: "CASCADE")] - private Node $node; + private ?Node $node; #[ORM\Column(type: "json")] private array $data; @@ -44,18 +44,12 @@ class NodeData #[ORM\OneToMany(mappedBy: 'node_data', targetEntity: AssetEmployment::class, cascade: ['persist', 'remove'])] private Collection $asset_employment; - private int $nb_pages = 1; private array $emails = []; // => noeud "show_emails" - public function __construct(array $data, Node $node, Collection $asset_employment = new ArrayCollection, ?string $presentation = null, ?bool $chrono_order = null) - { + public function __construct(array $data, Node $node, Collection $asset_employment = new ArrayCollection){ $this->data = $data; $this->node = $node; $this->asset_employment = $asset_employment; - if(!empty($presentation) && $presentation === 'grid'){ - $this->grid_cols_min_width = 250; - } - $this->chrono_order = $chrono_order ?? null; } public function getId(): int @@ -82,7 +76,7 @@ class NodeData } // spécifique aux blocs contenant des articles - public function getPresentation(): ?string + /*public function getPresentation(): ?string { return $this->presentation; } @@ -117,6 +111,7 @@ class NodeData { $this->pagination_limit = $pagination_limit; } + private int $nb_pages = 1; public function getNumberOfPages(): int { return $this->nb_pages; @@ -124,13 +119,12 @@ class NodeData public function setNumberOfPages(int $nb_pages): void { $this->nb_pages = $nb_pages; - } + }*/ - /*public function setNode(Node $node): void + public function setNode(?Node $node): void { $this->node = $node; - }*/ - + } public function getNodeDataAssets(): Collection { diff --git a/src/model/entities/Presentation.php b/src/model/entities/Presentation.php new file mode 100644 index 0000000..912c19e --- /dev/null +++ b/src/model/entities/Presentation.php @@ -0,0 +1,133 @@ +data = $data; + $this->node = $node; + /*if(!empty($presentation) && $presentation === 'grid'){ + $this->grid_cols_min_width = 250; + } + $this->chrono_order = $chrono_order ?? null;*/ + } + + /*public function getId(): int + { + return $this->id_presentation; + }*/ + + public function setNode(?Node $node): void + { + $this->node = $node; + } + + // un trait pour ça + public function getData(): array + { + return $this->data; + } + public function updateData(string $key, string|int|bool|array $value = ''): void + { + if($value !== ''){ + $this->data[$key] = $value; + } + // si $value est vide, supprime la clé + elseif(isset($this->data[$key])){ + unset($this->data[$key]); + } + } + + // spécifique aux blocs contenant des articles + public function getPresentation(): ?string + { + return $this->presentation; + } + public function setPresentation(string $presentation): void + { + $this->presentation = $presentation; + } + public function getColsMinWidth(): int + { + $default = 320; // pixels + return $this->grid_cols_min_width === null ? $default : $this->grid_cols_min_width; + } + public function setColsMinWidth(int $columns): void + { + $this->grid_cols_min_width = $columns; + } + public function getChronoOrder(): bool + { + return $this->chrono_order ?? false; + } + public function setChronoOrder(bool $reverse_order): void + { + $this->chrono_order = $reverse_order; + } + + public function getPaginationLimit(): ?int + { + $default = 12; // si 0 pas de pagination, 12 rend bien avec des grilles de 2, 3 ou 4 colonnes + return $this->pagination_limit === null ? $default : $this->pagination_limit; + } + public function setPaginationLimit(int $pagination_limit): void + { + $this->pagination_limit = $pagination_limit; + } + public function getNumberOfPages(): int + { + return $this->nb_pages; + } + public function setNumberOfPages(int $nb_pages): void + { + $this->nb_pages = $nb_pages; + } + + static public array $blocks = ['post_block' => 'Articles libres', 'news_block' => 'Actualités', + //'galery' => 'Galerie', + 'calendar' => 'Calendrier', 'form' => 'Formulaire' + ]; + static public array $presentations = ['fullwidth' => 'Pleine largeur', 'grid' => 'Grille', 'mosaic' => 'Mosaïque' + //, 'carousel' => 'Carrousel' + ]; + static public function hasPresentation(string $block): bool + { + return in_array($block, ['post_block', 'news_block']) ? true : false; + } +} \ No newline at end of file diff --git a/src/service/Backup.php b/src/service/Backup.php index c30ce5b..2ee69c1 100644 --- a/src/service/Backup.php +++ b/src/service/Backup.php @@ -224,6 +224,7 @@ class Backup } if($elem === TABLE_PREFIX . $excluded){ unset($tables[$key]); + break; // petite optimisation } } } diff --git a/src/service/Router.php b/src/service/Router.php index 907baf4..28a6c39 100644 --- a/src/service/Router.php +++ b/src/service/Router.php @@ -106,7 +106,7 @@ class Router{ return ContactFormController::sendVisitorEmail($this->entityManager, $json); } /*else{ - return new JsonResponse(['success' => false, 'error' => 'tu fais quoi là mec?']); + return new JsonResponse(['success' => false, 'error' => 'tu fais quoi là mec?'], JsonResponse::HTTP_BAD_REQUEST); }*/ } @@ -183,7 +183,7 @@ class Router{ return MaintenanceController::eraseLogs($this->entityManager); default: - return new JsonResponse(['success' => false]); + return new JsonResponse(['success' => false, 'error' => 'bad parameters'], JsonResponse::HTTP_BAD_REQUEST); } } diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php index da16758..bb99c13 100644 --- a/src/view/FooterBuilder.php +++ b/src/view/FooterBuilder.php @@ -99,7 +99,7 @@ class FooterBuilder extends AbstractBuilder private function makePageModifModeButton(): string { $link_edit_page = new URL(['page' => CURRENT_PAGE]); - if(!in_array(CURRENT_PAGE, ['article', 'new_page', 'menu_paths', 'maintenance'])) // ajouter 'user_edit' et 'connection' le jour où ces pages auront un footer + if(!in_array(CURRENT_PAGE, ViewController::SPECIAL_PAGES)) // cas impossibles: 'user_edit' et 'connection' qui n'ont pas de footer { if(MainBuilder::$modif_mode){ $link_edit_label = 'Sortir du mode modification'; diff --git a/src/view/MainBuilder.php b/src/view/MainBuilder.php index b488703..b888a56 100644 --- a/src/view/MainBuilder.php +++ b/src/view/MainBuilder.php @@ -53,10 +53,10 @@ class MainBuilder extends AbstractBuilder } // mode modification de page uniquement - private function viewEditBlocks($node): void + private function viewEditBlocks(Node $node): void { $options = ''; - foreach(Blocks::$blocks as $key => $value){ + foreach(Presentation::$blocks as $key => $value){ $options .= '\n"; } @@ -69,7 +69,7 @@ class MainBuilder extends AbstractBuilder } // présentation par défaut - if(Blocks::hasPresentation($child_node->getName()) && $child_node->getNodeData()->getPresentation() === null){ + if(Presentation::hasPresentation($child_node->getName()) && $child_node->getNodeData()->getPresentation() === null){ $child_node->getNodeData()->setPresentation('full_width'); // pas de persistence ici } @@ -87,7 +87,7 @@ class MainBuilder extends AbstractBuilder private function makePresentationOptions(string $presentation): string { $options = ''; - foreach(Blocks::$presentations as $key => $value){ + foreach(Presentation::$presentations as $key => $value){ $options .= ''; } return $options; diff --git a/src/view/templates/modify_block.php b/src/view/templates/modify_block.php index d855a4a..1da3176 100644 --- a/src/view/templates/modify_block.php +++ b/src/view/templates/modify_block.php @@ -1,7 +1,7 @@
-
getName())){ +if(App\Entity\Presentation::hasPresentation($child_node->getName())){ ?>
-- cgit v1.2.3