From 67899d4a362bd053249c15ecc500354456d36c8f Mon Sep 17 00:00:00 2001
From: Tobias Gross-Vogt <tgros@tugraz.at>
Date: Tue, 20 Sep 2022 09:44:26 +0200
Subject: [PATCH] added pagination support

---
 composer.json                      |  2 +-
 composer.lock                      | 10 +++++-----
 src/Service/LDAPApi.php            | 28 +++++++++++++++++-----------
 src/Service/LDAPPersonProvider.php |  5 ++---
 4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/composer.json b/composer.json
index 3362392..61f640d 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
         "ext-simplexml": "*",
         "adldap2/adldap2": "^10.3",
         "dbp/relay-auth-bundle": "^0.1.6",
-        "dbp/relay-base-person-bundle": "^0.2.2",
+        "dbp/relay-base-person-bundle": "^0.3.0",
         "dbp/relay-core-bundle": "^0.1.38",
         "guzzlehttp/guzzle": "^7.3",
         "league/uri": "^6.5",
diff --git a/composer.lock b/composer.lock
index 31de557..e926425 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": "f9348007e76a9114cc35c21e3312c9b4",
+    "content-hash": "f6fe58d76950c7e09974a1a334ed2ad0",
     "packages": [
         {
             "name": "adldap2/adldap2",
@@ -354,11 +354,11 @@
         },
         {
             "name": "dbp/relay-base-person-bundle",
-            "version": "v0.2.2",
+            "version": "v0.3.0",
             "source": {
                 "type": "git",
                 "url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-base-person-bundle",
-                "reference": "41add7e3408b9e3085c23ea770e07995480b9df3"
+                "reference": "daf1d3dfa69891a07895c2416d75c62edc4aa98b"
             },
             "require": {
                 "api-platform/core": "^2.6.3",
@@ -399,7 +399,7 @@
             "license": [
                 "AGPL-3.0-or-later"
             ],
-            "time": "2022-08-16T11:01:05+00:00"
+            "time": "2022-09-20T07:22:42+00:00"
         },
         {
             "name": "dbp/relay-core-bundle",
@@ -11148,5 +11148,5 @@
     "platform-overrides": {
         "php": "7.3"
     },
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.2.0"
 }
diff --git a/src/Service/LDAPApi.php b/src/Service/LDAPApi.php
index b7dcef5..b8d8012 100644
--- a/src/Service/LDAPApi.php
+++ b/src/Service/LDAPApi.php
@@ -14,6 +14,7 @@ use Adldap\Connections\Provider;
 use Adldap\Connections\ProviderInterface;
 use Adldap\Models\User;
 use Adldap\Query\Builder;
+use Adldap\Query\Paginator as AdldapPaginator;
 use Dbp\Relay\BasePersonBundle\Entity\Person;
 use Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonFromUserItemPostEvent;
 use Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonPreEvent;
@@ -22,6 +23,8 @@ use Dbp\Relay\CoreBundle\API\UserSessionInterface;
 use Dbp\Relay\CoreBundle\Exception\ApiError;
 use Dbp\Relay\CoreBundle\Helpers\Tools as CoreTools;
 use Dbp\Relay\CoreBundle\LocalData\LocalDataAwareEventDispatcher;
+use Dbp\Relay\CoreBundle\Pagination\Pagination;
+use Dbp\Relay\CoreBundle\Pagination\Paginator;
 use Psr\Cache\CacheItemPoolInterface;
 use Psr\Container\ContainerInterface;
 use Psr\Log\LoggerAwareInterface;
@@ -35,8 +38,6 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
 {
     use LoggerAwareTrait;
 
-    private $PAGESIZE = 50;
-
     /** @var ProviderInterface|null */
     private $provider;
 
@@ -197,7 +198,7 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
     /*
      * @throws ApiError
      */
-    private function getPeopleUserItems(array $filters): array
+    private function getPeopleUserItems(array $options): AdldapPaginator
     {
         try {
             $provider = $this->getProvider();
@@ -206,8 +207,8 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
             $search = $builder
                 ->where('objectClass', '=', $provider->getSchema()->person());
 
-            if (isset($filters['search'])) {
-                $items = explode(' ', $filters['search']);
+            if (isset($options['search'])) {
+                $items = explode(' ', $options['search']);
 
                 // search for all substrings
                 foreach ($items as $item) {
@@ -215,7 +216,12 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
                 }
             }
 
-            return $search->sortBy($this->familyNameAttributeName, 'asc')->paginate($this->PAGESIZE)->getResults();
+            $maxNumItemsPerPage = Pagination::getMaxNumItemsPerPage($options);
+            // API platform's first page is 1, Adldap's first page is 0
+            $currentPageIndex = Pagination::getCurrentPageNumber($options) - 1;
+
+            return $search->sortBy($this->familyNameAttributeName, 'asc')
+                ->paginate($maxNumItemsPerPage, $currentPageIndex);
         } catch (\Adldap\Auth\BindException $e) {
             // There was an issue binding / connecting to the server.
             throw ApiError::withDetails(Response::HTTP_BAD_GATEWAY, sprintf('People could not be loaded! Message: %s', CoreTools::filterErrorMessage($e->getMessage())));
@@ -225,7 +231,7 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
     /*
      * @throws ApiError
      */
-    public function getPersons(array $options): array
+    public function getPersons(array $options): Paginator
     {
         $this->eventDispatcher->onNewOperation($options);
 
@@ -234,13 +240,13 @@ class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
         $options = array_merge($options, $preEvent->getQueryParameters());
 
         $persons = [];
-        $items = $this->getPeopleUserItems($options);
-        foreach ($items as $item) {
-            $person = $this->personFromUserItem($item, false);
+        $paginator = $this->getPeopleUserItems($options);
+        foreach ($paginator as $userItem) {
+            $person = $this->personFromUserItem($userItem, false);
             $persons[] = $person;
         }
 
-        return $persons;
+        return Pagination::createFullPaginator($persons, $options, count($paginator));
     }
 
     /*
diff --git a/src/Service/LDAPPersonProvider.php b/src/Service/LDAPPersonProvider.php
index 8d6f9b8..2609db8 100644
--- a/src/Service/LDAPPersonProvider.php
+++ b/src/Service/LDAPPersonProvider.php
@@ -7,6 +7,7 @@ namespace Dbp\Relay\BasePersonConnectorLdapBundle\Service;
 use Dbp\Relay\BasePersonBundle\API\PersonProviderInterface;
 use Dbp\Relay\BasePersonBundle\Entity\Person;
 use Dbp\Relay\CoreBundle\Exception\ApiError;
+use Dbp\Relay\CoreBundle\Pagination\Paginator;
 
 class LDAPPersonProvider implements PersonProviderInterface
 {
@@ -25,10 +26,8 @@ class LDAPPersonProvider implements PersonProviderInterface
      *                       * LocalData::QUERY_PARAMETER_NAME
      *
      * @throws ApiError
-     *
-     * @return Person[]
      */
-    public function getPersons(array $options): array
+    public function getPersons(array $options): Paginator
     {
         return $this->ldapApi->getPersons($options);
     }
-- 
GitLab