diff options
| author | polo <ordipolo@gmx.fr> | 2025-10-09 01:35:52 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2025-10-09 01:35:52 +0200 |
| commit | 15cbf5d56b4644151d59fee512f5f8fbe496caa3 (patch) | |
| tree | 0da411f4aff53a0249cf3d59ea13f3786897b740 /src/controller | |
| parent | 9f88389d78755d7c69c29e9db8f114fd1dbef034 (diff) | |
| download | cms-15cbf5d56b4644151d59fee512f5f8fbe496caa3.tar.gz cms-15cbf5d56b4644151d59fee512f5f8fbe496caa3.tar.bz2 cms-15cbf5d56b4644151d59fee512f5f8fbe496caa3.zip | |
pagination partie 2, nouvelles fonctions + renommage dans Director, ArticleController::fetch, et en JS: fetchArticles, insertLocalDates, modifs dans changePaginationLimit, dans les vues
Diffstat (limited to 'src/controller')
| -rw-r--r-- | src/controller/ArticleController.php | 41 | ||||
| -rw-r--r-- | src/controller/Director.php | 132 | ||||
| -rw-r--r-- | src/controller/PageManagementController.php | 17 |
3 files changed, 135 insertions, 55 deletions
diff --git a/src/controller/ArticleController.php b/src/controller/ArticleController.php index 411c1dc..8bbef19 100644 --- a/src/controller/ArticleController.php +++ b/src/controller/ArticleController.php | |||
| @@ -6,10 +6,51 @@ declare(strict_types=1); | |||
| 6 | use App\Entity\Node; | 6 | use App\Entity\Node; |
| 7 | use App\Entity\Article; | 7 | use App\Entity\Article; |
| 8 | use Doctrine\ORM\EntityManager; | 8 | use Doctrine\ORM\EntityManager; |
| 9 | use Symfony\Component\HttpFoundation\Request; | ||
| 9 | use Symfony\Component\HttpFoundation\Response; | 10 | use Symfony\Component\HttpFoundation\Response; |
| 10 | 11 | ||
| 11 | class ArticleController | 12 | class ArticleController |
| 12 | { | 13 | { |
| 14 | static public function fetch(EntityManager $entityManager, Request $request): void | ||
| 15 | { | ||
| 16 | if($request->query->has('id') && !empty($request->query->get('id')) && $request->query->has('last_article')){ | ||
| 17 | //var_dump($request->query->get('last_article')); | ||
| 18 | $id = (int)$request->get('id'); // type et nettoie | ||
| 19 | $director = new Director($entityManager); | ||
| 20 | $director->findNodeById($id); | ||
| 21 | $parent_block = $director->getNode(); | ||
| 22 | |||
| 23 | if(Blocks::hasPresentation($parent_block->getName())){ | ||
| 24 | $get_articles_return = $director->getNextArticles($parent_block, $request); | ||
| 25 | $bulk_data = $get_articles_return[0]; | ||
| 26 | |||
| 27 | if($parent_block->getName() === 'post_block'){ | ||
| 28 | $builder_name = 'PostBuilder'; | ||
| 29 | } | ||
| 30 | elseif($parent_block->getName() === 'news_block'){ | ||
| 31 | $builder_name = 'NewBuilder'; | ||
| 32 | } | ||
| 33 | |||
| 34 | $html = ''; | ||
| 35 | foreach($bulk_data as $article){ | ||
| 36 | $builder = new $builder_name($article); | ||
| 37 | $html .= $builder->render(); | ||
| 38 | } | ||
| 39 | |||
| 40 | echo json_encode(['success' => true, 'html' => $html, 'truncated' => $get_articles_return[1]]); | ||
| 41 | die; | ||
| 42 | } | ||
| 43 | else{ | ||
| 44 | echo json_encode(['success' => false, 'error' => 'mauvais type de bloc']); | ||
| 45 | die; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | else{ | ||
| 49 | echo json_encode(['success' => false, 'error' => 'la requête ne comporte pas les paramètres attendus']); | ||
| 50 | die; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 13 | static public function editorSubmit(EntityManager $entityManager, array $json): void | 54 | static public function editorSubmit(EntityManager $entityManager, array $json): void |
| 14 | { | 55 | { |
| 15 | if(json_last_error() === JSON_ERROR_NONE) | 56 | if(json_last_error() === JSON_ERROR_NONE) |
diff --git a/src/controller/Director.php b/src/controller/Director.php index 8f038fa..9c1c6e3 100644 --- a/src/controller/Director.php +++ b/src/controller/Director.php | |||
| @@ -1,12 +1,14 @@ | |||
| 1 | <?php | 1 | <?php |
| 2 | // src/controller/Director.php | 2 | // src/controller/Director.php |
| 3 | 3 | ||
| 4 | // => src/model/Model.php serait mieux | ||
| 5 | |||
| 4 | declare(strict_types=1); | 6 | declare(strict_types=1); |
| 5 | 7 | ||
| 6 | use Doctrine\ORM\EntityManager; | 8 | use Doctrine\ORM\EntityManager; |
| 7 | use App\Entity\Page; | 9 | use App\Entity\Page; |
| 8 | use App\Entity\Node; | 10 | use App\Entity\Node; |
| 9 | //use Doctrine\ORM\QueryBuilder; | 11 | use Doctrine\ORM\QueryBuilder; |
| 10 | use Symfony\Component\HttpFoundation\Request; | 12 | use Symfony\Component\HttpFoundation\Request; |
| 11 | 13 | ||
| 12 | class Director | 14 | class Director |
| @@ -24,7 +26,9 @@ class Director | |||
| 24 | $this->node = new Node; // instance mère "vide" ne possédant rien d'autre que des enfants | 26 | $this->node = new Node; // instance mère "vide" ne possédant rien d'autre que des enfants |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | public function makeMenuAndPaths(): void | 29 | // à déplacer dans Path ou un truc comme ça? |
| 30 | // couper Director en deux classes NodeModel et PageModel? | ||
| 31 | public function makeMenuAndPaths(): void // lit la table "page" | ||
| 28 | { | 32 | { |
| 29 | self::$menu_data = new Menu($this->entityManager); | 33 | self::$menu_data = new Menu($this->entityManager); |
| 30 | self::$page_path = new Path(); | 34 | self::$page_path = new Path(); |
| @@ -41,13 +45,12 @@ class Director | |||
| 41 | } | 45 | } |
| 42 | 46 | ||
| 43 | // affichage d'une page ordinaire | 47 | // affichage d'une page ordinaire |
| 44 | public function getWholePageData(Request $request): void | 48 | public function getWholePageData(Request $request): void // lit la table "node" + jointures |
| 45 | { | 49 | { |
| 46 | $id = CURRENT_PAGE === 'article' ? htmlspecialchars($request->query->get('id')) : ''; | 50 | $id = CURRENT_PAGE === 'article' ? htmlspecialchars($request->query->get('id')) : ''; |
| 47 | 51 | ||
| 48 | if($id === '') // page "normale" | 52 | if($id === ''){ // page "normale" |
| 49 | { | 53 | // récupérer tous les noeuds sauf les articles |
| 50 | // tous les noeuds sauf les articles, tri par page | ||
| 51 | $dql = "SELECT n FROM App\Entity\Node n WHERE n.name_node != 'new' AND n.name_node != 'post' AND (n.page = :page OR n.page IS null)"; | 54 | $dql = "SELECT n FROM App\Entity\Node n WHERE n.name_node != 'new' AND n.name_node != 'post' AND (n.page = :page OR n.page IS null)"; |
| 52 | $bulk_data = $this->entityManager | 55 | $bulk_data = $this->entityManager |
| 53 | ->createQuery($dql) | 56 | ->createQuery($dql) |
| @@ -57,45 +60,11 @@ class Director | |||
| 57 | // groupes d'articles triés par bloc, permet de paginer par bloc | 60 | // groupes d'articles triés par bloc, permet de paginer par bloc |
| 58 | foreach($bulk_data as $parent_block){ | 61 | foreach($bulk_data as $parent_block){ |
| 59 | if(Blocks::hasPresentation($parent_block->getName())){ // = post_block ou news_block | 62 | if(Blocks::hasPresentation($parent_block->getName())){ // = post_block ou news_block |
| 60 | $qb = $this->entityManager->createQueryBuilder(); | 63 | $bulk_data = array_merge($bulk_data, $this->getNextArticles($parent_block, $request)[0]); |
| 61 | $qb->select('n') | ||
| 62 | ->from('App\Entity\Node', 'n') | ||
| 63 | ->where('n.parent = :parent') | ||
| 64 | ->setParameter('parent', $parent_block); | ||
| 65 | |||
| 66 | if($parent_block->getName() === 'post_block'){ | ||
| 67 | $qb->orderBy('n.position'); | ||
| 68 | } | ||
| 69 | elseif($parent_block->getName() === 'news_block'){ | ||
| 70 | $qb->join('n.article', 'a'); | ||
| 71 | if($parent_block->getNodeData()->getChronoOrder() ?? false){ // ordre antichrono par défaut | ||
| 72 | $qb->orderBy('a.date_time', 'ASC'); | ||
| 73 | } | ||
| 74 | else{ | ||
| 75 | $qb->orderBy('a.date_time', 'DESC'); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | // pagination | ||
| 80 | $limit = $parent_block->getNodeData()->getPaginationLimit() ?? 0; // 0 par défaut = pas de pagination, sinon 12 rend bien avec des grilles de 2, 3 ou 4 colonnes | ||
| 81 | if($limit > 0){ | ||
| 82 | //$this->paginateWithCursor($qb, $request->query->get('last_position') ?? 0, $limit); | ||
| 83 | $qb->andWhere('n.position > :last_position') | ||
| 84 | ->setParameter('last_position', $request->query->get('last_position') ?? 0) | ||
| 85 | ->setMaxResults($limit); | ||
| 86 | |||
| 87 | $nb_pages = $this->getNumberOfPages($parent_block, $limit); // nombres de "pages" d'articles | ||
| 88 | if($nb_pages > 1){ | ||
| 89 | //$parent_block->setNumberOfPages($nb_pages); // => navigation en HTML | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | $bulk_data = array_merge($bulk_data, $qb->getQuery()->getResult()); | ||
| 94 | } | 64 | } |
| 95 | } | 65 | } |
| 96 | } | 66 | } |
| 97 | else // page "article" | 67 | else{ // page "article" |
| 98 | { | ||
| 99 | $dql = 'SELECT n FROM App\Entity\Node n WHERE n.page = :page OR n.page IS null OR n.id_node = :id'; | 68 | $dql = 'SELECT n FROM App\Entity\Node n WHERE n.page = :page OR n.page IS null OR n.id_node = :id'; |
| 100 | $bulk_data = $this->entityManager | 69 | $bulk_data = $this->entityManager |
| 101 | ->createQuery($dql) | 70 | ->createQuery($dql) |
| @@ -103,18 +72,74 @@ class Director | |||
| 103 | ->setParameter('id', $id) | 72 | ->setParameter('id', $id) |
| 104 | ->getResult(); | 73 | ->getResult(); |
| 105 | } | 74 | } |
| 75 | |||
| 106 | $this->makeNodeTree($bulk_data); | 76 | $this->makeNodeTree($bulk_data); |
| 107 | } | 77 | } |
| 108 | 78 | ||
| 109 | /*private function paginateWithCursor(QueryBuilder $qb, int $last_position = 0, int $limit = 0): void | 79 | // récupération d'articles |
| 80 | public function getNextArticles(Node $parent_block, Request $request): array | ||
| 81 | { | ||
| 82 | $qb = $this->entityManager->createQueryBuilder(); | ||
| 83 | $qb->select('n') | ||
| 84 | ->from('App\Entity\Node', 'n') | ||
| 85 | ->where('n.parent = :parent') | ||
| 86 | ->setParameter('parent', $parent_block); | ||
| 87 | |||
| 88 | if($parent_block->getName() === 'post_block'){ | ||
| 89 | $qb->orderBy('n.position'); | ||
| 90 | } | ||
| 91 | elseif($parent_block->getName() === 'news_block'){ | ||
| 92 | $qb->join('n.article', 'a'); | ||
| 93 | if($parent_block->getNodeData()->getChronoOrder() ?? false){ // ordre antichrono par défaut | ||
| 94 | $qb->orderBy('a.date_time', 'ASC'); | ||
| 95 | } | ||
| 96 | else{ | ||
| 97 | $qb->orderBy('a.date_time', 'DESC'); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | // pagination | ||
| 102 | $limit = $parent_block->getNodeData()->getPaginationLimit(); // = 12 par défaut si = null en BDD | ||
| 103 | $this->paginateWithCursor($qb, $parent_block, $request->query->get('last_article')); | ||
| 104 | $result = $qb->getQuery()->getResult(); | ||
| 105 | |||
| 106 | // il reste des articles à récupérer SI on vient d'en récupérer trop | ||
| 107 | // ET on gère le cas particulier de $limit <= 0 | ||
| 108 | $truncated = false; | ||
| 109 | if(count($result) > $limit && $limit > 0){ // si nb résultat > limit > 0 | ||
| 110 | $truncated = true; | ||
| 111 | array_pop($result); // compenser le $limit + 1 dans paginateWithCursor | ||
| 112 | } | ||
| 113 | |||
| 114 | return [$result, $truncated]; // besoin exceptionnel de retourner deux valeurs | ||
| 115 | } | ||
| 116 | |||
| 117 | private function paginateWithCursor(QueryBuilder $qb, Node $parent_block, ?string $last_article): void | ||
| 110 | { | 118 | { |
| 111 | $qb->andWhere('n.position > :last_position') | 119 | //var_dump($last_article); |
| 112 | ->setParameter('last_position', $last_position) | 120 | $limit = $parent_block->getNodeData()->getPaginationLimit(); // = 12 par défaut si = null en BDD |
| 113 | ->setMaxResults($limit); | 121 | |
| 114 | }*/ | 122 | if($limit > 0){ // si 0 ou moins pas de pagination |
| 123 | // nombres de "pages" d'articles | ||
| 124 | $nb_pages = $this->getNumberOfPages($parent_block, $limit); | ||
| 125 | $parent_block->getNodeData()->setNumberOfPages($nb_pages > 1 ? $nb_pages : 1); | ||
| 126 | |||
| 127 | // adaptation de la requête | ||
| 128 | if($parent_block->getName() === 'post_block'){ | ||
| 129 | $qb->andWhere('n.position > :last_position') | ||
| 130 | ->setParameter('last_position', empty($last_article) ? 0 : $last_article) | ||
| 131 | ->setMaxResults($limit + 1); | ||
| 132 | } | ||
| 133 | elseif($parent_block->getName() === 'news_block'){ | ||
| 134 | $cursor_start = $parent_block->getNodeData()->getChronoOrder() ? '1970-01-01' : '9999-12-31'; | ||
| 135 | $qb->andWhere($parent_block->getNodeData()->getChronoOrder() ? 'a.date_time > :date_time' : 'a.date_time < :date_time') | ||
| 136 | ->setParameter('date_time', empty($last_article) ? $cursor_start : $last_article) | ||
| 137 | ->setMaxResults($limit + 1); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 115 | 141 | ||
| 116 | // requête à part n'alimentant pas $bulk_data | 142 | // le Paginator de doctrine le fait aussi si on décidait de s'en servir |
| 117 | // fonctionnalité offerte par le Paginator de doctrine si on décidait de s'en servir | ||
| 118 | private function getNumberOfPages(Node $parent_block, int $limit): int | 143 | private function getNumberOfPages(Node $parent_block, int $limit): int |
| 119 | { | 144 | { |
| 120 | $dql = 'SELECT COUNT(n.id_node) FROM App\Entity\Node n WHERE n.parent = :parent'; | 145 | $dql = 'SELECT COUNT(n.id_node) FROM App\Entity\Node n WHERE n.parent = :parent'; |
| @@ -129,11 +154,9 @@ class Director | |||
| 129 | { | 154 | { |
| 130 | // puis on les range | 155 | // puis on les range |
| 131 | // (attention, risque de disfonctionnement si les noeuds de 1er niveau ne sont pas récupérés en 1er dans la BDD) | 156 | // (attention, risque de disfonctionnement si les noeuds de 1er niveau ne sont pas récupérés en 1er dans la BDD) |
| 132 | foreach($bulk_data as $node) | 157 | foreach($bulk_data as $node){ |
| 133 | { | ||
| 134 | // premier niveau | 158 | // premier niveau |
| 135 | if($node->getParent() == null) | 159 | if($node->getParent() == null){ |
| 136 | { | ||
| 137 | $this->node->addChild($node); | 160 | $this->node->addChild($node); |
| 138 | 161 | ||
| 139 | // spécifique page article | 162 | // spécifique page article |
| @@ -142,8 +165,7 @@ class Director | |||
| 142 | } | 165 | } |
| 143 | } | 166 | } |
| 144 | // autres niveaux | 167 | // autres niveaux |
| 145 | else | 168 | else{ |
| 146 | { | ||
| 147 | $node->getParent()->addChild($node); | 169 | $node->getParent()->addChild($node); |
| 148 | 170 | ||
| 149 | // spécifique page article | 171 | // spécifique page article |
diff --git a/src/controller/PageManagementController.php b/src/controller/PageManagementController.php index 2cc88a5..8efcb79 100644 --- a/src/controller/PageManagementController.php +++ b/src/controller/PageManagementController.php | |||
| @@ -334,4 +334,21 @@ class PageManagementController | |||
| 334 | } | 334 | } |
| 335 | die; | 335 | die; |
| 336 | } | 336 | } |
| 337 | static public function changePaginationLimit(EntityManager $entityManager, array $json): void | ||
| 338 | { | ||
| 339 | if(isset($json['id']) && isset($json['pagination_limit'])){ | ||
| 340 | $director = new Director($entityManager); | ||
| 341 | $director->findNodeById($json['id']); | ||
| 342 | $old_limit = $director->getNode()->getNodeData()->getPaginationLimit() ?? 12; | ||
| 343 | $director->getNode()->getNodeData()->setPaginationLimit((int)$json['pagination_limit']); // attention conversion? | ||
| 344 | |||
| 345 | $entityManager->flush(); | ||
| 346 | |||
| 347 | echo json_encode(['success' => true, 'old_limit' => $old_limit, 'new_limit' => $json['pagination_limit']]); | ||
| 348 | } | ||
| 349 | else{ | ||
| 350 | echo json_encode(['success' => false]); | ||
| 351 | } | ||
| 352 | die; | ||
| 353 | } | ||
| 337 | } \ No newline at end of file | 354 | } \ No newline at end of file |
