From deed404d80f853000e514e4c74375df0ddb2a09a Mon Sep 17 00:00:00 2001
From: Camille Simiand <camille.simiand@tetras-libre.fr>
Date: Wed, 12 Jan 2022 17:40:08 +0100
Subject: [PATCH] Add pagination on capsule page with Knp Pagnitor Bundle

---
 composer.json                                 |  10 +-
 composer.lock                                 | 179 +++++++++++++++++-
 config/bundles.php                            |   1 +
 config/packages/paginator.yaml                |  13 ++
 config/packages/twig.yaml                     |   4 +-
 src/Controller/CapsuleController.php          |  16 +-
 templates/capsule/index.html.twig             |   8 +-
 .../ResetPasswordControllerTest.php           |   2 +-
 8 files changed, 212 insertions(+), 21 deletions(-)
 create mode 100644 config/packages/paginator.yaml

diff --git a/composer.json b/composer.json
index 17d572c..be6047c 100644
--- a/composer.json
+++ b/composer.json
@@ -9,6 +9,7 @@
         "ext-curl": "*",
         "ext-iconv": "*",
         "ext-json": "*",
+        "ext-simplexml": "*",
         "ext-zip": "^1.15",
         "composer/package-versions-deprecated": "1.11.99.4",
         "doctrine/annotations": "^1.0",
@@ -16,6 +17,7 @@
         "doctrine/doctrine-migrations-bundle": "^3.2",
         "doctrine/orm": "^2.10",
         "gregwar/captcha-bundle": "^2.1",
+        "knplabs/knp-paginator-bundle": "^5.8",
         "phpdocumentor/reflection-docblock": "^5.3",
         "sensio/framework-extra-bundle": "^6.1",
         "symfony/asset": "5.3.*",
@@ -34,7 +36,7 @@
         "symfony/process": "5.3.*",
         "symfony/property-access": "5.3.*",
         "symfony/property-info": "5.3.*",
-        "symfony/proxy-manager-bridge": "5.3.*",
+        "symfony/proxy-manager-bridge": "^5.4",
         "symfony/runtime": "5.3.*",
         "symfony/security-bundle": "5.3.*",
         "symfony/security-csrf": "5.3.*",
@@ -50,8 +52,7 @@
         "symfonycasts/reset-password-bundle": "^1.11",
         "symfonycasts/verify-email-bundle": "^1.6",
         "twig/extra-bundle": "^2.12|^3.0",
-        "twig/twig": "^2.12|^3.0",
-      "ext-simplexml": "*"
+        "twig/twig": "^2.12|^3.0"
     },
     "require-dev": {
         "ext-dom": "*",
@@ -70,8 +71,7 @@
         "symfony/maker-bundle": "^1.0",
         "symfony/phpunit-bridge": "^5.3",
         "symfony/stopwatch": "5.3.*",
-        "symfony/web-profiler-bundle": "5.3.*",
-      "ext-imap": "*"
+        "symfony/web-profiler-bundle": "5.3.*"
     },
     "config": {
         "optimize-autoloader": true,
diff --git a/composer.lock b/composer.lock
index 71384d7..1823b30 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "3badb0e15c5718d6bafe1e9fb50518da",
+    "content-hash": "5a3fe5b92e70e4b11bd1416b24082640",
     "packages": [
         {
             "name": "composer/package-versions-deprecated",
@@ -1711,6 +1711,165 @@
             },
             "time": "2021-04-20T07:20:37+00:00"
         },
+        {
+            "name": "knplabs/knp-components",
+            "version": "v3.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/KnpLabs/knp-components.git",
+                "reference": "03e8ad16261dd8a70a8c6e01f18eb3852437546e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/KnpLabs/knp-components/zipball/03e8ad16261dd8a70a8c6e01f18eb3852437546e",
+                "reference": "03e8ad16261dd8a70a8c6e01f18eb3852437546e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.3 || ^8.0",
+                "symfony/event-dispatcher-contracts": "^1.1 || ^2.0",
+                "symfony/http-foundation": "^4.4 || ^5.3 || ^6.0"
+            },
+            "conflict": {
+                "doctrine/dbal": "<2.10"
+            },
+            "require-dev": {
+                "doctrine/mongodb-odm": "^2.0",
+                "doctrine/orm": "^2.7",
+                "doctrine/phpcr-odm": "^1.2",
+                "ext-pdo_sqlite": "*",
+                "jackalope/jackalope-doctrine-dbal": "^1.2",
+                "phpunit/phpunit": "^9.5",
+                "propel/propel1": "^1.7",
+                "ruflin/elastica": "^7.0",
+                "solarium/solarium": "^6.0",
+                "symfony/http-kernel": "^4.4 || ^5.2",
+                "symfony/property-access": "^4.4 || ^5.3 || ^6.0"
+            },
+            "suggest": {
+                "doctrine/common": "to allow usage pagination with Doctrine ArrayCollection",
+                "doctrine/mongodb-odm": "to allow usage pagination with Doctrine ODM MongoDB",
+                "doctrine/orm": "to allow usage pagination with Doctrine ORM",
+                "doctrine/phpcr-odm": "to allow usage pagination with Doctrine ODM PHPCR",
+                "propel/propel1": "to allow usage pagination with Propel ORM",
+                "ruflin/elastica": "to allow usage pagination with ElasticSearch Client",
+                "solarium/solarium": "to allow usage pagination with Solarium Client",
+                "symfony/property-access": "To allow sorting arrays"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Knp\\Component\\": "src/Knp/Component"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "KnpLabs Team",
+                    "homepage": "https://knplabs.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://github.com/KnpLabs/knp-components/contributors"
+                }
+            ],
+            "description": "Knplabs component library",
+            "homepage": "http://github.com/KnpLabs/knp-components",
+            "keywords": [
+                "components",
+                "knp",
+                "knplabs",
+                "pager",
+                "paginator"
+            ],
+            "support": {
+                "issues": "https://github.com/KnpLabs/knp-components/issues",
+                "source": "https://github.com/KnpLabs/knp-components/tree/v3.3.0"
+            },
+            "time": "2021-10-29T06:56:28+00:00"
+        },
+        {
+            "name": "knplabs/knp-paginator-bundle",
+            "version": "v5.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/KnpLabs/KnpPaginatorBundle.git",
+                "reference": "216b9d5708001788321916c5b7632da9fb9ef6ca"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/KnpLabs/KnpPaginatorBundle/zipball/216b9d5708001788321916c5b7632da9fb9ef6ca",
+                "reference": "216b9d5708001788321916c5b7632da9fb9ef6ca",
+                "shasum": ""
+            },
+            "require": {
+                "knplabs/knp-components": "^2.4 || ^3.0",
+                "php": "^7.3 || ^8.0",
+                "symfony/config": "^4.4 || ^5.3 || ^6.0",
+                "symfony/dependency-injection": "^4.4 || ^5.3 || ^6.0",
+                "symfony/event-dispatcher": "^4.4 || ^5.3 || ^6.0",
+                "symfony/http-foundation": "^4.4 || ^5.3 || ^6.0",
+                "symfony/http-kernel": "^4.4 || ^5.3 || ^6.0",
+                "symfony/routing": "^4.4 || ^5.3 || ^6.0",
+                "symfony/translation": "^4.4 || ^5.3 || ^6.0",
+                "twig/twig": "^2.0 || ^3.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^0.12.93",
+                "phpunit/phpunit": "^8.5 || ^9.5",
+                "symfony/expression-language": "^4.4 || ^5.3 || ^6.0",
+                "symfony/templating": "^4.4 || ^5.3 || ^6.0"
+            },
+            "type": "symfony-bundle",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Knp\\Bundle\\PaginatorBundle\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "KnpLabs Team",
+                    "homepage": "http://knplabs.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://github.com/KnpLabs/KnpPaginatorBundle/contributors"
+                }
+            ],
+            "description": "Paginator bundle for Symfony to automate pagination and simplify sorting and other features",
+            "homepage": "http://github.com/KnpLabs/KnpPaginatorBundle",
+            "keywords": [
+                "bundle",
+                "knp",
+                "knplabs",
+                "pager",
+                "pagination",
+                "paginator",
+                "symfony"
+            ],
+            "support": {
+                "issues": "https://github.com/KnpLabs/KnpPaginatorBundle/issues",
+                "source": "https://github.com/KnpLabs/KnpPaginatorBundle/tree/v5.8.0"
+            },
+            "time": "2021-10-30T08:27:46+00:00"
+        },
         {
             "name": "laminas/laminas-code",
             "version": "4.5.0",
@@ -5839,27 +5998,26 @@
         },
         {
             "name": "symfony/proxy-manager-bridge",
-            "version": "v5.3.11",
+            "version": "v5.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/proxy-manager-bridge.git",
-                "reference": "c774a6a852fd702154414e76f8dcd4e96086c2a8"
+                "reference": "50aa8ac8012d414f2aed26be760e0654abec2d76"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/c774a6a852fd702154414e76f8dcd4e96086c2a8",
-                "reference": "c774a6a852fd702154414e76f8dcd4e96086c2a8",
+                "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/50aa8ac8012d414f2aed26be760e0654abec2d76",
+                "reference": "50aa8ac8012d414f2aed26be760e0654abec2d76",
                 "shasum": ""
             },
             "require": {
-                "composer/package-versions-deprecated": "^1.8",
                 "friendsofphp/proxy-manager-lts": "^1.0.2",
                 "php": ">=7.2.5",
-                "symfony/dependency-injection": "^5.0",
+                "symfony/dependency-injection": "^5.0|^6.0",
                 "symfony/polyfill-php80": "^1.16"
             },
             "require-dev": {
-                "symfony/config": "^4.4|^5.0"
+                "symfony/config": "^4.4|^5.0|^6.0"
             },
             "type": "symfony-bridge",
             "autoload": {
@@ -5887,7 +6045,7 @@
             "description": "Provides integration for ProxyManager with various Symfony components",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/proxy-manager-bridge/tree/v5.3.11"
+                "source": "https://github.com/symfony/proxy-manager-bridge/tree/v5.4.2"
             },
             "funding": [
                 {
@@ -5903,7 +6061,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-17T12:16:12+00:00"
+            "time": "2021-12-25T19:45:36+00:00"
         },
         {
             "name": "symfony/routing",
@@ -10960,6 +11118,7 @@
         "ext-curl": "*",
         "ext-iconv": "*",
         "ext-json": "*",
+        "ext-simplexml": "*",
         "ext-zip": "^1.15"
     },
     "platform-dev": {
diff --git a/config/bundles.php b/config/bundles.php
index 3b2aefd..5175442 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -18,4 +18,5 @@ return [
     DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
     Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
     SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true],
+    Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true]
 ];
diff --git a/config/packages/paginator.yaml b/config/packages/paginator.yaml
new file mode 100644
index 0000000..6b7060c
--- /dev/null
+++ b/config/packages/paginator.yaml
@@ -0,0 +1,13 @@
+knp_paginator:
+  page_range: 3                     # number of links showed in the pagination menu (e.g: you have 10 pages, a page_range of 3, on the 5th page you'll see links to page 4, 5, 6)
+  default_options:
+    page_name: page                 # page query parameter name
+    sort_field_name: sort           # sort field query parameter name
+    sort_direction_name: direction  # sort direction query parameter name
+    distinct: true                  # ensure distinct results, useful when ORM queries are using GROUP BY statements
+    filter_field_name: filterField  # filter field query parameter name
+    filter_value_name: filterValue  # filter value query parameter name
+  template:
+    pagination:  '@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig'    # sliding pagination controls template
+    sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
+    filtration: '@KnpPaginator/Pagination/filtration.html.twig'
\ No newline at end of file
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
index 3be7d52..12a4d48 100644
--- a/config/packages/twig.yaml
+++ b/config/packages/twig.yaml
@@ -1,7 +1,9 @@
 twig:
     default_path: '%kernel.project_dir%/templates'
     form_themes: ['bootstrap_5_layout.html.twig']
+    paths:
+        '%kernel.project_dir%/vendor/knplabs/knp-paginator-bundle/templates': KnpPaginator
 
 when@test:
     twig:
-        strict_variables: true
+        strict_variables: true
\ No newline at end of file
diff --git a/src/Controller/CapsuleController.php b/src/Controller/CapsuleController.php
index d970dff..55dc82b 100644
--- a/src/Controller/CapsuleController.php
+++ b/src/Controller/CapsuleController.php
@@ -7,6 +7,7 @@ use App\Helper\StringHelper;
 use App\Repository\CapsuleRepository;
 use App\Builder\CapsuleBuilder;
 use App\Form\CreateCapsuleFormType;
+use Knp\Component\Pager\PaginatorInterface;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
@@ -20,15 +21,24 @@ class CapsuleController extends AbstractController
      * @Route("/my_capsules", name="capsule_list")
      * @Route("/", name="home")
      */
-    public function index(CapsuleRepository $capsuleRepository): Response
-    {
+    public function index(
+        CapsuleRepository $capsuleRepository,
+        PaginatorInterface $paginator,
+        Request $request
+    ): Response {
         $current_user = $this->getUser();
 
         if (! $current_user instanceof User) {
             return $this->redirectToRoute('app_logout');
         }
 
-        $capsules = $capsuleRepository->findBy(['creation_author' => $current_user]);
+        $all_capsules = $capsuleRepository->findBy(['creation_author' => $current_user]);
+
+        $capsules = $paginator->paginate(
+            $all_capsules,
+            $request->query->getInt('page', 1),
+            5
+        );
 
         return $this->render('capsule/index.html.twig', [
             'capsules' => $capsules,
diff --git a/templates/capsule/index.html.twig b/templates/capsule/index.html.twig
index 382d145..80eee00 100644
--- a/templates/capsule/index.html.twig
+++ b/templates/capsule/index.html.twig
@@ -9,7 +9,9 @@
 {% block body %}
     <div class="row gx-0">
         <div class="row-title-box">
-            <h3 class="row-title">My capsules</h3>
+            <h3 class="row-title">
+                {{ 'capsule.title'|trans }}
+            </h3>
         </div>
     </div>
 <div class="mt-4">
@@ -83,6 +85,10 @@
             </div>
         </div>
         {% endfor %}
+
+        <div class="d-inline-flex justify-content-center m-auto mb-3 col-2 p-3">
+            {{ knp_pagination_render(capsules) }}
+        </div>
     </div>
 
 {% endblock %}
diff --git a/tests/functional/ResetPasswordControllerTest.php b/tests/functional/ResetPasswordControllerTest.php
index 0e7e57c..607a1a5 100644
--- a/tests/functional/ResetPasswordControllerTest.php
+++ b/tests/functional/ResetPasswordControllerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace App\Tests\Controller;
+namespace App\Tests\functional;
 
 use Symfony\Bundle\FrameworkBundle\KernelBrowser;
 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
-- 
GitLab