From 70920e0e045637986c533a804eae39d40df2e0cc Mon Sep 17 00:00:00 2001
From: Tobias Gross-Vogt <tgros@tugraz.at>
Date: Wed, 10 Aug 2022 11:22:43 +0200
Subject: [PATCH] introduces queryLocal logic; removed domain-specific query
 parameters term, organization, lecturer to connector impl

---
 composer.json                                 |   2 +-
 composer.lock                                 | 289 ++++++++++++++++--
 src/API/CourseProviderInterface.php           |  10 -
 src/Controller/GetAttendeesByCourse.php       |   2 +-
 .../CourseCollectionDataProvider.php          |  54 +---
 src/Entity/Course.php                         |   4 +-
 6 files changed, 277 insertions(+), 84 deletions(-)

diff --git a/composer.json b/composer.json
index e58ddd1..3a0181b 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
         "php": ">=7.3",
         "ext-json": "*",
         "api-platform/core": "^2.6",
-        "dbp/relay-core-bundle": "^0.1.37",
+        "dbp/relay-core-bundle": "dev-main as 0.1.37",
         "symfony/config": "^5.4",
         "symfony/framework-bundle": "^5.4",
         "symfony/security-bundle": "^5.4",
diff --git a/composer.lock b/composer.lock
index 98f2f83..0d300af 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": "c3250fce568b9896e229c4b518571f9c",
+    "content-hash": "6a230b56ba7f733bcfa3b81b0329f114",
     "packages": [
         {
             "name": "api-platform/core",
@@ -169,17 +169,11 @@
         },
         {
             "name": "dbp/relay-core-bundle",
-            "version": "0.1.37",
+            "version": "dev-main",
             "source": {
                 "type": "git",
-                "url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle.git",
-                "reference": "b58c833026de0aa0572a38684d0b0f2107e46aee"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://gitlab.tugraz.at/api/v4/projects/dbp%2Frelay%2Fdbp-relay-core-bundle/repository/archive.zip?sha=b58c833026de0aa0572a38684d0b0f2107e46aee",
-                "reference": "b58c833026de0aa0572a38684d0b0f2107e46aee",
-                "shasum": ""
+                "url": "git@gitlab.tugraz.at:dbp/relay/dbp-relay-core-bundle.git",
+                "reference": "ef4b59a336fc63384de22bea88b3bf6a4bdca6c3"
             },
             "require": {
                 "api-platform/core": "^2.6.6",
@@ -188,6 +182,8 @@
                 "ext-fileinfo": "*",
                 "ext-json": "*",
                 "guzzlehttp/guzzle": "^7.0",
+                "kevinrob/guzzle-cache-middleware": "^4.0",
+                "league/uri": "^6.5",
                 "nelmio/cors-bundle": "^2.1.0",
                 "php": "^7.3 || ^8.0",
                 "phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.0",
@@ -221,6 +217,7 @@
                 "symfony/phpunit-bridge": "^5.3",
                 "vimeo/psalm": "^4.4"
             },
+            "default-branch": true,
             "type": "symfony-bundle",
             "extra": {
                 "hooks": {
@@ -274,11 +271,7 @@
                 "AGPL-3.0-or-later"
             ],
             "description": "The core bundle of the Relay API gateway",
-            "support": {
-                "source": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle/-/tree/0.1.37",
-                "issues": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle/-/issues"
-            },
-            "time": "2022-06-22T11:04:47+02:00"
+            "time": "2022-08-10T09:18:18+00:00"
         },
         {
             "name": "doctrine/annotations",
@@ -965,6 +958,257 @@
             ],
             "time": "2022-06-20T21:43:11+00:00"
         },
+        {
+            "name": "kevinrob/guzzle-cache-middleware",
+            "version": "v4.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Kevinrob/guzzle-cache-middleware.git",
+                "reference": "0a61532ee8bf278a0d875a86a536aeeab592da5a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Kevinrob/guzzle-cache-middleware/zipball/0a61532ee8bf278a0d875a86a536aeeab592da5a",
+                "reference": "0a61532ee8bf278a0d875a86a536aeeab592da5a",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^6.0 || ^7.0",
+                "guzzlehttp/psr7": "^1.7.0 || ^2.0.0",
+                "php": ">=7.2.0"
+            },
+            "require-dev": {
+                "cache/array-adapter": "^0.4 || ^0.5 || ^1.0",
+                "cache/simple-cache-bridge": "^0.1 || ^1.0",
+                "doctrine/cache": "^1.10",
+                "illuminate/cache": "^5.0",
+                "league/flysystem": "^1.0",
+                "phpunit/phpunit": "^8.5.15 || ^9.5",
+                "psr/cache": "^1.0",
+                "symfony/cache": "^4.4 || ^5.0",
+                "symfony/phpunit-bridge": "^4.4 || ^5.0"
+            },
+            "suggest": {
+                "doctrine/cache": "This library has a lot of ready-to-use cache storage (to be used with Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage). Use only versions >=1.4.0 < 2.0.0",
+                "guzzlehttp/guzzle": "For using this library. It was created for Guzzle6 (but you can use it with any PSR-7 HTTP client).",
+                "laravel/framework": "To be used with Kevinrob\\GuzzleCache\\Storage\\LaravelCacheStorage",
+                "league/flysystem": "To be used with Kevinrob\\GuzzleCache\\Storage\\FlysystemStorage",
+                "psr/cache": "To be used with Kevinrob\\GuzzleCache\\Storage\\Psr6CacheStorage",
+                "psr/simple-cache": "To be used with Kevinrob\\GuzzleCache\\Storage\\Psr16CacheStorage"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Kevinrob\\GuzzleCache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Kevin Robatel",
+                    "email": "kevinrob2@gmail.com",
+                    "homepage": "https://github.com/Kevinrob"
+                }
+            ],
+            "description": "A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)",
+            "homepage": "https://github.com/Kevinrob/guzzle-cache-middleware",
+            "keywords": [
+                "Etag",
+                "Flysystem",
+                "Guzzle",
+                "cache",
+                "cache-control",
+                "doctrine",
+                "expiration",
+                "guzzle6",
+                "handler",
+                "http",
+                "http 1.1",
+                "middleware",
+                "performance",
+                "php",
+                "promise",
+                "psr6",
+                "psr7",
+                "rfc7234",
+                "validation"
+            ],
+            "support": {
+                "issues": "https://github.com/Kevinrob/guzzle-cache-middleware/issues",
+                "source": "https://github.com/Kevinrob/guzzle-cache-middleware/tree/v4.0.1"
+            },
+            "time": "2022-03-15T21:47:10+00:00"
+        },
+        {
+            "name": "league/uri",
+            "version": "6.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri.git",
+                "reference": "c68ca445abb04817d740ddd6d0b3551826ef0c5a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri/zipball/c68ca445abb04817d740ddd6d0b3551826ef0c5a",
+                "reference": "c68ca445abb04817d740ddd6d0b3551826ef0c5a",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "league/uri-interfaces": "^2.3",
+                "php": "^7.3 || ^8.0",
+                "psr/http-message": "^1.0"
+            },
+            "conflict": {
+                "league/uri-schemes": "^1.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^2.19 || ^3.0",
+                "phpstan/phpstan": "^0.12.90",
+                "phpstan/phpstan-phpunit": "^0.12.22",
+                "phpstan/phpstan-strict-rules": "^0.12.11",
+                "phpunit/phpunit": "^8.0 || ^9.0",
+                "psr/http-factory": "^1.0"
+            },
+            "suggest": {
+                "ext-fileinfo": "Needed to create Data URI from a filepath",
+                "ext-intl": "Needed to improve host validation",
+                "league/uri-components": "Needed to easily manipulate URI objects",
+                "psr/http-factory": "Needed to use the URI factory"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Uri\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ignace Nyamagana Butera",
+                    "email": "nyamsprod@gmail.com",
+                    "homepage": "https://nyamsprod.com"
+                }
+            ],
+            "description": "URI manipulation library",
+            "homepage": "http://uri.thephpleague.com",
+            "keywords": [
+                "data-uri",
+                "file-uri",
+                "ftp",
+                "hostname",
+                "http",
+                "https",
+                "middleware",
+                "parse_str",
+                "parse_url",
+                "psr-7",
+                "query-string",
+                "querystring",
+                "rfc3986",
+                "rfc3987",
+                "rfc6570",
+                "uri",
+                "uri-template",
+                "url",
+                "ws"
+            ],
+            "support": {
+                "docs": "https://uri.thephpleague.com",
+                "forum": "https://thephpleague.slack.com",
+                "issues": "https://github.com/thephpleague/uri/issues",
+                "source": "https://github.com/thephpleague/uri/tree/6.5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-08-27T09:54:07+00:00"
+        },
+        {
+            "name": "league/uri-interfaces",
+            "version": "2.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri-interfaces.git",
+                "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
+                "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^2.19",
+                "phpstan/phpstan": "^0.12.90",
+                "phpstan/phpstan-phpunit": "^0.12.19",
+                "phpstan/phpstan-strict-rules": "^0.12.9",
+                "phpunit/phpunit": "^8.5.15 || ^9.5"
+            },
+            "suggest": {
+                "ext-intl": "to use the IDNA feature",
+                "symfony/intl": "to use the IDNA feature via Symfony Polyfill"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Uri\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ignace Nyamagana Butera",
+                    "email": "nyamsprod@gmail.com",
+                    "homepage": "https://nyamsprod.com"
+                }
+            ],
+            "description": "Common interface for URI representation",
+            "homepage": "http://github.com/thephpleague/uri-interfaces",
+            "keywords": [
+                "rfc3986",
+                "rfc3987",
+                "uri",
+                "url"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/uri-interfaces/issues",
+                "source": "https://github.com/thephpleague/uri-interfaces/tree/2.3.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-06-28T04:27:21+00:00"
+        },
         {
             "name": "nelmio/cors-bundle",
             "version": "2.2.0",
@@ -10040,9 +10284,18 @@
             "time": "2015-12-17T08:42:14+00:00"
         }
     ],
-    "aliases": [],
+    "aliases": [
+        {
+            "package": "dbp/relay-core-bundle",
+            "version": "dev-main",
+            "alias": "0.1.37",
+            "alias_normalized": "0.1.37.0"
+        }
+    ],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "dbp/relay-core-bundle": 20
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
@@ -10053,5 +10306,5 @@
     "platform-overrides": {
         "php": "7.3"
     },
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.2.0"
 }
diff --git a/src/API/CourseProviderInterface.php b/src/API/CourseProviderInterface.php
index da917ad..22c6a5c 100644
--- a/src/API/CourseProviderInterface.php
+++ b/src/API/CourseProviderInterface.php
@@ -20,16 +20,6 @@ interface CourseProviderInterface
      */
     public function getCourses(array $options = []): Paginator;
 
-    /**
-     * @throws ApiError
-     */
-    public function getCoursesByOrganization(string $orgUnitId, array $options = []): Paginator;
-
-    /**
-     * @throws ApiError
-     */
-    public function getCoursesByLecturer(string $lecturerId, array $options = []): Paginator;
-
     /**
      * @throws ApiError
      */
diff --git a/src/Controller/GetAttendeesByCourse.php b/src/Controller/GetAttendeesByCourse.php
index 78596d9..6e1f02b 100644
--- a/src/Controller/GetAttendeesByCourse.php
+++ b/src/Controller/GetAttendeesByCourse.php
@@ -27,7 +27,7 @@ class GetAttendeesByCourse extends AbstractController
         $options = [];
         $options['lang'] = $request->query->get('lang', 'de');
 
-        Pagination::addPaginationOptions($options, $request->query->all());
+        Pagination::addOptions($options, $request->query->all());
 
         return $this->coursesProvider->getAttendeesByCourse($identifier, $options);
     }
diff --git a/src/DataProvider/CourseCollectionDataProvider.php b/src/DataProvider/CourseCollectionDataProvider.php
index 53ea098..ee26089 100644
--- a/src/DataProvider/CourseCollectionDataProvider.php
+++ b/src/DataProvider/CourseCollectionDataProvider.php
@@ -39,57 +39,9 @@ final class CourseCollectionDataProvider extends AbstractController implements C
             $options['search'] = $search;
         }
 
-        if ($term = ($filters['term'] ?? null)) {
-            $options['term'] = $term;
-        }
-
-        if ($includeParameter = LocalData::getIncludeParameter($filters)) {
-            $options[LocalData::INCLUDE_PARAMETER_NAME] = $includeParameter;
-        }
-
-        $organizationId = $filters['organization'] ?? '';
-        $lecturerId = $filters['lecturer'] ?? '';
-
-        $filterByOrganizationId = $organizationId !== '';
-        $filterByLecturerId = $lecturerId !== '';
-
-        if (!($filterByOrganizationId && $filterByLecturerId)) {
-            Pagination::addPaginationOptions($options, $filters);
-        } // else (both filters provided) -> request paginators holding the whole set of results since we need to intersect them
-
-        $coursePaginator = null;
-        if ($filterByOrganizationId || $filterByLecturerId) {
-            if ($filterByOrganizationId) {
-                $coursePaginator = $this->courseProvider->getCoursesByOrganization($organizationId, $options);
-            }
-            if ($filterByLecturerId) {
-                $coursesByPersonPaginator = $this->courseProvider->getCoursesByLecturer($lecturerId, $options);
+        LocalData::addOptions($options, $filters);
+        Pagination::addOptions($options, $filters);
 
-                if (!$filterByOrganizationId) {
-                    $coursePaginator = $coursesByPersonPaginator;
-                } else {
-                    $intersection = array_uintersect($coursePaginator->getItems(), $coursesByPersonPaginator->getItems(),
-                        'Dbp\Relay\BaseCourseBundle\DataProvider\CourseCollectionDataProvider::compareCourses');
-                    $courses = array_values($intersection);
-                    Pagination::addPaginationOptions($options, $filters);
-                    $coursePaginator = Pagination::createWholeResultPaginator($courses, $options);
-                }
-            }
-        } else {
-            $coursePaginator = $this->courseProvider->getCourses($options);
-        }
-
-        return $coursePaginator ?? [];
-    }
-
-    public static function compareCourses(Course $a, Course $b): int
-    {
-        if ($a->getIdentifier() > $b->getIdentifier()) {
-            return 1;
-        } elseif ($a->getIdentifier() === $b->getIdentifier()) {
-            return 0;
-        } else {
-            return -1;
-        }
+        return $this->courseProvider->getCourses($options);
     }
 }
diff --git a/src/Entity/Course.php b/src/Entity/Course.php
index adfdc4a..5b9f7b3 100644
--- a/src/Entity/Course.php
+++ b/src/Entity/Course.php
@@ -20,9 +20,7 @@ use Dbp\Relay\CoreBundle\LocalData\LocalDataAwareTrait;
  *                 "parameters" = {
  *                     {"name" = "search", "in" = "query", "description" = "Search for a course", "type" = "string", "required" = false},
  *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
- *                     {"name" = "term", "in" = "query", "description" = "Teaching term", "type" = "string", "enum" = {"W", "S"}, "example" = "W"},
- *                     {"name" = "organization", "in" = "query", "description" = "Get courses of an organization (ID of BaseOrganization resource)", "required" = false, "type" = "string", "example" = "1190"},
- *                     {"name" = "lecturer", "in" = "query", "description" = "Get courses of a lecturer (ID of BasePerson resource)", "required" = false, "type" = "string", "example" = "woody007"},
+ *                     {"name" = "queryLocal", "in" = "query", "description" = "Local query parameters to apply", "type" = "string"},
  *                     {"name" = "includeLocal", "in" = "query", "description" = "Local data attributes to include", "type" = "string", "example" = "BaseCourse.code,BaseCourse.numberOfCredits"},
  *                     {"name" = "partialPagination", "in" = "query", "description" = "Enable partial pagination", "type" = "bool", "example" = "false"}
  *                 }
-- 
GitLab