aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2021-08-20 06:11:05 +0000
committerMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2021-08-20 06:11:05 +0000
commit9b6bd7e747bd5ed44d169a8e1baee0e519d209d6 (patch)
tree104c177e3c0d40d7471d7c081d61dec15cb1bab9
parent8edcc69d26d73736b1bab92df28a00cd97ab8cf3 (diff)
Update der JSONAPI-Bibliotheken, fixes #80
-rw-r--r--composer.json12
-rw-r--r--composer.lock1081
-rw-r--r--lib/classes/JsonApi/AppFactory.php54
-rw-r--r--lib/classes/JsonApi/Contracts/JsonApiPlugin.php4
-rw-r--r--lib/classes/JsonApi/Errors/AuthorizationFailedException.php4
-rw-r--r--lib/classes/JsonApi/Errors/BadRequestException.php4
-rw-r--r--lib/classes/JsonApi/Errors/ConflictException.php6
-rw-r--r--lib/classes/JsonApi/Errors/ErrorHandler.php140
-rw-r--r--lib/classes/JsonApi/Errors/HttpRangeException.php6
-rw-r--r--lib/classes/JsonApi/Errors/InternalServerError.php4
-rw-r--r--lib/classes/JsonApi/Errors/JsonApiExceptionHandler.php97
-rw-r--r--lib/classes/JsonApi/Errors/NotAcceptableException.php15
-rw-r--r--lib/classes/JsonApi/Errors/NotImplementedException.php4
-rw-r--r--lib/classes/JsonApi/Errors/RecordNotFoundException.php6
-rw-r--r--lib/classes/JsonApi/Errors/UnprocessableEntityException.php4
-rw-r--r--lib/classes/JsonApi/Errors/UnsupportedMediaTypeException.php15
-rw-r--r--lib/classes/JsonApi/Errors/UnsupportedRequestError.php4
-rw-r--r--lib/classes/JsonApi/JsonApiController.php437
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/Container.php98
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/EncoderParser.php49
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/Factory.php42
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/JsonApiTrait.php428
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/Paginator.php24
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/Parser.php75
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/QueryChecker.php186
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/QueryParser.php76
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/QueryParserInterface.php25
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/Responses.php133
-rw-r--r--lib/classes/JsonApi/JsonApiIntegration/SchemaContainer.php104
-rw-r--r--lib/classes/JsonApi/Middlewares/Auth/HttpBasicAuthStrategy.php13
-rw-r--r--lib/classes/JsonApi/Middlewares/Auth/OAuth1Strategy.php17
-rw-r--r--lib/classes/JsonApi/Middlewares/Auth/SessionStrategy.php4
-rw-r--r--lib/classes/JsonApi/Middlewares/Auth/Strategy.php6
-rw-r--r--lib/classes/JsonApi/Middlewares/Authentication.php44
-rw-r--r--lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php19
-rw-r--r--lib/classes/JsonApi/Middlewares/JsonApi.php80
-rw-r--r--lib/classes/JsonApi/Middlewares/RemoveTrailingSlashes.php35
-rw-r--r--lib/classes/JsonApi/Middlewares/StudipMockNavigation.php13
-rw-r--r--lib/classes/JsonApi/Models/Studip.php7
-rw-r--r--lib/classes/JsonApi/NonJsonApiController.php34
-rw-r--r--lib/classes/JsonApi/Providers/JsonApiConfig.php31
-rw-r--r--lib/classes/JsonApi/Providers/JsonApiServices.php169
-rw-r--r--lib/classes/JsonApi/Providers/StudipConfig.php36
-rw-r--r--lib/classes/JsonApi/Providers/StudipServices.php41
-rw-r--r--lib/classes/JsonApi/RouteMap.php511
-rw-r--r--lib/classes/JsonApi/Routes/ActivityStreamShow.php38
-rw-r--r--lib/classes/JsonApi/Routes/ArrayHelperTrait.php2
-rw-r--r--lib/classes/JsonApi/Routes/Blubber/FilterTrait.php4
-rw-r--r--lib/classes/JsonApi/Routes/Blubber/ThreadsIndex.php9
-rw-r--r--lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php2
-rw-r--r--lib/classes/JsonApi/Routes/DiscoveryIndex.php4
-rw-r--r--lib/classes/JsonApi/Routes/Events/UserEventsIcal.php4
-rw-r--r--lib/classes/JsonApi/Routes/Files/FileRefsContentHead.php3
-rw-r--r--lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php2
-rw-r--r--lib/classes/JsonApi/Routes/Files/FoldersCopy.php3
-rw-r--r--lib/classes/JsonApi/Routes/Files/NegotiateFileRefsCreate.php11
-rw-r--r--lib/classes/JsonApi/Routes/Files/RoutesHelperTrait.php9
-rw-r--r--lib/classes/JsonApi/Routes/News/Rel/Ranges.php9
-rw-r--r--lib/classes/JsonApi/Routes/RelationshipsController.php2
-rw-r--r--lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php46
-rw-r--r--lib/classes/JsonApi/Routes/Studip/PropertiesIndex.php2
-rw-r--r--lib/classes/JsonApi/Routes/Users/UsersIndex.php10
-rw-r--r--lib/classes/JsonApi/Routes/Users/UsersShow.php21
-rw-r--r--lib/classes/JsonApi/Routes/Wiki/WikiShow.php3
-rw-r--r--lib/classes/JsonApi/SchemaMap.php89
-rw-r--r--lib/classes/JsonApi/Schemas/Activity.php35
-rw-r--r--lib/classes/JsonApi/Schemas/BlubberComment.php33
-rw-r--r--lib/classes/JsonApi/Schemas/BlubberStatusgruppeThread.php12
-rw-r--r--lib/classes/JsonApi/Schemas/BlubberThread.php49
-rw-r--r--lib/classes/JsonApi/Schemas/CalendarEvent.php18
-rw-r--r--lib/classes/JsonApi/Schemas/ConfigValue.php13
-rw-r--r--lib/classes/JsonApi/Schemas/ConsultationBlock.php38
-rw-r--r--lib/classes/JsonApi/Schemas/ConsultationBooking.php22
-rw-r--r--lib/classes/JsonApi/Schemas/ConsultationSlot.php24
-rw-r--r--lib/classes/JsonApi/Schemas/ContentTermsOfUse.php13
-rw-r--r--lib/classes/JsonApi/Schemas/Course.php65
-rw-r--r--lib/classes/JsonApi/Schemas/CourseEvent.php18
-rw-r--r--lib/classes/JsonApi/Schemas/CourseMember.php33
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/Block.php70
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/BlockComment.php30
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/BlockFeedback.php30
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/Container.php62
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/Instance.php32
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/StructuralElement.php94
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/UserDataField.php30
-rwxr-xr-xlib/classes/JsonApi/Schemas/Courseware/UserProgress.php30
-rw-r--r--lib/classes/JsonApi/Schemas/FeedbackElement.php78
-rw-r--r--lib/classes/JsonApi/Schemas/FeedbackEntry.php35
-rw-r--r--lib/classes/JsonApi/Schemas/File.php35
-rw-r--r--lib/classes/JsonApi/Schemas/FileRef.php68
-rw-r--r--lib/classes/JsonApi/Schemas/Folder.php47
-rw-r--r--lib/classes/JsonApi/Schemas/ForumCategory.php26
-rw-r--r--lib/classes/JsonApi/Schemas/ForumEntry.php24
-rw-r--r--lib/classes/JsonApi/Schemas/Institute.php24
-rw-r--r--lib/classes/JsonApi/Schemas/InstituteMember.php26
-rw-r--r--lib/classes/JsonApi/Schemas/LibraryFile.php78
-rw-r--r--lib/classes/JsonApi/Schemas/Message.php39
-rw-r--r--lib/classes/JsonApi/Schemas/ScheduleEntry.php20
-rw-r--r--lib/classes/JsonApi/Schemas/SchemaProvider.php60
-rw-r--r--lib/classes/JsonApi/Schemas/SemClass.php20
-rw-r--r--lib/classes/JsonApi/Schemas/SemType.php22
-rw-r--r--lib/classes/JsonApi/Schemas/Semester.php13
-rw-r--r--lib/classes/JsonApi/Schemas/SeminarCycleDate.php18
-rw-r--r--lib/classes/JsonApi/Schemas/SlimRoute.php16
-rw-r--r--lib/classes/JsonApi/Schemas/StatusGroup.php22
-rw-r--r--lib/classes/JsonApi/Schemas/Studip.php13
-rw-r--r--lib/classes/JsonApi/Schemas/StudipComment.php45
-rw-r--r--lib/classes/JsonApi/Schemas/StudipNews.php34
-rw-r--r--lib/classes/JsonApi/Schemas/StudipProperty.php15
-rw-r--r--lib/classes/JsonApi/Schemas/StudyArea.php30
-rw-r--r--lib/classes/JsonApi/Schemas/User.php234
-rw-r--r--lib/classes/JsonApi/Schemas/WikiPage.php107
-rw-r--r--lib/classes/JsonApi/dependencies.php62
-rw-r--r--lib/classes/JsonApi/middleware.php50
-rw-r--r--lib/classes/JsonApi/routes.php8
-rw-r--r--lib/classes/JsonApi/settings.php55
-rw-r--r--public/jsonapi.php62
-rw-r--r--tests/_support/Helper/Jsonapi.php192
-rw-r--r--tests/_support/Helper/StudipPDO.php649
-rw-r--r--tests/_support/_generated/JsonapiTesterActions.php19
-rw-r--r--tests/jsonapi/BlubberCommentsUpdateTest.php10
-rw-r--r--tests/jsonapi/BlubberThreadsCreateTest.php12
-rw-r--r--tests/jsonapi/BlubberThreadsIndexTest.php17
-rw-r--r--tests/jsonapi/FileRefsCreateTest.php130
-rw-r--r--tests/jsonapi/FileRefsDeleteTest.php5
-rw-r--r--tests/jsonapi/FileRefsShowTest.php5
-rw-r--r--tests/jsonapi/ForumCategoriesCreateTest.php29
-rw-r--r--tests/jsonapi/ForumCategoriesIndexTest.php27
-rw-r--r--tests/jsonapi/ForumCategoriesShowTest.php24
-rw-r--r--tests/jsonapi/ForumCategoriesUpdateTest.php28
-rw-r--r--tests/jsonapi/ForumCategoryDeleteTest.php26
-rw-r--r--tests/jsonapi/ForumEntriesCreateTest.php75
-rw-r--r--tests/jsonapi/ForumEntriesDeleteTest.php24
-rw-r--r--tests/jsonapi/ForumEntriesShowTest.php91
-rw-r--r--tests/jsonapi/ForumEntriesUpdateTest.php29
-rw-r--r--tests/jsonapi/MessagesShowTest.php7
-rw-r--r--tests/jsonapi/NewsCreateTest.php130
-rw-r--r--tests/jsonapi/NewsShowTest.php19
-rw-r--r--tests/jsonapi/UserEventsIcalTest.php2
-rw-r--r--tests/jsonapi/UserScheduleShowTest.php1
-rw-r--r--tests/jsonapi/_bootstrap.php1
141 files changed, 4145 insertions, 4014 deletions
diff --git a/composer.json b/composer.json
index dfe31c1..50b3f8a 100644
--- a/composer.json
+++ b/composer.json
@@ -9,17 +9,16 @@
"camspiers/json-pretty": "~1.0.2",
"monolog/monolog": "~1.21.0",
"php-http/curl-client": "~1.7.0",
- "woohoolabs/yang": "~0.9.0",
+ "woohoolabs/yang": "2.3.2",
"codeception/codeception": "~4.1.21",
"codeception/module-asserts": "^1.3"
},
"require": {
"php": "^7.2",
"guzzlehttp/psr7": "~1.4.2",
- "neomerx/json-api": "~1.0.9",
- "slim/slim": "~3.12.3",
+ "neomerx/json-api": "4.0.1",
"spomky-labs/otphp": "^8.3.3",
- "tuupola/cors-middleware": "~0.5.2",
+ "tuupola/cors-middleware": "1.2.1",
"tecnickcom/tcpdf": "^6.3",
"scssphp/scssphp": "^1.4",
"symfony/yaml": "^3.4",
@@ -43,6 +42,9 @@
"ext-pcre": "*",
"ext-pdo": "*",
"ext-mbstring": "*",
- "opis/json-schema": "^1.0"
+ "opis/json-schema": "^1.0",
+ "slim/psr7": "1.4",
+ "slim/slim": "4.7.1",
+ "php-di/php-di": "6.3.4"
}
}
diff --git a/composer.lock b/composer.lock
index 0532937..440bb70 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": "dc13abed7b7557def19c639c0b91cb4f",
+ "content-hash": "98af1effd6c2da72cc51ac552e851451",
"packages": [
{
"name": "algo26-matthias/idna-convert",
@@ -275,6 +275,62 @@
"time": "2020-06-29T00:56:53+00:00"
},
{
+ "name": "fig/http-message-util",
+ "version": "1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message-util.git",
+ "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765",
+ "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3 || ^7.0 || ^8.0"
+ },
+ "suggest": {
+ "psr/http-message": "The package containing the PSR-7 interfaces"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Fig\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Utility classes and constants for use with PSR-7 (psr/http-message)",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/http-message-util/issues",
+ "source": "https://github.com/php-fig/http-message-util/tree/1.1.5"
+ },
+ "time": "2020-11-24T22:02:12+00:00"
+ },
+ {
"name": "gossi/docblock",
"version": "v1.6",
"source": {
@@ -657,36 +713,37 @@
},
{
"name": "neomerx/json-api",
- "version": "v1.0.9",
+ "version": "v4.0.1",
"source": {
"type": "git",
"url": "https://github.com/neomerx/json-api.git",
- "reference": "c911b7494496e79f9de72ee40d6a2b791caaf95b"
+ "reference": "0e45254a4574a3118e0ed663312b43aca23b89c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/neomerx/json-api/zipball/c911b7494496e79f9de72ee40d6a2b791caaf95b",
- "reference": "c911b7494496e79f9de72ee40d6a2b791caaf95b",
+ "url": "https://api.github.com/repos/neomerx/json-api/zipball/0e45254a4574a3118e0ed663312b43aca23b89c7",
+ "reference": "0e45254a4574a3118e0ed663312b43aca23b89c7",
"shasum": ""
},
"require": {
- "php": ">=5.5.0",
- "psr/http-message": "^1.0",
- "psr/log": "^1.0"
+ "php": ">=7.1.0"
},
"require-dev": {
- "mockery/mockery": "~0.9.4",
- "monolog/monolog": "^1.18",
+ "friendsofphp/php-cs-fixer": "^2.14",
+ "mockery/mockery": "^1.0",
"phpmd/phpmd": "^2.6",
- "phpunit/phpunit": "^4.6 || ^5.0 || ^6.0",
- "scrutinizer/ocular": "^1.3",
- "squizlabs/php_codesniffer": "^2.5"
+ "phpunit/phpunit": "^7.0",
+ "scrutinizer/ocular": "^1.4",
+ "squizlabs/php_codesniffer": "^2.9"
},
"type": "library",
"autoload": {
"psr-4": {
"Neomerx\\JsonApi\\": "src/"
- }
+ },
+ "files": [
+ "src/I18n/format.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -710,9 +767,9 @@
],
"support": {
"issues": "https://github.com/neomerx/json-api/issues",
- "source": "https://github.com/neomerx/json-api/tree/v1.x"
+ "source": "https://github.com/neomerx/json-api/tree/develop"
},
- "time": "2018-02-21T13:45:30+00:00"
+ "time": "2020-03-03T05:56:54+00:00"
},
{
"name": "nikic/fast-route",
@@ -765,6 +822,71 @@
"time": "2018-02-13T20:26:39+00:00"
},
{
+ "name": "opis/closure",
+ "version": "3.6.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/opis/closure.git",
+ "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/opis/closure/zipball/06e2ebd25f2869e54a306dda991f7db58066f7f6",
+ "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.4 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "jeremeamia/superclosure": "^2.0",
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.6.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Opis\\Closure\\": "src/"
+ },
+ "files": [
+ "functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marius Sarca",
+ "email": "marius.sarca@gmail.com"
+ },
+ {
+ "name": "Sorin Sarca",
+ "email": "sarca_sorin@hotmail.com"
+ }
+ ],
+ "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
+ "homepage": "https://opis.io/closure",
+ "keywords": [
+ "anonymous functions",
+ "closure",
+ "function",
+ "serializable",
+ "serialization",
+ "serialize"
+ ],
+ "support": {
+ "issues": "https://github.com/opis/closure/issues",
+ "source": "https://github.com/opis/closure/tree/3.6.2"
+ },
+ "time": "2021-04-09T13:42:10+00:00"
+ },
+ {
"name": "opis/json-schema",
"version": "1.1.0",
"source": {
@@ -1054,6 +1176,171 @@
"time": "2018-08-04T14:22:05+00:00"
},
{
+ "name": "php-di/invoker",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-DI/Invoker.git",
+ "reference": "540c27c86f663e20fe39a24cd72fa76cdb21d41a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/540c27c86f663e20fe39a24cd72fa76cdb21d41a",
+ "reference": "540c27c86f663e20fe39a24cd72fa76cdb21d41a",
+ "shasum": ""
+ },
+ "require": {
+ "psr/container": "~1.0"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "phpunit/phpunit": "~4.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Invoker\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Generic and extensible callable invoker",
+ "homepage": "https://github.com/PHP-DI/Invoker",
+ "keywords": [
+ "callable",
+ "dependency",
+ "dependency-injection",
+ "injection",
+ "invoke",
+ "invoker"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-DI/Invoker/issues",
+ "source": "https://github.com/PHP-DI/Invoker/tree/master"
+ },
+ "time": "2017-03-20T19:28:22+00:00"
+ },
+ {
+ "name": "php-di/php-di",
+ "version": "6.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-DI/PHP-DI.git",
+ "reference": "f53bcba06ab31b18e911b77c039377f4ccd1f7a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/f53bcba06ab31b18e911b77c039377f4ccd1f7a5",
+ "reference": "f53bcba06ab31b18e911b77c039377f4ccd1f7a5",
+ "shasum": ""
+ },
+ "require": {
+ "opis/closure": "^3.5.5",
+ "php": ">=7.2.0",
+ "php-di/invoker": "^2.0",
+ "php-di/phpdoc-reader": "^2.0.1",
+ "psr/container": "^1.0"
+ },
+ "provide": {
+ "psr/container-implementation": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.2",
+ "friendsofphp/php-cs-fixer": "^2.4",
+ "mnapoli/phpunit-easymock": "^1.2",
+ "ocramius/proxy-manager": "^2.0.2",
+ "phpstan/phpstan": "^0.12",
+ "phpunit/phpunit": "^8.5|^9.0"
+ },
+ "suggest": {
+ "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)",
+ "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~2.0)"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DI\\": "src/"
+ },
+ "files": [
+ "src/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "The dependency injection container for humans",
+ "homepage": "https://php-di.org/",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interop",
+ "dependency injection",
+ "di",
+ "ioc",
+ "psr11"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-DI/PHP-DI/issues",
+ "source": "https://github.com/PHP-DI/PHP-DI/tree/6.3.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/mnapoli",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/php-di/php-di",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-06-10T08:04:48+00:00"
+ },
+ {
+ "name": "php-di/phpdoc-reader",
+ "version": "2.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-DI/PhpDocReader.git",
+ "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/66daff34cbd2627740ffec9469ffbac9f8c8185c",
+ "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "require-dev": {
+ "mnapoli/hard-mode": "~0.3.0",
+ "phpunit/phpunit": "^8.5|^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpDocReader\\": "src/PhpDocReader"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)",
+ "keywords": [
+ "phpdoc",
+ "reflection"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-DI/PhpDocReader/issues",
+ "source": "https://github.com/PHP-DI/PhpDocReader/tree/2.2.1"
+ },
+ "time": "2020-10-12T12:39:22+00:00"
+ },
+ {
"name": "phpseclib/phpseclib",
"version": "2.0.31",
"source": {
@@ -1268,35 +1555,31 @@
"time": "2020-03-04T10:26:33+00:00"
},
{
- "name": "pimple/pimple",
- "version": "v3.2.3",
+ "name": "psr/container",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/silexphp/Pimple.git",
- "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
- "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
- "php": ">=5.3.0",
- "psr/container": "^1.0"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "^3.2"
+ "php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.2.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Pimple": "src/"
+ "psr-4": {
+ "Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1305,38 +1588,42 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
}
],
- "description": "Pimple, a simple Dependency Injection Container",
- "homepage": "http://pimple.sensiolabs.org",
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
"keywords": [
+ "PSR-11",
"container",
- "dependency injection"
+ "container-interface",
+ "container-interop",
+ "psr"
],
"support": {
- "issues": "https://github.com/silexphp/Pimple/issues",
- "source": "https://github.com/silexphp/Pimple/tree/master"
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/master"
},
- "time": "2018-01-21T07:42:36+00:00"
+ "time": "2017-02-14T16:28:37+00:00"
},
{
- "name": "psr/container",
- "version": "1.0.0",
+ "name": "psr/http-factory",
+ "version": "1.0.1",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0"
},
"type": "library",
"extra": {
@@ -1346,7 +1633,7 @@
},
"autoload": {
"psr-4": {
- "Psr\\Container\\": "src/"
+ "Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1359,20 +1646,21 @@
"homepage": "http://www.php-fig.org/"
}
],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
+ "description": "Common interfaces for PSR-7 HTTP message factories",
"keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
],
"support": {
- "issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/master"
+ "source": "https://github.com/php-fig/http-factory/tree/master"
},
- "time": "2017-02-14T16:28:37+00:00"
+ "time": "2019-04-30T12:38:16+00:00"
},
{
"name": "psr/http-message",
@@ -1428,6 +1716,120 @@
"time": "2016-08-06T14:39:51+00:00"
},
{
+ "name": "psr/http-server-handler",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-server-handler.git",
+ "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+ "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Server\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP server-side request handler",
+ "keywords": [
+ "handler",
+ "http",
+ "http-interop",
+ "psr",
+ "psr-15",
+ "psr-7",
+ "request",
+ "response",
+ "server"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/http-server-handler/issues",
+ "source": "https://github.com/php-fig/http-server-handler/tree/master"
+ },
+ "time": "2018-10-30T16:46:14+00:00"
+ },
+ {
+ "name": "psr/http-server-middleware",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-server-middleware.git",
+ "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+ "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0",
+ "psr/http-message": "^1.0",
+ "psr/http-server-handler": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Server\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP server-side middleware",
+ "keywords": [
+ "http",
+ "http-interop",
+ "middleware",
+ "psr",
+ "psr-15",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/http-server-middleware/issues",
+ "source": "https://github.com/php-fig/http-server-middleware/tree/master"
+ },
+ "time": "2018-10-30T17:12:04+00:00"
+ },
+ {
"name": "psr/log",
"version": "1.1.3",
"source": {
@@ -1478,6 +1880,50 @@
"time": "2020-03-23T09:12:05+00:00"
},
{
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
"name": "scssphp/scssphp",
"version": "v1.4.0",
"source": {
@@ -1545,35 +1991,132 @@
"time": "2020-11-07T20:53:41+00:00"
},
{
+ "name": "slim/psr7",
+ "version": "1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/slimphp/Slim-Psr7.git",
+ "reference": "0dca983ca32a26f4a91fb11173b7b9eaee29e9d6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/0dca983ca32a26f4a91fb11173b7b9eaee29e9d6",
+ "reference": "0dca983ca32a26f4a91fb11173b7b9eaee29e9d6",
+ "shasum": ""
+ },
+ "require": {
+ "fig/http-message-util": "^1.1.5",
+ "php": "^7.2 || ^8.0",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.0",
+ "ralouphie/getallheaders": "^3",
+ "symfony/polyfill-php80": "^1.22"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "1.0",
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "adriansuter/php-autoload-override": "^1.2",
+ "ext-json": "*",
+ "http-interop/http-factory-tests": "^0.9.0",
+ "php-http/psr7-integration-tests": "dev-master",
+ "phpstan/phpstan": "^0.12",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "squizlabs/php_codesniffer": "^3.6",
+ "weirdan/prophecy-shim": "^1.0 || ^2.0.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Slim\\Psr7\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Josh Lockhart",
+ "email": "hello@joshlockhart.com",
+ "homepage": "http://joshlockhart.com"
+ },
+ {
+ "name": "Andrew Smith",
+ "email": "a.smith@silentworks.co.uk",
+ "homepage": "http://silentworks.co.uk"
+ },
+ {
+ "name": "Rob Allen",
+ "email": "rob@akrabat.com",
+ "homepage": "http://akrabat.com"
+ },
+ {
+ "name": "Pierre Berube",
+ "email": "pierre@lgse.com",
+ "homepage": "http://www.lgse.com"
+ }
+ ],
+ "description": "Strict PSR-7 implementation",
+ "homepage": "https://www.slimframework.com",
+ "keywords": [
+ "http",
+ "psr-7",
+ "psr7"
+ ],
+ "support": {
+ "issues": "https://github.com/slimphp/Slim-Psr7/issues",
+ "source": "https://github.com/slimphp/Slim-Psr7/tree/1.4"
+ },
+ "time": "2021-05-08T18:22:56+00:00"
+ },
+ {
"name": "slim/slim",
- "version": "3.12.3",
+ "version": "4.7.1",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
- "reference": "1c9318a84ffb890900901136d620b4f03a59da38"
+ "reference": "0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slimphp/Slim/zipball/1c9318a84ffb890900901136d620b4f03a59da38",
- "reference": "1c9318a84ffb890900901136d620b4f03a59da38",
+ "url": "https://api.github.com/repos/slimphp/Slim/zipball/0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f",
+ "reference": "0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f",
"shasum": ""
},
"require": {
"ext-json": "*",
- "ext-libxml": "*",
- "ext-simplexml": "*",
- "nikic/fast-route": "^1.0",
- "php": ">=5.5.0",
- "pimple/pimple": "^3.0",
+ "nikic/fast-route": "^1.3",
+ "php": "^7.2 || ^8.0",
"psr/container": "^1.0",
- "psr/http-message": "^1.0"
- },
- "provide": {
- "psr/http-message-implementation": "1.0"
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.0",
+ "psr/http-server-handler": "^1.0",
+ "psr/http-server-middleware": "^1.0",
+ "psr/log": "^1.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.0",
- "squizlabs/php_codesniffer": "^2.5"
+ "adriansuter/php-autoload-override": "^1.2",
+ "ext-simplexml": "*",
+ "guzzlehttp/psr7": "^1.7",
+ "http-interop/http-factory-guzzle": "^1.0",
+ "laminas/laminas-diactoros": "^2.4",
+ "nyholm/psr7": "^1.3",
+ "nyholm/psr7-server": "^1.0.1",
+ "phpspec/prophecy": "^1.12",
+ "phpstan/phpstan": "^0.12.58",
+ "phpunit/phpunit": "^8.5.13",
+ "slim/http": "^1.2",
+ "slim/psr7": "^1.3",
+ "squizlabs/php_codesniffer": "^3.5",
+ "weirdan/prophecy-shim": "^1.0 || ^2.0.2"
+ },
+ "suggest": {
+ "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
+ "ext-xml": "Needed to support XML format in BodyParsingMiddleware",
+ "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim",
+ "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information."
},
"type": "library",
"autoload": {
@@ -1602,13 +2145,18 @@
"homepage": "http://akrabat.com"
},
{
+ "name": "Pierre Berube",
+ "email": "pierre@lgse.com",
+ "homepage": "http://www.lgse.com"
+ },
+ {
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
- "homepage": "https://slimframework.com",
+ "homepage": "https://www.slimframework.com",
"keywords": [
"api",
"framework",
@@ -1616,10 +2164,26 @@
"router"
],
"support": {
+ "docs": "https://www.slimframework.com/docs/v4/",
+ "forum": "https://discourse.slimframework.com/",
+ "irc": "irc://irc.freenode.net:6667/slimphp",
"issues": "https://github.com/slimphp/Slim/issues",
- "source": "https://github.com/slimphp/Slim/tree/3.x"
+ "rss": "https://www.slimframework.com/blog/feed.rss",
+ "slack": "https://slimphp.slack.com/",
+ "source": "https://github.com/slimphp/Slim",
+ "wiki": "https://github.com/slimphp/Slim/wiki"
},
- "time": "2019-11-28T17:40:33+00:00"
+ "funding": [
+ {
+ "url": "https://opencollective.com/slimphp",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/slim/slim",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-12-01T19:41:22+00:00"
},
{
"name": "spomky-labs/otphp",
@@ -1908,6 +2472,89 @@
"time": "2020-07-14T12:35:20+00:00"
},
{
+ "name": "symfony/polyfill-php80",
+ "version": "v1.23.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
"name": "symfony/polyfill-util",
"version": "v1.18.1",
"source": {
@@ -2118,27 +2765,96 @@
"time": "2020-02-14T14:20:12+00:00"
},
{
+ "name": "tuupola/callable-handler",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tuupola/callable-handler.git",
+ "reference": "0bc7b88630ca753de9aba8f411046856f5ca6f8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tuupola/callable-handler/zipball/0bc7b88630ca753de9aba8f411046856f5ca6f8c",
+ "reference": "0bc7b88630ca753de9aba8f411046856f5ca6f8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0",
+ "psr/http-server-middleware": "^1.0"
+ },
+ "require-dev": {
+ "overtrue/phplint": "^1.0",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "squizlabs/php_codesniffer": "^3.2",
+ "tuupola/http-factory": "^0.4.0|^1.0",
+ "zendframework/zend-diactoros": "^1.6.0|^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Tuupola\\Middleware\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mika Tuupola",
+ "email": "tuupola@appelsiini.net",
+ "homepage": "https://appelsiini.net/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Compatibility layer for PSR-7 double pass and PSR-15 middlewares.",
+ "homepage": "https://github.com/tuupola/callable-handler",
+ "keywords": [
+ "middleware",
+ "psr-15",
+ "psr-7"
+ ],
+ "support": {
+ "issues": "https://github.com/tuupola/callable-handler/issues",
+ "source": "https://github.com/tuupola/callable-handler/tree/1.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/tuupola",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-09T08:31:54+00:00"
+ },
+ {
"name": "tuupola/cors-middleware",
- "version": "0.5.2",
+ "version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/tuupola/cors-middleware.git",
- "reference": "db69d8e67b99570b16e8cd5f78c423ed1167cb21"
+ "reference": "4f085d11f349e83d18f1eb5802551353b2b093a3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tuupola/cors-middleware/zipball/db69d8e67b99570b16e8cd5f78c423ed1167cb21",
- "reference": "db69d8e67b99570b16e8cd5f78c423ed1167cb21",
+ "url": "https://api.github.com/repos/tuupola/cors-middleware/zipball/4f085d11f349e83d18f1eb5802551353b2b093a3",
+ "reference": "4f085d11f349e83d18f1eb5802551353b2b093a3",
"shasum": ""
},
"require": {
- "neomerx/cors-psr7": "^1.0",
- "php": "^5.5 || ^7.0"
+ "neomerx/cors-psr7": "^1.0.4",
+ "php": "^7.1|^8.0",
+ "psr/http-message": "^1.0.1",
+ "psr/http-server-middleware": "^1.0",
+ "tuupola/callable-handler": "^1.0",
+ "tuupola/http-factory": "^1.0.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.8",
- "squizlabs/php_codesniffer": "^2.5",
- "zendframework/zend-diactoros": "^1.3"
+ "equip/dispatch": "^2.0",
+ "overtrue/phplint": "^1.0",
+ "phpstan/phpstan": "^0.12.42",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "squizlabs/php_codesniffer": "^3.5",
+ "zendframework/zend-diactoros": "^1.0|^2.0"
},
"type": "library",
"autoload": {
@@ -2154,22 +2870,96 @@
{
"name": "Mika Tuupola",
"email": "tuupola@appelsiini.net",
- "homepage": "http://www.appelsiini.net/",
+ "homepage": "https://appelsiini.net/",
"role": "Developer"
}
],
- "description": "PSR-7 CORS Middleware",
+ "description": "PSR-7 and PSR-15 CORS middleware",
"homepage": "https://github.com/tuupola/cors-middleware",
"keywords": [
"cors",
"middleware",
- "slim"
+ "psr-15",
+ "psr-7"
],
"support": {
"issues": "https://github.com/tuupola/cors-middleware/issues",
- "source": "https://github.com/tuupola/cors-middleware/tree/master"
+ "source": "https://github.com/tuupola/cors-middleware/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/tuupola",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-29T11:01:06+00:00"
+ },
+ {
+ "name": "tuupola/http-factory",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tuupola/http-factory.git",
+ "reference": "aa48841a9f572b9cebe9d3ac5d5d3362a83f57ac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tuupola/http-factory/zipball/aa48841a9f572b9cebe9d3ac5d5d3362a83f57ac",
+ "reference": "aa48841a9f572b9cebe9d3ac5d5d3362a83f57ac",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0",
+ "psr/http-factory": "^1.0"
+ },
+ "conflict": {
+ "nyholm/psr7": "<1.0"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "^1.0"
+ },
+ "require-dev": {
+ "http-interop/http-factory-tests": "^0.7.0",
+ "overtrue/phplint": "^1.0",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "squizlabs/php_codesniffer": "^3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Tuupola\\Http\\Factory\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mika Tuupola",
+ "email": "tuupola@appelsiini.net",
+ "homepage": "https://appelsiini.net/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Lightweight autodiscovering PSR-17 HTTP factories",
+ "homepage": "https://github.com/tuupola/http-factory",
+ "keywords": [
+ "http",
+ "psr-17",
+ "psr-7"
+ ],
+ "support": {
+ "issues": "https://github.com/tuupola/http-factory/issues",
+ "source": "https://github.com/tuupola/http-factory/tree/1.3.0"
},
- "time": "2016-08-12T13:12:58+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/tuupola",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-01T07:46:32+00:00"
}
],
"packages-dev": [
@@ -5481,89 +6271,6 @@
"time": "2021-02-19T12:13:01+00:00"
},
{
- "name": "symfony/polyfill-php80",
- "version": "v1.23.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
- "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
- },
- "files": [
- "bootstrap.php"
- ],
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-02-19T12:13:01+00:00"
- },
- {
"name": "symfony/service-contracts",
"version": "v2.2.0",
"source": {
@@ -5835,27 +6542,33 @@
},
{
"name": "woohoolabs/yang",
- "version": "0.9.0",
+ "version": "2.3.2",
"source": {
"type": "git",
"url": "https://github.com/woohoolabs/yang.git",
- "reference": "00dc9820d48780364cd214537604b032d751a781"
+ "reference": "da65122971fa6add83751497ec76af1fb6cccf77"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/woohoolabs/yang/zipball/00dc9820d48780364cd214537604b032d751a781",
- "reference": "00dc9820d48780364cd214537604b032d751a781",
+ "url": "https://api.github.com/repos/woohoolabs/yang/zipball/da65122971fa6add83751497ec76af1fb6cccf77",
+ "reference": "da65122971fa6add83751497ec76af1fb6cccf77",
"shasum": ""
},
"require": {
- "php": "^5.6.0||^7.0.0",
- "php-http/client-implementation": "^1.0.0",
- "php-http/httplug": "^1.0.0"
+ "php": "^7.2.0||^8.0.0",
+ "php-http/httplug": "^1.0.0|^2.0.0",
+ "psr/http-message-implementation": "^1.0.0"
},
"require-dev": {
- "php-http/guzzle6-adapter": "^1.1.0",
- "phpunit/phpunit": "^5.4.0",
- "squizlabs/php_codesniffer": "^2.3.1"
+ "guzzlehttp/psr7": "^1.4.0",
+ "php-http/guzzle6-adapter": "^2.0.0",
+ "phpstan/phpstan": "^0.12.0",
+ "phpstan/phpstan-phpunit": "^0.12.0",
+ "phpstan/phpstan-strict-rules": "^0.12.0",
+ "phpunit/phpunit": "^7.0.0||^8.2.0||^9.0.0",
+ "squizlabs/php_codesniffer": "^3.5.1",
+ "woohoolabs/coding-standard": "^1.0.0",
+ "woohoolabs/releaser": "^1.1.0"
},
"suggest": {
"php-http/guzzle6-adapter": "Allows to use Guzzle 6 as the HTTP client implementation"
@@ -5877,18 +6590,18 @@
}
],
"description": "Woohoo Labs. Yang",
- "homepage": "http://yang.woohoolabs.com",
"keywords": [
"Woohoo Labs.",
"Yang",
"json api",
+ "psr-18",
"psr-7"
],
"support": {
"issues": "https://github.com/woohoolabs/yang/issues",
"source": "https://github.com/woohoolabs/yang"
},
- "time": "2016-12-21T20:37:46+00:00"
+ "time": "2020-11-15T08:55:55+00:00"
}
],
"aliases": [],
@@ -5910,5 +6623,5 @@
"ext-mbstring": "*"
},
"platform-dev": [],
- "plugin-api-version": "2.1.0"
+ "plugin-api-version": "2.0.0"
}
diff --git a/lib/classes/JsonApi/AppFactory.php b/lib/classes/JsonApi/AppFactory.php
deleted file mode 100644
index ae715aa..0000000
--- a/lib/classes/JsonApi/AppFactory.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace JsonApi;
-
-use Slim\App;
-use StudipPlugin;
-use JsonApi\Middlewares\RemoveTrailingSlashes;
-
-/**
- * Diese Klasse erstellt eine neue Slim-Applikation und konfiguriert
- * diese rudimentär vor.
- *
- * Dabei werden im `Dependency Container` der Slim-Applikation unter
- * dem Schlüssel `plugin` das Stud.IP-Plugin vermerkt und außerdem
- * eingestellt, dass Fehler des Slim-Frameworks detailliert angezeigt
- * werden sollen, wenn sich Stud.IP im Modus `development` befindet.
- *
- * Darüber hinaus wird eine Middleware installiert, die alle Requests umleitet,
- * die mit einem Schrägstrich enden (und zwar jeweils auf das Pendant
- * ohne Schrägstrich).
- *
- * @see http://www.slimframework.com/
- * @see \Studip\ENV
- * @see \JsonApi\Middlewares\RemoveTrailingSlashes
- */
-class AppFactory
-{
- /**
- * Diese Factory-Methode erstellt die Slim-Applikation und
- * konfiguriert diese wie oben angegeben.
- *
- * @return \Slim\App die erstellte Slim-Applikation
- */
- public function makeApp()
- {
- $app = new App();
- $app = $this->configureContainer($app);
- $app->add(new RemoveTrailingSlashes());
-
- return $app;
- }
-
- // hier wird der Container konfiguriert
- private function configureContainer($app)
- {
- $container = $app->getContainer();
- $container['settings']['displayErrorDetails'] = defined('\\Studip\\ENV') && \Studip\ENV === 'development';
-
- $container->register(new Providers\StudipConfig());
- $container->register(new Providers\StudipServices());
-
- return $app;
- }
-}
diff --git a/lib/classes/JsonApi/Contracts/JsonApiPlugin.php b/lib/classes/JsonApi/Contracts/JsonApiPlugin.php
index f7b607a..15f1a65 100644
--- a/lib/classes/JsonApi/Contracts/JsonApiPlugin.php
+++ b/lib/classes/JsonApi/Contracts/JsonApiPlugin.php
@@ -28,6 +28,8 @@ interface JsonApiPlugin
*
* @param \Slim\App $app die Slim-Applikation, in der das Plugin
* Routen eintragen möchte
+ *
+ * @return void
*/
public function registerAuthenticatedRoutes(\Slim\App $app);
@@ -51,6 +53,8 @@ interface JsonApiPlugin
*
* @param \Slim\App $app die Slim-Applikation, in der das Plugin
* Routen eintragen möchte
+ *
+ * @return void
*/
public function registerUnauthenticatedRoutes(\Slim\App $app);
diff --git a/lib/classes/JsonApi/Errors/AuthorizationFailedException.php b/lib/classes/JsonApi/Errors/AuthorizationFailedException.php
index 104a4b5..af3d4fb 100644
--- a/lib/classes/JsonApi/Errors/AuthorizationFailedException.php
+++ b/lib/classes/JsonApi/Errors/AuthorizationFailedException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class AuthorizationFailedException extends JsonApiException
*/
public function __construct()
{
- $error = new Error('Forbidden', null, 403);
+ $error = new Error(null, null, null, '403', null, 'Forbidden');
parent::__construct($error, 403);
}
}
diff --git a/lib/classes/JsonApi/Errors/BadRequestException.php b/lib/classes/JsonApi/Errors/BadRequestException.php
index 577ac22..c09a96a 100644
--- a/lib/classes/JsonApi/Errors/BadRequestException.php
+++ b/lib/classes/JsonApi/Errors/BadRequestException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class BadRequestException extends JsonApiException
*/
public function __construct($detail = null, array $source = null)
{
- $error = new Error('Bad Request', null, 400, null, null, $detail, $source);
+ $error = new Error(null, null, null, 400, null, 'Bad Request', $detail, $source);
parent::__construct($error, 400);
}
}
diff --git a/lib/classes/JsonApi/Errors/ConflictException.php b/lib/classes/JsonApi/Errors/ConflictException.php
index 69b00c5..c5cf0d7 100644
--- a/lib/classes/JsonApi/Errors/ConflictException.php
+++ b/lib/classes/JsonApi/Errors/ConflictException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class ConflictException extends JsonApiException
*/
public function __construct($error = null)
{
- $error = new Error($error ?: 'Conflict', null, 409);
- parent::__construct($error, 409);
+ $errorObject = new Error(null, null, null, 409, null, 'Conflict', $error);
+ parent::__construct($errorObject, 409);
}
}
diff --git a/lib/classes/JsonApi/Errors/ErrorHandler.php b/lib/classes/JsonApi/Errors/ErrorHandler.php
new file mode 100644
index 0000000..93549b5
--- /dev/null
+++ b/lib/classes/JsonApi/Errors/ErrorHandler.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace JsonApi\Errors;
+
+use Neomerx\JsonApi\Exceptions\JsonApiException;
+use Neomerx\JsonApi\Schema\Error;
+use Neomerx\JsonApi\Schema\ErrorCollection;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Log\LoggerInterface;
+use Slim\App;
+use Slim\Exception\HttpException;
+use Throwable;
+
+class ErrorHandler
+{
+ /** @var \Slim\App */
+ private $app;
+
+ public function __construct(App $app)
+ {
+ $this->app = $app;
+ }
+
+ public function __invoke(
+ ServerRequestInterface $request,
+ Throwable $exception,
+ bool $displayErrorDetails,
+ bool $logErrors,
+ bool $logErrorDetails,
+ ?LoggerInterface $logger = null
+ ): ResponseInterface {
+ if ($logger) {
+ $logger->error($exception->getMessage());
+ }
+
+ $response = $this->app->getResponseFactory()->createResponse();
+ $response->getBody()->write($this->determinePayload($exception, $displayErrorDetails));
+
+ $code = $this->determineStatusCode($exception, $request->getMethod());
+
+ return $response->withStatus($code);
+ }
+
+ protected function determineStatusCode(Throwable $exception, string $method): int
+ {
+ if ('OPTIONS' === $method) {
+ return 200;
+ }
+
+ if ($exception instanceof HttpException) {
+ return $exception->getCode();
+ }
+
+ if ($exception instanceof JsonApiException) {
+ return $exception->getHttpCode();
+ }
+
+ return 500;
+ }
+
+ protected function determinePayload(Throwable $exception, bool $displayErrorDetails): string
+ {
+ $message = '';
+ if ($exception instanceof JsonApiException) {
+ $httpCode = $exception->getHttpCode();
+ $errors = new ErrorCollection();
+ foreach ($exception->getErrors() as $error) {
+ $errors[] = $this->copyError($error, $displayErrorDetails, $exception);
+ }
+ } elseif ($exception instanceof HttpException) {
+ $errors = $this->createErrorCollection(
+ $exception->getCode(),
+ $exception->getMessage(),
+ $exception->getDescription(),
+ $exception,
+ $displayErrorDetails
+ );
+ } else {
+ $errors = $this->createErrorCollection(
+ '500',
+ $exception->getMessage(),
+ null,
+ $exception,
+ $displayErrorDetails
+ );
+ }
+
+ if (sizeof($errors)) {
+ $encoder = $this->app->getContainer()->get('json-api-error-encoder');
+
+ return $encoder->encodeErrors($errors);
+ }
+
+ return '';
+ }
+
+ private function createErrorCollection(
+ string $httpCode,
+ string $message,
+ ?string $details,
+ Throwable $exception,
+ bool $displayErrorDetails
+ ): ErrorCollection {
+ /** @var \Exception $exception */
+ $errors = new ErrorCollection();
+ $errors->add(
+ new Error(
+ null,
+ null,
+ null,
+ $httpCode,
+ null,
+ $message,
+ $details,
+ $displayErrorDetails ? ['backtrace' => explode("\n", $exception->getTraceAsString())] : null
+ )
+ );
+
+ return $errors;
+ }
+
+ private function copyError(Error $error, bool $displayErrorDetails, JsonApiException $exception): Error
+ {
+ $newError = new Error(
+ $error->getId(),
+ $error->getLinks(),
+ $error->getTypeLinks(),
+ $error->getStatus(),
+ $error->getCode(),
+ $error->getTitle(),
+ $error->getDetail(),
+ $displayErrorDetails ? ['backtrace' => explode("\n", $exception->getTraceAsString())] : null,
+ false,
+ $error->getMeta()
+ );
+
+ return $newError;
+ }
+}
diff --git a/lib/classes/JsonApi/Errors/HttpRangeException.php b/lib/classes/JsonApi/Errors/HttpRangeException.php
index 950535d..077d14c 100644
--- a/lib/classes/JsonApi/Errors/HttpRangeException.php
+++ b/lib/classes/JsonApi/Errors/HttpRangeException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class HttpRangeException extends JsonApiException
*/
public function __construct($error = null)
{
- $error = new Error($error ?: 'Requested Range Not Satisfiable.', null, 416);
- parent::__construct($error, 416);
+ $errorObject = new Error(null, null, null, 416, null, 'Requested Range Not Satisfiable.', $error);
+ parent::__construct($errorObject, 416);
}
}
diff --git a/lib/classes/JsonApi/Errors/InternalServerError.php b/lib/classes/JsonApi/Errors/InternalServerError.php
index 98bae8f..ccff364 100644
--- a/lib/classes/JsonApi/Errors/InternalServerError.php
+++ b/lib/classes/JsonApi/Errors/InternalServerError.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class InternalServerError extends JsonApiException
*/
public function __construct($detail = null, array $source = null)
{
- $error = new Error('Internal Server Error', null, 500, null, null, $detail, $source);
+ $error = new Error(null, null, null, 500, null, 'Internal Server Error', $detail, $source);
parent::__construct($error, 500);
}
}
diff --git a/lib/classes/JsonApi/Errors/JsonApiExceptionHandler.php b/lib/classes/JsonApi/Errors/JsonApiExceptionHandler.php
deleted file mode 100644
index 25ac092..0000000
--- a/lib/classes/JsonApi/Errors/JsonApiExceptionHandler.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-namespace JsonApi\Errors;
-
-use JsonApi\Providers\JsonApiConfig as C;
-use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface as SC;
-use Neomerx\JsonApi\Document\Error;
-use Neomerx\JsonApi\Encoder\EncoderOptions;
-use Neomerx\JsonApi\Exceptions\ErrorCollection;
-use Neomerx\JsonApi\Exceptions\JsonApiException;
-use Psr\Container\ContainerInterface;
-use Psr\Http\Message\ResponseInterface as Response;
-use Psr\Http\Message\ServerRequestInterface as Request;
-
-/**
- * Dieser spezielle Exception Handler wird in der Slim-Applikation
- * für alle JSON-API-Routen installiert und sorgt dafür, dass auch
- * evtl. Fehler JSON-API-kompatibel geliefert werden.
- */
-class JsonApiExceptionHandler
-{
- private $previous;
-
- private $container;
-
- /**
- * Der Konstruktor...
- *
- * @param ContainerInterface $container der Dependency Container,
- * der in der Slim-Applikation verwendet wird
- * @param callable $previous der zuvor installierte `Error
- * Handler` als Fallback
- */
- public function __construct(ContainerInterface $container, $previous = null)
- {
- $this->previous = $previous;
- $this->container = $container;
- }
-
- /**
- * Diese Methode wird aufgerufen, sobald es zu einer Exception
- * kam, und generiert eine entsprechende JSON-API-spezifische Response.
- *
- * @param Request $request der eingehende Request
- * @param Response $response die vorbereitete ausgehende Response
- * @param \Exception $exception die aufgetretene Exception
- *
- * @return Response die JSON-API-kompatible Response
- */
- public function __invoke(Request $request, Response $response, \Exception $exception)
- {
- if ($exception instanceof JsonApiException) {
- $httpCode = $exception->getHttpCode();
- $errors = $exception->getErrors();
- } else {
- $httpCode = 500;
- $details = null;
-
- $debugEnabled = \Studip\ENV === 'development';
- if ($debugEnabled === true) {
- $message = $exception->getMessage();
- $details = (string) $exception;
- }
- $errors = new ErrorCollection();
- $errors->add(new Error(null, null, $httpCode, null, $message, $details));
- }
-
- if (sizeof($errors)) {
- $encoder = $this->createEncoder();
- $response = $response
- ->withHeader(
- 'Content-Type',
- sprintf('%s/%s',
- MediaTypeInterface::JSON_API_TYPE,
- MediaTypeInterface::JSON_API_SUB_TYPE
- )
- )
- ->write($encoder->encodeErrors($errors));
- }
-
- return $response->withStatus($httpCode);
- }
-
- private function createEncoder()
- {
- $factory = $this->container[FactoryInterface::class];
- $schemaContainer = $this->container[SC::class];
-
- $urlPrefix = $this->container[C::JSON_URL_PREFIX];
-
- $encoderOptions = new EncoderOptions(0, $urlPrefix);
-
- return $factory->createEncoder($schemaContainer, $encoderOptions);
- }
-}
diff --git a/lib/classes/JsonApi/Errors/NotAcceptableException.php b/lib/classes/JsonApi/Errors/NotAcceptableException.php
new file mode 100644
index 0000000..dddb377
--- /dev/null
+++ b/lib/classes/JsonApi/Errors/NotAcceptableException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace JsonApi\Errors;
+
+use Neomerx\JsonApi\Schema\Error;
+use Neomerx\JsonApi\Exceptions\JsonApiException;
+
+class NotAcceptableException extends JsonApiException
+{
+ public function __construct()
+ {
+ $error = new Error(null, null, null, '406', null, 'Not Acceptable Error');
+ parent::__construct($error, 406);
+ }
+}
diff --git a/lib/classes/JsonApi/Errors/NotImplementedException.php b/lib/classes/JsonApi/Errors/NotImplementedException.php
index 4e8541d..d6f35a1 100644
--- a/lib/classes/JsonApi/Errors/NotImplementedException.php
+++ b/lib/classes/JsonApi/Errors/NotImplementedException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class NotImplementedException extends JsonApiException
*/
public function __construct($detail = null, array $source = null)
{
- $error = new Error('Not Implemented Error', null, 501, null, null, $detail, $source);
+ $error = new Error(null, null, null, 501, null, 'Not Implemented Error', $detail, $source);
parent::__construct($error, 501);
}
}
diff --git a/lib/classes/JsonApi/Errors/RecordNotFoundException.php b/lib/classes/JsonApi/Errors/RecordNotFoundException.php
index 9ed0c1a..4cf0cb9 100644
--- a/lib/classes/JsonApi/Errors/RecordNotFoundException.php
+++ b/lib/classes/JsonApi/Errors/RecordNotFoundException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class RecordNotFoundException extends JsonApiException
*/
public function __construct($error = null)
{
- $error = new Error($error ?: 'Not Found', null, 404);
- parent::__construct($error, 404);
+ $errorObject = new Error(null, null, null, 404, null, 'Not Found', $error);
+ parent::__construct($errorObject, 404);
}
}
diff --git a/lib/classes/JsonApi/Errors/UnprocessableEntityException.php b/lib/classes/JsonApi/Errors/UnprocessableEntityException.php
index e8a4794..2af4d89 100644
--- a/lib/classes/JsonApi/Errors/UnprocessableEntityException.php
+++ b/lib/classes/JsonApi/Errors/UnprocessableEntityException.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class UnprocessableEntityException extends JsonApiException
*/
public function __construct($detail = null, array $source = null)
{
- $error = new Error('Unprocesssable Entity', null, 422, null, null, $detail, $source);
+ $error = new Error(null, null, null, 422, null, 'Unprocesssable Entity', $detail, $source);
parent::__construct($error, 422);
}
}
diff --git a/lib/classes/JsonApi/Errors/UnsupportedMediaTypeException.php b/lib/classes/JsonApi/Errors/UnsupportedMediaTypeException.php
new file mode 100644
index 0000000..ec83571
--- /dev/null
+++ b/lib/classes/JsonApi/Errors/UnsupportedMediaTypeException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace JsonApi\Errors;
+
+use Neomerx\JsonApi\Schema\Error;
+use Neomerx\JsonApi\Exceptions\JsonApiException;
+
+class UnsupportedMediaTypeException extends JsonApiException
+{
+ public function __construct()
+ {
+ $error = new Error(null, null, null, '415', null, 'Unsupported Media Type Error');
+ parent::__construct($error, 415);
+ }
+}
diff --git a/lib/classes/JsonApi/Errors/UnsupportedRequestError.php b/lib/classes/JsonApi/Errors/UnsupportedRequestError.php
index 62ac4fb..3b8bcd5 100644
--- a/lib/classes/JsonApi/Errors/UnsupportedRequestError.php
+++ b/lib/classes/JsonApi/Errors/UnsupportedRequestError.php
@@ -2,7 +2,7 @@
namespace JsonApi\Errors;
-use Neomerx\JsonApi\Document\Error;
+use Neomerx\JsonApi\Schema\Error;
use Neomerx\JsonApi\Exceptions\JsonApiException;
/**
@@ -15,7 +15,7 @@ class UnsupportedRequestError extends JsonApiException
*/
public function __construct($detail = null, array $source = null)
{
- $error = new Error('Unsupported request.', null, 403, null, null, $detail, $source);
+ $error = new Error(null, null, null, 403, null, 'Unsupported request.', $detail, $source);
parent::__construct($error, 403);
}
}
diff --git a/lib/classes/JsonApi/JsonApiController.php b/lib/classes/JsonApi/JsonApiController.php
index 645d404..1718c52 100644
--- a/lib/classes/JsonApi/JsonApiController.php
+++ b/lib/classes/JsonApi/JsonApiController.php
@@ -3,10 +3,20 @@
namespace JsonApi;
use JsonApi\JsonApiIntegration\JsonApiTrait;
+use JsonApi\JsonApiIntegration\QueryParserInterface;
+use JsonApi\Middlewares\Authentication;
+use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface;
+use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
+use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
+use Neomerx\JsonApi\Http\Headers\MediaType;
+use Neomerx\JsonApi\Schema\Link;
use Psr\Container\ContainerInterface;
-
-use Neomerx\JsonApi\Contracts\Http\Headers\HeadersCheckerInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
/**
* Ein JsonApiController ist die einfachste Möglichkeit, eine eigene
@@ -28,19 +38,426 @@ use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface;
*/
class JsonApiController
{
- use JsonApiTrait;
+ /**
+ * @var \Slim\App
+ */
+ protected $app;
+
+ /**
+ * @var ContainerInterface;
+ */
+ protected $container;
+
+ /**
+ * @var FactoryInterface
+ */
+ protected $factory;
+
+ /**
+ * @var EncoderInterface
+ */
+ protected $encoder;
+
+ /**
+ * @var SchemaContainerInterface
+ */
+ protected $schemaContainer;
+
+ /**
+ * @var QueryParserInterface
+ */
+ protected $queryParser;
/**
* Der Konstruktor.
+ */
+ public function __construct(
+ \Slim\App $app,
+ ContainerInterface $container,
+ FactoryInterface $factory,
+ EncoderInterface $encoder,
+ SchemaContainerInterface $schemaContainer,
+ QueryParserInterface $queryParser,
+ HeaderParametersParserInterface $headerParametersParser
+ ) {
+ $this->app = $app;
+ $this->container = $container;
+ $this->factory = $factory;
+ $this->encoder = $encoder;
+ $this->schemaContainer = $schemaContainer;
+ $this->queryParser = $queryParser;
+
+ $queryChecker = new JsonApiIntegration\QueryChecker(
+ $this->allowUnrecognizedParams,
+ $this->allowedIncludePaths,
+ $this->allowedFieldSetTypes,
+ $this->allowedSortFields,
+ $this->allowedPagingParameters,
+ $this->allowedFilteringParameters
+ );
+
+ $queryChecker->checkQuery($queryParser);
+
+ $this->checkAcceptHeader($headerParametersParser);
+ $this->checkContentTypeHeader($headerParametersParser);
+ }
+
+ /**
+ * If unrecognized parameters should be allowed in input parameters.
+ *
+ * @var bool
+ */
+ protected $allowUnrecognizedParams = false;
+
+ /**
+ * A list of allowed include paths in input parameters.
+ *
+ * Empty array [] means clients are not allowed to specify include paths and 'null' means all paths are allowed.
+ *
+ * @var string[]|null
+ */
+ protected $allowedIncludePaths = [];
+
+ /**
+ * A list of JSON API types which clients can sent field sets to.
+ *
+ * Possible values
+ *
+ * $allowedFieldSetTypes = null; // <-- for all types all fields are allowed
+ *
+ * $allowedFieldSetTypes = []; // <-- non of the types and fields are allowed
+ *
+ * $allowedFieldSetTypes = [
+ * 'people' => null, // <-- all fields for 'people' are allowed
+ * 'comments' => [], // <-- no fields for 'comments' are allowed (all denied)
+ * 'posts' => ['title', 'body'], // <-- only 'title' and 'body' fields are allowed for 'posts'
+ * ];
*
- * @param ContainerInterface $container der Dependency Container
+ * @var string[]|null
*/
- public function __construct(ContainerInterface $container)
+ protected $allowedFieldSetTypes = null;
+
+ /**
+ * A list of allowed sort field names in input parameters.
+ *
+ * Empty array [] means clients are not allowed to specify sort fields and 'null' means all fields are allowed.
+ *
+ * @var string[]|null
+ */
+ protected $allowedSortFields = [];
+
+ /**
+ * A list of allowed pagination input parameters (e.g 'number', 'size', 'offset' and etc).
+ *
+ * Empty array [] means clients are not allowed to specify paging and 'null' means all parameters are allowed.
+ *
+ * @var string[]|null
+ */
+ protected $allowedPagingParameters = [];
+
+ /**
+ * A list of allowed filtering input parameters.
+ *
+ * Empty array [] means clients are not allowed to specify filtering and 'null' means all parameters are allowed.
+ *
+ * @var string[]|null
+ */
+ protected $allowedFilteringParameters = [];
+
+ // ***** RESPONSE GENERATORS *****
+
+ /**
+ * Get response with HTTP code only.
+ */
+ protected function getCodeResponse(int $statusCode, array $headers = []): Response
{
- $this->container = $container;
- $this->initJsonApiSupport($container);
+ $responses = $this->getResponses();
+
+ return $responses->getCodeResponse($statusCode, $headers);
+ }
+
+ /**
+ * Get response with meta information only.
+ *
+ * @param array|object $meta Meta information
+ * @param int $statusCode
+ */
+ protected function getMetaResponse($meta, $statusCode = ResponsesInterface::HTTP_OK, array $headers = []): Response
+ {
+ $responses = $this->getResponses();
+
+ return $responses->getMetaResponse($meta, $statusCode, $headers);
+ }
+
+ /**
+ * Get response with regular JSON API Document in body.
+ *
+ * @param object|array $data
+ * @param int $statusCode
+ * @param array|null $links
+ * @param mixed $meta
+ */
+ protected function getContentResponse(
+ $data,
+ $statusCode = ResponsesInterface::HTTP_OK,
+ $links = [],
+ $meta = [],
+ array $headers = []
+ ): Response {
+ $responses = $this->getResponses($links, $meta);
+
+ return $responses->getContentResponse($data, $statusCode, $headers);
+ }
+
+ /**
+ * Get response with only resource identifiers.
+ *
+ * @param object|array $data
+ * @param array|null $links
+ * @param mixed $meta
+ */
+ protected function getIdentifiersResponse($data, $links = [], $meta = [], array $headers = []): Response
+ {
+ $responses = $this->getResponses($links, $meta);
+ $statusCode = ResponsesInterface::HTTP_OK;
+
+ return $responses->getIdentifiersResponse($data, $statusCode, $headers);
+ }
+
+ /**
+ * Get response with paginated resource identifiers.
+ *
+ * @param object|array $data
+ * @param ?int $total
+ * @param array|null $links
+ * @param mixed $meta
+ */
+ protected function getPaginatedIdentifiersResponse(
+ $data,
+ $total,
+ $links = [],
+ $meta = [],
+ array $headers = []
+ ): Response {
+ list($offset, $limit) = $this->getOffsetAndLimit();
+
+ $meta['page'] = [
+ 'offset' => (int) $offset,
+ 'limit' => (int) $limit,
+ ];
+
+ if (isset($total)) {
+ $meta['page']['total'] = (int) $total;
+ }
+
+ $paginator = new JsonApiIntegration\Paginator($total, $offset, $limit);
+
+ foreach (words('first last prev next') as $rel) {
+ if (list($off, $lim) = $paginator->{'get'.ucfirst($rel).'PageOffsetAndLimit'}()) {
+ $links[$rel] = $this->createLink($off, $lim);
+ }
+ }
+
+ $responses = $this->getResponses($links, $meta);
+ $statusCode = ResponsesInterface::HTTP_OK;
+
+ return $responses->getIdentifiersResponse($data, $statusCode, $headers);
+ }
+
+ /**
+ * @param object $resource
+ * @param array|null $links
+ * @param mixed $meta
+ */
+ protected function getCreatedResponse($resource, $links = [], $meta = [], array $headers = []): Response
+ {
+ $responses = $this->getResponses($links, $meta);
+ $urlPrefix = $this->container->get('json-api-integration-urlPrefix');
+ $url = $this->schemaContainer
+ ->getSchema($resource)
+ ->getSelfLink($resource)
+ ->getStringRepresentation($urlPrefix);
+
+ return $responses->getCreatedResponse($resource, $url, $headers);
+ }
+
+ /**
+ * @param object|array $data
+ * @param ?int $total
+ * @param int $statusCode
+ * @param array|null $links
+ * @param mixed $meta
+ */
+ protected function getPaginatedContentResponse(
+ $data,
+ $total,
+ $statusCode = ResponsesInterface::HTTP_OK,
+ $links = [],
+ $meta = [],
+ array $headers = []
+ ): Response {
+ list($offset, $limit) = $this->getOffsetAndLimit();
+
+ $meta['page'] = [
+ 'offset' => (int) $offset,
+ 'limit' => (int) $limit,
+ ];
+
+ if (isset($total)) {
+ $meta['page']['total'] = (int) $total;
+ }
+
+ $paginator = new JsonApiIntegration\Paginator($total, $offset, $limit);
+
+ foreach (words('first last prev next') as $rel) {
+ if (list($off, $lim) = $paginator->{'get'.ucfirst($rel).'PageOffsetAndLimit'}()) {
+ $links[$rel] = $this->createLink($off, $lim);
+ }
+ }
+
+ $responses = $this->getResponses($links, $meta);
+
+ return $responses->getContentResponse($data, $statusCode, $headers);
+ }
+
+ protected function getQueryParameters(): QueryParserInterface
+ {
+ return $this->queryParser;
+ }
+
+ /**
+ * Liefert Offset und Limit aus den Request-Parametern zurück.
+ *
+ * @param int $offsetDefault optional; gibt den Standard-Offset
+ * an, falls dieser Wert nicht im Request gesetzt ist
+ * @param int $limitDefault optional; gibt das Standard-Limit an,
+ * falls dieser Wert nicht im Request gesetzt ist
+ *
+ * @return array<int> {
+ *
+ * @var int $offset der im Request gesetzte Offset oder
+ * ansonsten der Default-Wert 0
+ * @var int $limit das im Request gesetzte Limit oder
+ * ansonsten der Default-Wert 30
+ * }
+ */
+ protected function getOffsetAndLimit($offsetDefault = 0, $limitDefault = 30): array
+ {
+ $params = iterator_to_array($this->queryParser->getPagination());
+
+ return [
+ $params && array_key_exists('offset', $params) ? (int) $params['offset'] : $offsetDefault,
+ $params && array_key_exists('limit', $params) ? (int) $params['limit'] : $limitDefault,
+ ];
+ }
+
+ // Hier wird der aktuelle Link zusätzlich noch mit Paginierung ausgestattet
+ private function createLink(int $offset, int $limit): Link
+ {
+ $request = $this->container->get('request');
+ $queryParams = $request->getQueryParams();
+ $queryParams['page']['offset'] = $offset;
+ $queryParams['page']['limit'] = $limit;
+
+ $uri = $request->getUri()->withQuery(http_build_query($queryParams));
+
+ $path = $uri->getPath();
+ $query = $uri->getQuery();
+ $fragment = $uri->getFragment();
+
+ $uriString = $path.($query ? '?'.$query : '').($fragment ? '#'.$fragment : '');
+
+ return new Link(false, $uriString, false);
+ }
+
+ /**
+ * Gibt null oder das User-Objekt des "eingeloggten" Nutzers zurück.
+ *
+ * @param Request $request Request der eingehende Request
+ *
+ * @return mixed entweder null oder das User-Objekt des
+ * "eingeloggten" Nutzers
+ */
+ public function getUser(Request $request)
+ {
+ return $request->getAttribute(Authentication::USER_KEY, null);
+ }
+
+ /**
+ * Gibt das Schema zu einer beliebigen Ressource zurück.
+ *
+ * @param mixed $resource die Ressource, zu der das Schema geliefert werden soll
+ *
+ * @return SchemaInterface das Schema zur Ressource
+ */
+ protected function getSchema($resource): SchemaInterface
+ {
+ return $this->schemaContainer->getSchema($resource);
+ }
+
+ protected function getResponses(array $links = [], array $meta = []): ResponsesInterface
+ {
+ $paths = $this->queryParser->getIncludePaths();
+ $fieldSets = iterator_to_array($this->queryParser->getFields());
+
+ $encoder = $this->encoder
+ ->withIncludedPaths($paths)
+ ->withFieldSets($fieldSets)
+ ->withLinks($links);
+ if (count($meta)) {
+ $encoder = $encoder->withMeta($meta);
+ }
+
+ $mediaType = new MediaType(MediaTypeInterface::JSON_API_TYPE, MediaTypeInterface::JSON_API_SUB_TYPE);
+
+ return new JsonApiIntegration\Responses($encoder, $mediaType);
+ }
+
+ private function checkAcceptHeader(HeaderParametersParserInterface $headerParametersParser): void
+ {
+ $request = $this->container->get('request');
+ $accept = $request->getHeader(HeaderParametersParserInterface::HEADER_ACCEPT);
+ if (count($accept)) {
+ $mediaType = $this->factory->createMediaType(
+ MediaTypeInterface::JSON_API_TYPE,
+ MediaTypeInterface::JSON_API_SUB_TYPE
+ );
+
+ foreach ($headerParametersParser->parseAcceptHeader($accept[0]) as $acceptMediaType) {
+ if ($mediaType->matchesTo($acceptMediaType)) {
+ return;
+ }
+ }
+ }
+ throw new Errors\NotAcceptableException();
+ }
+
+ private function checkContentTypeHeader(HeaderParametersParserInterface $headerParametersParser): void
+ {
+ $request = $this->container->get('request');
+ if ($this->doesRequestHaveBody($request)) {
+ $contentType = $request->getHeader(HeaderParametersParserInterface::HEADER_CONTENT_TYPE);
+ if (count($contentType)) {
+ $mediaType = $this->factory->createMediaType(
+ MediaTypeInterface::JSON_API_TYPE,
+ MediaTypeInterface::JSON_API_SUB_TYPE
+ );
+ $parsedContentType = $headerParametersParser->parseContentTypeHeader($contentType[0]);
+ if ($mediaType->matchesTo($parsedContentType)) {
+ return;
+ }
+ }
+ throw new Errors\UnsupportedMediaTypeException();
+ }
+ }
+
+ private function doesRequestHaveBody(Request $request): bool
+ {
+ if (count($request->getHeader('Transfer-Encoding'))) {
+ return true;
+ }
+ $contentLength = $request->getHeader('Content-Length');
- $headerChecker = $this->container[HeadersCheckerInterface::class];
- $headerChecker->checkHeaders($this->container[HeaderParametersInterface::class]);
+ return count($contentLength) && $contentLength[0] > 0;
}
}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/Container.php b/lib/classes/JsonApi/JsonApiIntegration/Container.php
deleted file mode 100644
index 7f9911a..0000000
--- a/lib/classes/JsonApi/JsonApiIntegration/Container.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-
-namespace JsonApi\JsonApiIntegration;
-
-class Container extends \Neomerx\JsonApi\Schema\Container
-{
- /**
- * Überprüft nicht nur, ob es ein mapping zum $type gibt, sondern
- * sucht sonst auch nach mappings der Oberklassen bzw. Interfaces.
- *
- * @param string $type
- *
- * @return bool
- */
- protected function hasProviderMapping($type)
- {
- if (parent::hasProviderMapping($type)) {
- return true;
- }
-
- foreach ($this->getParentClassesAndInterfaces($type) as $class) {
- if (parent::hasProviderMapping($class)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Liefert nicht nur direkte Treffer aus den provider mappings
- * sondern schaut falls nötig auch nach Oberklassen bzw. Interfaces.
- *
- * @param string $type
- *
- * @return mixed
- */
- protected function getProviderMapping($type)
- {
- $providerMapping = $this->getProviderMappings();
-
- if (isset($providerMapping[$type])) {
- return $providerMapping[$type];
- }
-
- foreach ($this->getParentClassesAndInterfaces($type) as $class) {
- if (isset($providerMapping[$class])) {
- return $providerMapping[$class];
- }
- }
-
- return null;
- }
-
- private function getParentClassesAndInterfaces($type)
- {
- return class_exists($type) ? @class_parents($type) + @class_implements($type) : [];
- }
-
- /**
- * @deprecated use `createSchemaFromCallable` method instead
- *
- * @param Closure $closure
- *
- * @return SchemaProviderInterface
- */
- protected function createSchemaFromClosure(\Closure $closure)
- {
- $schema = $closure($this->getFactory(), $this);
-
- return $schema;
- }
-
- /**
- * @param callable $callable
- *
- * @return SchemaProviderInterface
- */
- protected function createSchemaFromCallable(callable $callable)
- {
- $schema = $callable instanceof \Closure ?
- $this->createSchemaFromClosure($callable) : call_user_func($callable, $this->getFactory(), $this);
-
- return $schema;
- }
-
- /**
- * @param string $className
- *
- * @return SchemaProviderInterface
- */
- protected function createSchemaFromClassName($className)
- {
- $schema = new $className($this->getFactory(), $this);
-
- return $schema;
- }
-}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/EncoderParser.php b/lib/classes/JsonApi/JsonApiIntegration/EncoderParser.php
deleted file mode 100644
index 2e047b7..0000000
--- a/lib/classes/JsonApi/JsonApiIntegration/EncoderParser.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-namespace JsonApi\JsonApiIntegration;
-
-use SimpleORMap;
-use Neomerx\JsonApi\Encoder\Parser\Parser as NeomerxParser;
-
-/**
- * Eine Instanz von Neomerx\JsonApi\Encoder\Parser\Parser wird
- * benötigt, um Werte, die an den JSON-API-Encoder gehen, zu
- * analysieren und entsprechned weiter zu verarbeiten. Unter anderem
- * wird darin auch die Unterscheidung getroffen, ob Werte, die an den
- * JSON-API-Encoder gehen, Collections sind oder nicht.
- *
- * Bei dieser Analyse werden sinnvollerweise alle Werte, die das
- * PHP-Interface \IteratorAggregate implementieren, als Collections
- * behandelt. Da aber die Stud.IP-Klasse \SimpleORMap
- * ungewöhnlicherweise ebenfalls dieses Interface implementiert, muss
- * hier eine Sonderbehandlung stattfinden.
- *
- * Dazu wird die Methode
- * Neomerx\JsonApi\Encoder\Parser\Parser::analyzeCurrentData so
- * überschrieben, dass Instanzen von \SimpleORMap nicht als
- * Collections gelten.
- *
- * @see Neomerx\JsonApi\Encoder\Parser\Parser
- * @see \SimpleORMap
- */
-class EncoderParser extends NeomerxParser
-{
- /**
- * {@inheritdoc}
- */
- protected function analyzeCurrentData()
- {
- $relationship = $this->stack->end()->getRelationship();
- $data = $relationship->isShowData() === true ? $relationship->getData() : null;
-
- if ($data instanceof SimpleORMap) {
- $isEmpty = false;
- $isCollection = false;
- $traversableData = [$data];
-
- return [$isEmpty, $isCollection, $traversableData];
- }
-
- return parent::analyzeCurrentData();
- }
-}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/Factory.php b/lib/classes/JsonApi/JsonApiIntegration/Factory.php
index 8e99d3b..afdd431 100644
--- a/lib/classes/JsonApi/JsonApiIntegration/Factory.php
+++ b/lib/classes/JsonApi/JsonApiIntegration/Factory.php
@@ -2,9 +2,12 @@
namespace JsonApi\JsonApiIntegration;
+use Neomerx\JsonApi\Contracts\Parser\EditableContextInterface;
+use Neomerx\JsonApi\Contracts\Parser\ParserInterface;
+use Neomerx\JsonApi\Contracts\Schema\LinkInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
use Neomerx\JsonApi\Factories\Factory as NeomerxFactory;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
-use Neomerx\JsonApi\Contracts\Encoder\Parser\ParserManagerInterface;
+use Neomerx\JsonApi\Schema\Link;
/**
* Die "normale" \Neomerx\JsonApi\Factories\Factory stellt in
@@ -19,38 +22,21 @@ use Neomerx\JsonApi\Contracts\Encoder\Parser\ParserManagerInterface;
*/
class Factory extends NeomerxFactory
{
- private $diContainer;
-
- public function setDependencyInjectionContainer(\Psr\Container\ContainerInterface $diContainer)
- {
- $this->diContainer = $diContainer;
- }
-
- public function getDependencyInjectionContainer()
- {
- return $this->diContainer;
- }
-
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
- public function createContainer(array $providers = [])
- {
- $container = new Container($this, $providers);
-
- $container->setLogger($this->logger);
-
- return $container;
+ public function createParser(
+ SchemaContainerInterface $container,
+ EditableContextInterface $context
+ ): ParserInterface {
+ return new Parser($this, $container, $context);
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
- public function createParser(ContainerInterface $container, ParserManagerInterface $manager)
+ public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
{
- $parser = new EncoderParser($this, $this, $this, $container, $manager);
- $parser->setLogger($this->logger);
-
- return $parser;
+ return new SchemaContainer($this, $schemas);
}
}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/JsonApiTrait.php b/lib/classes/JsonApi/JsonApiIntegration/JsonApiTrait.php
deleted file mode 100644
index 3a5e122..0000000
--- a/lib/classes/JsonApi/JsonApiIntegration/JsonApiTrait.php
+++ /dev/null
@@ -1,428 +0,0 @@
-<?php
-
-namespace JsonApi\JsonApiIntegration;
-
-use JsonApi\Middlewares\Authentication;
-use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
-use Neomerx\JsonApi\Contracts\Codec\CodecMatcherInterface;
-use Neomerx\JsonApi\Contracts\Parameters\ParametersInterface;
-use Neomerx\JsonApi\Contracts\Parameters\ParametersCheckerInterface;
-use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
-use Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
-use Psr\Http\Message\ServerRequestInterface as Request;
-
-/**
- * Dieser Trait beinhaltet Instanzmethoden und -variablen, die in
- * JSON-API-Routen verwendet werden können, um entsprechende
- * JSON-API-Responses zu generieren.
- *
- * @author info@neomerx.com (www.neomerx.com)
- * @author mlunzena@uos.de
- *
- * @see https://github.com/InactiveProjects/limoncello/blob/v0.5.1/src/Http/JsonApiTrait.php
- */
-trait JsonApiTrait
-{
- /**
- * If unrecognized parameters should be allowed in input parameters.
- *
- * @var bool
- */
- protected $allowUnrecognizedParams = false;
-
- /**
- * A list of allowed include paths in input parameters.
- *
- * Empty array [] means clients are not allowed to specify include paths and 'null' means all paths are allowed.
- *
- * @var string[]|null
- */
- protected $allowedIncludePaths = [];
-
- /**
- * A list of JSON API types which clients can sent field sets to.
- *
- * Possible values
- *
- * $allowedFieldSetTypes = null; // <-- for all types all fields are allowed
- *
- * $allowedFieldSetTypes = []; // <-- non of the types and fields are allowed
- *
- * $allowedFieldSetTypes = [
- * 'people' => null, // <-- all fields for 'people' are allowed
- * 'comments' => [], // <-- no fields for 'comments' are allowed (all denied)
- * 'posts' => ['title', 'body'], // <-- only 'title' and 'body' fields are allowed for 'posts'
- * ];
- *
- * @var array|null
- */
- protected $allowedFieldSetTypes = null;
-
- /**
- * A list of allowed sort field names in input parameters.
- *
- * Empty array [] means clients are not allowed to specify sort fields and 'null' means all fields are allowed.
- *
- * @var string[]|null
- */
- protected $allowedSortFields = [];
-
- /**
- * A list of allowed pagination input parameters (e.g 'number', 'size', 'offset' and etc).
- *
- * Empty array [] means clients are not allowed to specify paging and 'null' means all parameters are allowed.
- *
- * @var string[]|null
- */
- protected $allowedPagingParameters = [];
-
- /**
- * A list of allowed filtering input parameters.
- *
- * Empty array [] means clients are not allowed to specify filtering and 'null' means all parameters are allowed.
- *
- * @var string[]|null
- */
- protected $allowedFilteringParameters = [];
-
- /**
- * @var Psr\Container\ContainerInterface;
- */
- protected $container;
-
- /**
- * @var ParametersCheckerInterface
- */
- private $parametersChecker;
-
- /**
- * @var bool
- */
- private $parametersChecked = false;
-
- /**
- * Init integrations with JSON API implementation.
- *
- * @param $container
- */
- private function initJsonApiSupport($container)
- {
- $this->container = $container;
-
- $factory = $container[FactoryInterface::class];
-
- $this->parametersChecker = $factory->createQueryChecker(
- $this->allowUnrecognizedParams,
- $this->allowedIncludePaths,
- $this->allowedFieldSetTypes,
- $this->allowedSortFields,
- $this->allowedPagingParameters,
- $this->allowedFilteringParameters
- );
- }
-
- // ***** RESPONSE GENERATORS *****
-
- /**
- * Get response with HTTP code only.
- *
- * @param $statusCode
- *
- * @return Response
- */
- protected function getCodeResponse($statusCode, array $headers = [])
- {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
-
- return $responses->getCodeResponse($statusCode, $headers);
- }
-
- /**
- * Get response with meta information only.
- *
- * @param array|object $meta Meta information
- * @param int $statusCode
- *
- * @return Response
- */
- protected function getMetaResponse($meta, $statusCode = ResponsesInterface::HTTP_OK, $headers = [])
- {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
-
- return $responses->getMetaResponse($meta, $statusCode, $headers);
- }
-
- /**
- * Get response with regular JSON API Document in body.
- *
- * @param object|array $data
- * @param int $statusCode
- * @param array<string,\Neomerx\JsonApi\Contracts\Schema\LinkInterface>|null $links
- * @param mixed $meta
- *
- * @return Response
- */
- protected function getContentResponse(
- $data,
- $statusCode = ResponsesInterface::HTTP_OK,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
-
- return $responses->getContentResponse($data, $statusCode, $links, $meta, $headers);
- }
-
- /**
- * Get response with only resource identifiers.
- *
- * @param object|array $data
- * @param int $statusCode
- * @param array|null $links
- * @param mixed $meta
- * @param array $headers
- *
- * @return mixed
- */
- protected function getIdentifiersResponse(
- $data,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
- $statusCode = ResponsesInterface::HTTP_OK;
-
- return $responses->getIdentifiersResponse($data, $statusCode, $links, $meta, $headers);
- }
-
- protected function getPaginatedIdentifiersResponse(
- $data,
- $total,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
- $statusCode = ResponsesInterface::HTTP_OK;
-
- list($offset, $limit) = $this->getOffsetAndLimit();
-
- if (!$meta) {
- $meta = [];
- }
-
- $meta['page'] = [
- 'offset' => (int) $offset,
- 'limit' => (int) $limit,
- ];
-
- if (isset($total)) {
- $meta['page']['total'] = (int) $total;
- }
-
- $paginator = new Paginator($total, $offset, $limit);
-
- if (!$links) {
- $links = [];
- }
-
- foreach (words('first last prev next') as $rel) {
- if (list($off, $lim) = $paginator->{'get'.ucfirst($rel).'PageOffsetAndLimit'}()) {
- $links[$rel] = $this->createLink($off, $lim);
- }
- }
-
- return $responses->getIdentifiersResponse($data, $statusCode, $links, $meta, $headers);
- }
-
- /**
- * @param object $resource
- * @param array<string,\Neomerx\JsonApi\Contracts\Schema\LinkInterface>|null $links
- * @param mixed $meta
- *
- * @return Response
- */
- protected function getCreatedResponse(
- $resource,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
-
- return $responses->getCreatedResponse($resource, $links, $meta, $headers);
- }
-
- protected function getPaginatedContentResponse(
- $data,
- $total,
- $statusCode = ResponsesInterface::HTTP_OK,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $this->checkQueryParameters();
- $responses = $this->container[ResponsesInterface::class];
-
- list($offset, $limit) = $this->getOffsetAndLimit();
-
- if (!$meta) {
- $meta = [];
- }
-
- $meta['page'] = [
- 'offset' => (int) $offset,
- 'limit' => (int) $limit,
- ];
-
- if (isset($total)) {
- $meta['page']['total'] = (int) $total;
- }
-
- $paginator = new Paginator($total, $offset, $limit);
-
- if (!$links) {
- $links = [];
- }
-
- foreach (words('first last prev next') as $rel) {
- if (list($off, $lim) = $paginator->{'get'.ucfirst($rel).'PageOffsetAndLimit'}()) {
- $links[$rel] = $this->createLink($off, $lim);
- }
- }
-
- return $responses->getContentResponse($data, $statusCode, $links, $meta, $headers);
- }
-
- /**
- * @return mixed
- */
- protected function getDocument()
- {
- $request = $this->container['request'];
- $codecMatcher = $this->container[CodecMatcherInterface::class];
- if ($codecMatcher->getDecoder() === null) {
- $parameters = $this->container[HeaderParametersInterface::class];
- $codecMatcher->matchDecoder($parameters->getContentTypeHeader());
- }
- $decoder = $codecMatcher->getDecoder();
-
- return $decoder->decode($request->getBody()->getContents());
- }
-
- protected function checkQueryParameters()
- {
- $this->parametersChecker->checkQuery($this->container[EncodingParametersInterface::class]);
- $this->parametersChecked = true;
- }
-
- /**
- * @return ParametersInterface
- */
- protected function getQueryParameters()
- {
- if ($this->parametersChecked === false) {
- $this->checkQueryParameters();
- }
-
- return $this->container[EncodingParametersInterface::class];
- }
-
- /**
- * Liefert Offset und Limit aus den Request-Parametern zurück.
- *
- * @param int $offsetDefault optional; gibt den Standard-Offset
- * an, falls dieser Wert nicht im Request gesetzt ist
- * @param int $limitDefault optional; gibt das Standard-Limit an,
- * falls dieser Wert nicht im Request gesetzt ist
- *
- * @return array {
- *
- * @var int $offset der im Request gesetzte Offset oder
- * ansonsten der Default-Wert 0
- * @var int $limit das im Request gesetzte Limit oder
- * ansonsten der Default-Wert 30
- * }
- */
- protected function getOffsetAndLimit($offsetDefault = 0, $limitDefault = 30)
- {
- $params = $this->getQueryParameters()->getPaginationParameters();
-
- return [
- $params && array_key_exists('offset', $params) ? (int) $params['offset'] : $offsetDefault,
- $params && array_key_exists('limit', $params) ? (int) $params['limit'] : $limitDefault,
- ];
- }
-
- private function createLink($offset, $limit)
- {
- $factory = $this->container[FactoryInterface::class];
- $request = $this->container['request'];
-
- $queryParams = $request->getQueryParams();
- $queryParams['page']['offset'] = $offset;
- $queryParams['page']['limit'] = $limit;
-
- $uri = $request->getUri()->withQuery(http_build_query($queryParams));
-
- $basePath = $uri->getBasePath();
- $path = $uri->getPath();
- $query = $uri->getQuery();
- $fragment = $uri->getFragment();
-
- $uriString = $basePath.'/'.ltrim($path, '/')
- .($query ? '?'.$query : '')
- .($fragment ? '#'.$fragment : '');
-
- return $factory->createLink($uriString, null, true);
- }
-
- /**
- * Gibt null oder das User-Objekt des "eingeloggten" Nutzers zurück.
- *
- * @param request Request der eingehende Request
- *
- * @return mixed entweder null oder das User-Objekt des
- * "eingeloggten" Nutzers
- */
- public function getUser(Request $request)
- {
- return $request->getAttribute(Authentication::USER_KEY, null);
- }
-
- /**
- * Gibt das Schema zu einer beliebigen Ressource zurück.
- *
- * @param resource Object die Ressource, zu der das Schema geliefert werden soll
- *
- * @return SchemaProviderInterface das Schema zur Ressource
- */
- protected function getSchema($resource)
- {
- return $this->container[ContainerInterface::class]->getSchema($resource);
- }
-
- /**
- * Ermöglicht JSON-Routen das ermitteln der resource location URL
- * eines Objekts.
- *
- * @param resource Object die Ressource zu der die URL gefunden
- * werden soll
- *
- * @retunr String die resource location URL
- */
- protected function getResourceLocationUrl($resource)
- {
- return $this->container[ResponsesInterface::class]->getResourceLocationUrl($resource);
- }
-}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/Paginator.php b/lib/classes/JsonApi/JsonApiIntegration/Paginator.php
index 09f8fc8..7e74f80 100644
--- a/lib/classes/JsonApi/JsonApiIntegration/Paginator.php
+++ b/lib/classes/JsonApi/JsonApiIntegration/Paginator.php
@@ -11,6 +11,20 @@ namespace JsonApi\JsonApiIntegration;
*/
class Paginator
{
+ /** @var int|null */
+ private $total;
+
+ /** @var int */
+ private $offset;
+
+ /** @var int */
+ private $limit;
+
+ /**
+ * @param int|null $total
+ * @param int $offset
+ * @param int $limit
+ */
public function __construct($total, $offset, $limit)
{
$this->total = $total;
@@ -18,16 +32,16 @@ class Paginator
$this->limit = $limit;
}
- public function getFirstPageOffsetAndLimit()
+ public function getFirstPageOffsetAndLimit(): array
{
- if ($this->limit === 0) {
+ if (0 === $this->limit) {
return [0, 0];
}
return [0, $this->limit];
}
- public function getLastPageOffsetAndLimit()
+ public function getLastPageOffsetAndLimit(): ?array
{
if (!isset($this->total)) {
return null;
@@ -42,7 +56,7 @@ class Paginator
return [$last, $this->limit];
}
- public function getPrevPageOffsetAndLimit()
+ public function getPrevPageOffsetAndLimit(): ?array
{
if ($this->limit === 0) {
return null;
@@ -55,7 +69,7 @@ class Paginator
return [max(0, $this->offset - $this->limit), $this->limit];
}
- public function getNextPageOffsetAndLimit()
+ public function getNextPageOffsetAndLimit(): ?array
{
if ($this->limit === 0) {
return null;
diff --git a/lib/classes/JsonApi/JsonApiIntegration/Parser.php b/lib/classes/JsonApi/JsonApiIntegration/Parser.php
new file mode 100644
index 0000000..6e460d9
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/Parser.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace JsonApi\JsonApiIntegration;
+
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Neomerx\JsonApi\Contracts\Parser\EditableContextInterface;
+use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
+use Neomerx\JsonApi\Parser\Parser as NeomerxParser;
+use SimpleORMap;
+use function Neomerx\JsonApi\I18n\format as _;
+
+/**
+ * Eine Instanz von Neomerx\JsonApi\Encoder\Parser\Parser wird
+ * benötigt, um Werte, die an den JSON-API-Encoder gehen, zu
+ * analysieren und entsprechned weiter zu verarbeiten. Unter anderem
+ * wird darin auch die Unterscheidung getroffen, ob Werte, die an den
+ * JSON-API-Encoder gehen, Collections sind oder nicht.
+ *
+ * Bei dieser Analyse werden sinnvollerweise alle Werte, die das
+ * PHP-Interface \IteratorAggregate implementieren, als Collections
+ * behandelt. Da aber die Stud.IP-Klasse \SimpleORMap
+ * ungewöhnlicherweise ebenfalls dieses Interface implementiert, muss
+ * hier eine Sonderbehandlung stattfinden.
+ *
+ * Dazu wird die Methode
+ * Neomerx\JsonApi\Encoder\Parser\Parser::analyzeCurrentData so
+ * überschrieben, dass Instanzen von \SimpleORMap nicht als
+ * Collections gelten.
+ *
+ * @see Neomerx\JsonApi\Parser\Parser
+ * @see \SimpleORMap
+ */
+class Parser extends NeomerxParser
+{
+ /**
+ * @var SchemaContainerInterface
+ */
+ private $schemaContainer;
+
+ /**
+ * As `$schemaContainer` is private in \Neomerx\JsonApi\Parser\Parser it has
+ * to be stored again in this subclass.
+ *
+ * @param FactoryInterface $factory
+ * @param SchemaContainerInterface $container
+ * @param EditableContextInterface $context
+ */
+ public function __construct(
+ FactoryInterface $factory,
+ SchemaContainerInterface $container,
+ EditableContextInterface $context
+ ) {
+ $this->schemaContainer = $container;
+
+ parent::__construct($factory, $container, $context);
+ }
+
+ /**
+ * Show better error messages using instances of subclasses of \SimpleORMap
+ * without a Schema.
+ *
+ * @inheritdoc
+ */
+ public function parse($data, array $paths = []): iterable
+ {
+ \assert(\is_array($data) === true || \is_object($data) === true || $data === null);
+
+ if ($data instanceof SimpleORMap && $this->schemaContainer->hasSchema($data) !== true) {
+ throw new InvalidArgumentException(_(static::MSG_NO_SCHEMA_FOUND, \get_class($data)));
+ }
+
+ return parent::parse($data, $paths);
+ }
+}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/QueryChecker.php b/lib/classes/JsonApi/JsonApiIntegration/QueryChecker.php
new file mode 100644
index 0000000..ff2a03d
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/QueryChecker.php
@@ -0,0 +1,186 @@
+<?php
+
+namespace JsonApi\JsonApiIntegration;
+
+use Neomerx\JsonApi\Exceptions\JsonApiException;
+use Neomerx\JsonApi\Schema\ErrorCollection;
+
+class QueryChecker
+{
+ /**
+ * @var bool
+ */
+ private $allowUnrecognized;
+
+ /**
+ * @var array|null
+ */
+ private $includePaths;
+
+ /**
+ * @var array|null
+ */
+ private $fieldSetTypes;
+
+ /**
+ * @var array|null
+ */
+ private $pagingParameters;
+
+ /**
+ * @var array|null
+ */
+ private $sortParameters;
+
+ /**
+ * @var array|null
+ */
+ private $filteringParameters;
+
+ public function __construct(
+ bool $allowUnrecognized = true,
+ array $includePaths = null,
+ array $fieldSetTypes = null,
+ array $sortParameters = null,
+ array $pagingParameters = null,
+ array $filteringParameters = null
+ ) {
+ $this->includePaths = $includePaths;
+ $this->allowUnrecognized = $allowUnrecognized;
+ $this->fieldSetTypes = $fieldSetTypes;
+ $this->sortParameters = $this->flip($sortParameters);
+ $this->pagingParameters = $this->flip($pagingParameters);
+ $this->filteringParameters = $this->flip($filteringParameters);
+ }
+
+ public function checkQuery(QueryParserInterface $queryParser): void
+ {
+ $errors = new ErrorCollection();
+
+ $this->checkIncludePaths($errors, $queryParser);
+ $this->checkFieldSets($errors, $queryParser);
+ $this->checkFiltering($errors, $queryParser);
+ $this->checkSorting($errors, $queryParser);
+ $this->checkPaging($errors, $queryParser);
+ $this->checkUnrecognized($errors, $queryParser);
+
+ if ($errors->count()) {
+ throw new JsonApiException($errors, JsonApiException::HTTP_CODE_BAD_REQUEST);
+ }
+ }
+
+ protected function checkIncludePaths(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ $withinAllowed = $this->valuesWithinAllowed(
+ iterator_to_array($queryParser->getIncludePaths()),
+ $this->includePaths
+ );
+ if (!$withinAllowed) {
+ $errors->addQueryParameterError(
+ QueryParser::PARAM_INCLUDE,
+ 'Include paths should contain only allowed ones.'
+ );
+ }
+ }
+
+ protected function checkFieldSets(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ $withinAllowed = $this->isFieldsAllowed(iterator_to_array($queryParser->getFields()));
+ if (!$withinAllowed) {
+ $errors->addQueryParameterError(QueryParser::PARAM_FIELDS, 'Field sets should contain only allowed ones.');
+ }
+ }
+
+ protected function checkFiltering(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ $withinAllowed = $this->keysWithinAllowed(
+ iterator_to_array($queryParser->getFilters()),
+ $this->filteringParameters
+ );
+ if (!$withinAllowed) {
+ $errors->addQueryParameterError(QueryParser::PARAM_FILTER, 'Filter should contain only allowed values.');
+ }
+ }
+
+ protected function checkSorting(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ if (null !== $queryParser->getSorts() && null !== $this->sortParameters) {
+ foreach ($queryParser->getSorts() as $sortParameter) {
+ if (!array_key_exists($sortParameter->getField(), $this->sortParameters)) {
+ $errors->addQueryParameterError(
+ QueryParser::PARAM_SORT,
+ sprintf('Sort parameter %s is not allowed.', $sortParameter->getField())
+ );
+ }
+ }
+ }
+ }
+
+ protected function checkPaging(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ $withinAllowed = $this->keysWithinAllowed(
+ iterator_to_array($queryParser->getPagination()),
+ $this->pagingParameters
+ );
+ if (!$withinAllowed) {
+ $errors->addQueryParameterError(
+ QueryParser::PARAM_PAGE,
+ 'Page parameter should contain only allowed values.'
+ );
+ }
+ }
+
+ protected function checkUnrecognized(ErrorCollection $errors, QueryParserInterface $queryParser): void
+ {
+ if (!$this->allowUnrecognized && !empty($queryParser->getUnrecognizedParameters())) {
+ foreach ($queryParser->getUnrecognizedParameters() as $name => $value) {
+ $errors->addQueryParameterError($name, 'Unrecognized Parameter.');
+ }
+ }
+ }
+
+ private function keysWithinAllowed(array $toCheck = null, array $allowed = null): bool
+ {
+ return null === $toCheck || null === $allowed || empty(array_diff_key($toCheck, $allowed));
+ }
+
+ private function valuesWithinAllowed(array $toCheck = null, array $allowed = null): bool
+ {
+ return null === $toCheck || null === $allowed || empty(array_diff($toCheck, $allowed));
+ }
+
+ /**
+ * @return array|null
+ */
+ private function flip(array $array = null)
+ {
+ return $array === null ? null : array_flip($array);
+ }
+
+ /**
+ * Check input fields against allowed.
+ *
+ * @param array|null $fields
+ */
+ private function isFieldsAllowed(array $fields = null): bool
+ {
+ if ($this->fieldSetTypes === null || $fields === null) {
+ return true;
+ }
+
+ foreach ($fields as $type => $requestedFields) {
+ if (array_key_exists($type, $this->fieldSetTypes) === false) {
+ return false;
+ }
+
+ $allowedFields = $this->fieldSetTypes[$type];
+
+ // if not all fields are allowed and requested more fields than allowed
+ if ($allowedFields !== null && empty(array_diff($requestedFields, $allowedFields)) === false) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/QueryParser.php b/lib/classes/JsonApi/JsonApiIntegration/QueryParser.php
new file mode 100644
index 0000000..a33979e
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/QueryParser.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace JsonApi\JsonApiIntegration;
+
+use Neomerx\JsonApi\Contracts\Http\Query\BaseQueryParserInterface as P;
+use Neomerx\JsonApi\Http\Query\BaseQueryParser;
+use Neomerx\JsonApi\Exceptions\JsonApiException;
+use Neomerx\JsonApi\Schema\Error;
+
+/**
+ */
+class QueryParser extends BaseQueryParser implements QueryParserInterface
+{
+ public function getFilteringParameters(): array
+ {
+ return iterator_to_array($this->getFilters());
+ }
+
+ public function getFilters(): iterable
+ {
+ $parameters = $this->getParameters();
+ if (array_key_exists(P::PARAM_FILTER, $parameters)) {
+ $filters = $parameters[P::PARAM_FILTER];
+ if (!is_array($filters) || empty($filters)) {
+ $errorTitle = $this->getMessage(static::MSG_ERR_INVALID_PARAMETER);
+ $error = new Error(null, null, null, null, null, $errorTitle, null, [
+ Error::SOURCE_PARAMETER => P::PARAM_FILTER,
+ ]);
+ throw new JsonApiException($error);
+ }
+
+ foreach ($filters as $type => $field) {
+ yield $type => $field;
+ }
+ }
+ }
+
+ /**
+ * Get pagination parameters from encoder.
+ *
+ * @return iterable
+ */
+ public function getPagination(): iterable
+ {
+ $parameters = $this->getParameters();
+ if (array_key_exists(P::PARAM_PAGE, $parameters)) {
+ $pagination = $parameters[P::PARAM_PAGE];
+ if (!is_array($pagination) || empty($pagination)) {
+ $errorTitle = $this->getMessage(static::MSG_ERR_INVALID_PARAMETER);
+ $error = new Error(null, null, null, null, null, $errorTitle, null, [
+ Error::SOURCE_PARAMETER => P::PARAM_PAGE,
+ ]);
+ throw new JsonApiException($error);
+ }
+
+ foreach ($pagination as $type => $field) {
+ yield $type => $field;
+ }
+ }
+ }
+
+ public function getUnrecognizedParameters(): iterable
+ {
+ $parameters = $this->getParameters();
+ $supported = [
+ P::PARAM_INCLUDE => 0,
+ P::PARAM_FIELDS => 0,
+ P::PARAM_PAGE => 0,
+ P::PARAM_FILTER => 0,
+ P::PARAM_SORT => 0,
+ ];
+ $unrecognized = array_diff_key($parameters, $supported);
+
+ return $unrecognized;
+ }
+}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/QueryParserInterface.php b/lib/classes/JsonApi/JsonApiIntegration/QueryParserInterface.php
new file mode 100644
index 0000000..ad37cb7
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/QueryParserInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace JsonApi\JsonApiIntegration;
+
+use Neomerx\JsonApi\Contracts\Http\Query\BaseQueryParserInterface;
+
+interface QueryParserInterface extends BaseQueryParserInterface
+{
+ /** Query parameter */
+ const PARAM_PAGING_LIMIT = 'limit';
+
+ /** Query parameter */
+ const PARAM_PAGING_OFFSET = 'offset';
+
+ public function getIncludePaths(): iterable;
+
+ public function getFilters(): iterable;
+
+ /**
+ * @return iterable
+ */
+ public function getPagination(): iterable;
+
+ public function getUnrecognizedParameters(): iterable;
+}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/Responses.php b/lib/classes/JsonApi/JsonApiIntegration/Responses.php
index e2f6b54..0b8ccb5 100644
--- a/lib/classes/JsonApi/JsonApiIntegration/Responses.php
+++ b/lib/classes/JsonApi/JsonApiIntegration/Responses.php
@@ -2,28 +2,24 @@
namespace JsonApi\JsonApiIntegration;
+use Neomerx\JsonApi\Http\BaseResponses;
use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
-use Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface;
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
+use Slim\Psr7\Headers;
+use Slim\Psr7\Response;
+
+use Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface;
use Neomerx\JsonApi\Contracts\Http\Headers\SupportedExtensionsInterface;
use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
-use Neomerx\JsonApi\Http\Responses as NeomerxResponses;
-use Slim\Http\Headers;
-use Slim\Http\Response;
/**
* Diese Factory-Klasse verknüpft die "neomerx/json-api"-Bibliothek mit der
* Slim-Applikation. Hier wird festgelegt, wie Slim-artige Response-Objekte gebildet
* werden.
*/
-class Responses extends NeomerxResponses
+class Responses extends BaseResponses
{
/**
- * @var EncodingParametersInterface|null
- */
- private $parameters;
-
- /**
* @var EncoderInterface
*/
private $encoder;
@@ -33,48 +29,12 @@ class Responses extends NeomerxResponses
*/
private $outputMediaType;
- /**
- * @var SupportedExtensionsInterface
- */
- private $extensions;
-
- /**
- * @var ContainerInterface
- */
- private $schemes;
-
- /**
- * @var null|string
- */
- private $urlPrefix;
-
- /**
- * Dieser Konstruktor wird in \JsonApi\Providers\JsonApiServices
- * befüllt.
- *
- * @param MediaTypeInterface $outputMediaType
- * @param SupportedExtensionsInterface $extensions
- * @param EncoderInterface $encoder
- * @param ContainerInterface $schemes
- * @param EncodingParametersInterface|null $parameters
- * @param string|null $urlPrefix
- *
- * @internal
- */
public function __construct(
- MediaTypeInterface $outputMediaType,
- SupportedExtensionsInterface $extensions,
EncoderInterface $encoder,
- ContainerInterface $schemes,
- EncodingParametersInterface $parameters = null,
- $urlPrefix = null
+ MediaTypeInterface $outputMediaType
) {
- $this->extensions = $extensions;
$this->encoder = $encoder;
$this->outputMediaType = $outputMediaType;
- $this->schemes = $schemes;
- $this->urlPrefix = $urlPrefix;
- $this->parameters = $parameters;
}
/**
@@ -87,13 +47,13 @@ class Responses extends NeomerxResponses
* zukünftigen Response
* @param array $headers die Header der zukünftigen Response
*
- * @return \Slim\Http\Response die fertige Slim-Response
+ * @return mixed die fertige Slim-Response
*/
- protected function createResponse($content, $statusCode, array $headers)
+ protected function createResponse(?string $content, int $statusCode, array $headers)
{
$headers = new Headers($headers);
$response = new Response($statusCode, $headers);
- $response->getBody()->write($content);
+ $response->getBody()->write($content ?? '');
return $response->withProtocolVersion('1.1');
}
@@ -103,7 +63,7 @@ class Responses extends NeomerxResponses
*
* @internal
*/
- protected function getEncoder()
+ protected function getEncoder(): EncoderInterface
{
return $this->encoder;
}
@@ -113,77 +73,8 @@ class Responses extends NeomerxResponses
*
* @internal
*/
- protected function getUrlPrefix()
- {
- return $this->urlPrefix;
- }
-
- /**
- * {@inheritdoc}
- *
- * @internal
- */
- protected function getEncodingParameters()
- {
- return $this->parameters;
- }
-
- /**
- * {@inheritdoc}
- *
- * @internal
- */
- protected function getSchemaContainer()
- {
- return $this->schemes;
- }
-
- /**
- * {@inheritdoc}
- *
- * @internal
- */
- protected function getSupportedExtensions()
- {
- return $this->extensions;
- }
-
- /**
- * {@inheritdoc}
- *
- * @internal
- */
- protected function getMediaType()
+ protected function getMediaType(): MediaTypeInterface
{
return $this->outputMediaType;
}
-
- /**
- * {@inheritdoc}
- */
- public function getIdentifiersResponse(
- $data,
- $statusCode = self::HTTP_OK,
- $links = null,
- $meta = null,
- array $headers = []
- ) {
- $encoder = $this->getEncoder();
-
- $links === null ?: $encoder->withLinks($links);
- $meta === null ?: $encoder->withMeta($meta);
- $content = $encoder->encodeIdentifiers($data, $this->getEncodingParameters());
-
- return $this->createJsonApiResponse($content, $statusCode, $headers);
- }
-
- /**
- * Widen method visibility from protected to public.
- *
- * {@inheritdoc}
- */
- public function getResourceLocationUrl($resource)
- {
- return parent::getResourceLocationUrl($resource);
- }
}
diff --git a/lib/classes/JsonApi/JsonApiIntegration/SchemaContainer.php b/lib/classes/JsonApi/JsonApiIntegration/SchemaContainer.php
new file mode 100644
index 0000000..a299084
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/SchemaContainer.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace JsonApi\JsonApiIntegration;
+
+use Closure;
+use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
+use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
+use function Neomerx\JsonApi\I18n\format as _;
+use Neomerx\JsonApi\Schema\SchemaContainer as NeomerxSchemaContainer;
+
+class SchemaContainer extends NeomerxSchemaContainer
+{
+ /**
+ * The original SchemaContainer does not like mappings of interfaces to schemas.
+ * So this method now allows classes *and* interfaces.
+ *
+ * @inheritdoc
+ */
+ public function register(string $type, $schema): void
+ {
+ if (true === empty($type) || (false === \class_exists($type) && false === \interface_exists($type))) {
+ throw new InvalidArgumentException(_(static::MSG_INVALID_MODEL_TYPE));
+ }
+
+ $isOk =
+ (true === \is_string($schema) &&
+ false === empty($schema) &&
+ true === \class_exists($schema) &&
+ true === \in_array(SchemaInterface::class, \class_implements($schema))) ||
+ \is_callable($schema) ||
+ $schema instanceof SchemaInterface;
+ if (false === $isOk) {
+ throw new InvalidArgumentException(_(static::MSG_INVALID_SCHEME, $type));
+ }
+
+ if (true === $this->hasProviderMapping($type)) {
+ throw new InvalidArgumentException(_(static::MSG_TYPE_REUSE_FORBIDDEN, $type));
+ }
+
+ if ($schema instanceof SchemaInterface) {
+ $this->setProviderMapping($type, \get_class($schema));
+ $this->setResourceToJsonTypeMapping($schema->getType(), $type);
+ $this->setCreatedProvider($type, $schema);
+ } else {
+ $this->setProviderMapping($type, $schema);
+ }
+ }
+
+ /**
+ * @param callable $callable
+ *
+ * @return SchemaInterface
+ */
+ protected function createSchemaFromCallable(callable $callable): SchemaInterface
+ {
+ $schema = \call_user_func($callable, $this);
+
+ return $schema;
+ }
+
+ /**
+ * @param string $type
+ *
+ * @return bool
+ */
+ protected function hasProviderMapping(string $type): bool
+ {
+ if (parent::hasProviderMapping($type)) {
+ return true;
+ }
+
+ foreach ($this->getParentClassesAndInterfaces($type) as $class) {
+ if (parent::hasProviderMapping($class)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param string $type
+ *
+ * @return mixed
+ */
+ protected function getProviderMapping(string $type)
+ {
+ if (parent::hasProviderMapping($type)) {
+ return parent::getProviderMapping($type);
+ }
+
+ foreach ($this->getParentClassesAndInterfaces($type) as $class) {
+ if (parent::hasProviderMapping($class)) {
+ return parent::getProviderMapping($class);
+ }
+ }
+ throw new InvalidArgumentException(_('Cannot find schema for type `%s`', $type));
+ }
+
+ private function getParentClassesAndInterfaces(string $type): array
+ {
+ return class_exists($type) ? @class_parents($type) + @class_implements($type) : [];
+ }
+}
diff --git a/lib/classes/JsonApi/Middlewares/Auth/HttpBasicAuthStrategy.php b/lib/classes/JsonApi/Middlewares/Auth/HttpBasicAuthStrategy.php
index 57faceb..42b18ae 100644
--- a/lib/classes/JsonApi/Middlewares/Auth/HttpBasicAuthStrategy.php
+++ b/lib/classes/JsonApi/Middlewares/Auth/HttpBasicAuthStrategy.php
@@ -2,15 +2,24 @@
namespace JsonApi\Middlewares\Auth;
-use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
class HttpBasicAuthStrategy implements Strategy
{
- protected $user;
+ /** @var callable */
+ protected $authenticator;
+ /** @var Request */
protected $request;
+ /** @var ?\User */
+ protected $user;
+
+ /**
+ * @param Request $request
+ * @param callable $authenticator
+ */
public function __construct(Request $request, $authenticator)
{
$this->request = $request;
diff --git a/lib/classes/JsonApi/Middlewares/Auth/OAuth1Strategy.php b/lib/classes/JsonApi/Middlewares/Auth/OAuth1Strategy.php
index 9d465ec..113ee09 100644
--- a/lib/classes/JsonApi/Middlewares/Auth/OAuth1Strategy.php
+++ b/lib/classes/JsonApi/Middlewares/Auth/OAuth1Strategy.php
@@ -2,15 +2,23 @@
namespace JsonApi\Middlewares\Auth;
-use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
class OAuth1Strategy implements Strategy
{
- protected $user;
+ /** @var callable */
+ protected $authenticator;
+ /** @var Request */
protected $request;
+ /** @var ?\User */
+ protected $user;
+
+ /**
+ * @param callable $authenticator
+ */
public function __construct(Request $request, $authenticator)
{
$this->request = $request;
@@ -40,7 +48,7 @@ class OAuth1Strategy implements Strategy
return $response; //->withHeader('WWW-Authenticate', sprintf('Basic realm="%s"', 'Stud.IP JSON-API'));
}
- private function detect()
+ private function detect(): ?\User
{
if (!\OAuthRequestVerifier::requestIsSigned()) {
return null;
@@ -75,10 +83,11 @@ class OAuth1Strategy implements Strategy
return null;
}
+ /** @var \User */
return \User::find($userId);
}
- private function getParamsFromAuthorizationHeader(Request $request, array $params)
+ private function getParamsFromAuthorizationHeader(Request $request, array $params): array
{
if ($request->hasHeader('Authorization')) {
$auth = $request->getHeaderLine('Authorization');
diff --git a/lib/classes/JsonApi/Middlewares/Auth/SessionStrategy.php b/lib/classes/JsonApi/Middlewares/Auth/SessionStrategy.php
index 101b172..26c0bc2 100644
--- a/lib/classes/JsonApi/Middlewares/Auth/SessionStrategy.php
+++ b/lib/classes/JsonApi/Middlewares/Auth/SessionStrategy.php
@@ -6,6 +6,7 @@ use Psr\Http\Message\ResponseInterface as Response;
class SessionStrategy implements Strategy
{
+ /** @var ?\User */
protected $user;
public function check()
@@ -22,7 +23,8 @@ class SessionStrategy implements Strategy
return $this->user;
}
- $isAuthenticated = isset($GLOBALS['auth']) && $GLOBALS['auth']->is_authenticated() && 'nobody' !== $GLOBALS['user']->id;
+ $isAuthenticated =
+ isset($GLOBALS['auth']) && $GLOBALS['auth']->is_authenticated() && 'nobody' !== $GLOBALS['user']->id;
if ($isAuthenticated) {
$this->user = $GLOBALS['user']->getAuthenticatedUser();
diff --git a/lib/classes/JsonApi/Middlewares/Auth/Strategy.php b/lib/classes/JsonApi/Middlewares/Auth/Strategy.php
index 69c92e5..6b26cedc 100644
--- a/lib/classes/JsonApi/Middlewares/Auth/Strategy.php
+++ b/lib/classes/JsonApi/Middlewares/Auth/Strategy.php
@@ -16,16 +16,16 @@ interface Strategy
/**
* Get the currently authenticated user.
*
- * @return \User|null
+ * @return ?\User
*/
public function user();
/**
* Validate a user's credentials.
*
- * @param array $credentials
+ * @param Response $response the current response
*
- * @return bool
+ * @return Response the new response containing the challenge
*/
public function addChallenge(Response $response);
}
diff --git a/lib/classes/JsonApi/Middlewares/Authentication.php b/lib/classes/JsonApi/Middlewares/Authentication.php
index 1608524..3e4ee17 100644
--- a/lib/classes/JsonApi/Middlewares/Authentication.php
+++ b/lib/classes/JsonApi/Middlewares/Authentication.php
@@ -2,18 +2,11 @@
namespace JsonApi\Middlewares;
+use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
-use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
+use Slim\Psr7\Response;
-/**
- * Diese Klasse ist eine "leere" Middleware, die noch implementiert
- * werden muss.
- *
- * Allerdings wird sie jetzt schon in \JsonApi\RouteMap
- * verwendet, um dort die autorisierten Routen abzusichern.
- *
- * @todo muss zu einem späteren Zeitpunk implementiert werden
- */
class Authentication
{
// der Schlüssel des Request-Attributs, in dem der Stud.IP-Nutzer
@@ -24,14 +17,16 @@ class Authentication
// a callable accepting two arguments username and password and
// returning either null or a Stud.IP user object
+ /** @var callable */
private $authenticator;
/**
* Der Konstruktor.
*
- * @param callable $authenticator ein Callable, das den
- * Nutzernamen und das Passwort als Argumente erhält und damit
- * entweder einen Stud.IP-User-Objekt oder null zurückgibt
+ * @param callable $authenticator ein Callable, das den Nutzernamen und
+ * das Passwort als Argumente erhält und
+ * damit entweder einen Stud.IP-User-Objekt
+ * oder null zurückgibt
*/
public function __construct($authenticator)
{
@@ -41,17 +36,14 @@ class Authentication
/**
* Hier muss die Autorisierung implementiert werden.
*
- * @param \Psr\Http\Message\ServerRequestInterface $request das
- * PSR-7 Request-Objekt
- * @param \Psr\Http\Message\ResponseInterface $response das PSR-7
- * Response-Objekt
- * @param callable $next das nächste Middleware-Callable
+ * @param Request $request das Request-Objekt
+ * @param RequestHandler $handler der PSR-15 Request Handler
*
- * @return \Psr\Http\Message\ResponseInterface das neue Response-Objekt
+ * @return ResponseInterface das neue Response-Objekt
*
* @SuppressWarnings(PHPMD.Superglobals)
*/
- public function __invoke(Request $request, Response $response, $next)
+ public function __invoke(Request $request, RequestHandler $handler)
{
$guards = [
new Auth\SessionStrategy(),
@@ -63,17 +55,17 @@ class Authentication
if ($guard->check()) {
$request = $this->provideUser($request, $guard->user());
- return $next($request, $response);
+ return $handler->handle($request);
}
}
- return $this->generateChallenges($response, $guards);
+ return $this->generateChallenges($guards);
}
// according to RFC 2616
- private function generateChallenges(Response $response, array $guards)
+ private function generateChallenges(array $guards): Response
{
- $response = $response->withStatus(401);
+ $response = new Response(401);
foreach ($guards as $guard) {
$response = $guard->addChallenge($response);
@@ -85,10 +77,10 @@ class Authentication
/**
* @SuppressWarnings(PHPMD.Superglobals)
*/
- private function provideUser(Request $request, \User $user)
+ private function provideUser(Request $request, \User $user): Request
{
if ('nobody' === $GLOBALS['user']->id) {
- $GLOBALS['user'] = new \Seminar_User($user->id);
+ $GLOBALS['user'] = new \Seminar_User($user);
$GLOBALS['auth'] = new \Seminar_Auth();
$GLOBALS['auth']->auth = [
'uid' => $user->id,
diff --git a/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php b/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php
index 4695242..8ff7880 100644
--- a/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php
+++ b/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php
@@ -2,31 +2,30 @@
namespace JsonApi\Middlewares;
+use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
-use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
+use Slim\Psr7\Response;
/**
* TODO.
*/
class DangerousRouteHandler
{
-
/**
* TODO.
*
- * @param \Psr\Http\Message\ServerRequestInterface $request das
- * PSR-7 Request-Objekt
- * @param \Psr\Http\Message\ResponseInterface $response das PSR-7
- * Response-Objekt
- * @param callable $next das nächste Middleware-Callable
+ * @param Request $request das Request-Objekt
+ * @param RequestHandler $handler der PSR-15 Request Handler
*
- * @return \Psr\Http\Message\ResponseInterface die neue Response
+ * @return ResponseInterface das neue Response-Objekt
*/
- public function __invoke(Request $request, Response $response, $next)
+ public function __invoke(Request $request, RequestHandler $handler)
{
if (\Config::get()->getValue('JSONAPI_DANGEROUS_ROUTES_ALLOWED')) {
- return $next($request, $response);
+ return $handler->handle($request);
}
+ $response = new Response();
return $response->withStatus(503)->write('Service Unavailable.');
}
diff --git a/lib/classes/JsonApi/Middlewares/JsonApi.php b/lib/classes/JsonApi/Middlewares/JsonApi.php
deleted file mode 100644
index cfc9024..0000000
--- a/lib/classes/JsonApi/Middlewares/JsonApi.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-namespace JsonApi\Middlewares;
-
-use JsonApi\Errors\JsonApiExceptionHandler;
-use JsonApi\Providers\JsonApiConfig as JsonApiConfigProvider;
-use JsonApi\Providers\JsonApiServices as JsonApiServiceProvider;
-use Psr\Http\Message\ServerRequestInterface as Request;
-use Psr\Http\Message\ResponseInterface as Response;
-
-/**
- * Diese Middleware sorgt dafür, dass alle von ihr versorgten
- * (JSON-API-)Routen auf die entsprechend benötigten JSON-API-Services
- * zugreifen können. Außerdem sorgt sie dafür, dass ein
- * JSON-API-spezifischer Exception-Handler registriert wird.
- */
-class JsonApi
-{
- /**
- * Der Konstruktor.
- *
- * @param \Slim\App $app die Slim-Applikation
- */
- public function __construct($app)
- {
- $this->app = $app;
- }
-
- /**
- * Hier wird der Dependency Container mit JSON-API-spezifischen
- * Services befüllt und ein JSON-API-spezifischer
- * Exception-Handler registriert.
- *
- * @param \Psr\Http\Message\ServerRequestInterface $request das
- * PSR-7 Request-Objekt
- * @param \Psr\Http\Message\ResponseInterface $response das PSR-7
- * Response-Objekt
- * @param callable $next das nächste Middleware-Callable
- *
- * @return \Psr\Http\Message\ResponseInterface die neue Response
- */
- public function __invoke(Request $request, Response $response, $next)
- {
- $container = $this->app->getContainer();
-
- $container->register(new JsonApiConfigProvider());
- $container->register(new JsonApiServiceProvider());
-
- $this->registerExceptionHandler($container);
-
- // TODO: wie kriegt man das hier korrekt hin?
- $request->registerMediaTypeParser(
- 'application/vnd.api+json',
- function ($input) {
- return json_decode($input, true);
- }
- );
-
- $response = $next($request, $response);
-
- return $response;
- }
-
- /**
- * Register exception handler.
- */
- private function registerExceptionHandler($container)
- {
- $previousHandler = null;
- if ($container['errorHandler']) {
- $previousHandler = $container['errorHandler'];
- }
-
- unset($container['errorHandler']);
-
- $container['errorHandler'] = function ($container) use ($previousHandler) {
- return new JsonApiExceptionHandler($container, $previousHandler);
- };
- }
-}
diff --git a/lib/classes/JsonApi/Middlewares/RemoveTrailingSlashes.php b/lib/classes/JsonApi/Middlewares/RemoveTrailingSlashes.php
index fb3d24a..3a16702 100644
--- a/lib/classes/JsonApi/Middlewares/RemoveTrailingSlashes.php
+++ b/lib/classes/JsonApi/Middlewares/RemoveTrailingSlashes.php
@@ -2,8 +2,10 @@
namespace JsonApi\Middlewares;
+use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
-use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
+use Slim\Psr7\Response;
/**
* Diese Klasse definiert eine Middleware, die Requests umleitet,
@@ -18,26 +20,35 @@ class RemoveTrailingSlashes
* delegiert, sondern eine Response mit `Location`-Header also
* einem Redirect zurückgegeben.
*
- * @param \Psr\Http\Message\ServerRequestInterface $request das
- * PSR-7 Request-Objekt
- * @param \Psr\Http\Message\ResponseInterface $response das PSR-7
- * Response-Objekt
- * @param callable $next das nächste Middleware-Callable
+ * @param Request $request das Request-Objekt
+ * @param RequestHandler $handler der PSR-15 Request Handler
*
- * @return \Psr\Http\Message\ResponseInterface die neue Response
+ * @return ResponseInterface das neue Response-Objekt
*/
- public function __invoke(Request $request, Response $response, $next)
+ public function __invoke(Request $request, RequestHandler $handler)
{
$uri = $request->getUri();
$path = $uri->getPath();
- if ($path != '/' && substr($path, -1) == '/') {
+
+ if ('/' != $path && '/' == substr($path, -1)) {
+ // recursively remove slashes when its more than 1 slash
+ $path = rtrim($path, '/');
+
// permanently redirect paths with a trailing slash
// to their non-trailing counterpart
- $uri = $uri->withPath(substr($path, 0, -1));
+ $uri = $uri->withPath($path);
+
+ if ('GET' == $request->getMethod()) {
+ $response = new Response();
- return $response->withRedirect((string) $uri, 301);
+ return $response
+ ->withHeader('Location', (string) $uri)
+ ->withStatus(301);
+ } else {
+ $request = $request->withUri($uri);
+ }
}
- return $next($request, $response);
+ return $handler->handle($request);
}
}
diff --git a/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php b/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
index 72911ea..0bce8a4 100644
--- a/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
+++ b/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
@@ -2,8 +2,9 @@
namespace JsonApi\Middlewares;
+use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
-use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class DummyNavigation extends \Navigation implements \ArrayAccess
{
@@ -56,10 +57,16 @@ class DummyNavigation extends \Navigation implements \ArrayAccess
class StudipMockNavigation
{
- public function __invoke(Request $request, Response $response, $next)
+ /**
+ * @param Request $request das PSR-7 Request-Objekt
+ * @param RequestHandlerInterface $handler das PSR-7 Response-Objekt
+ *
+ * @return ResponseInterface die neue Response
+ */
+ public function __invoke(Request $request, RequestHandler $handler)
{
\Navigation::setRootNavigation(new DummyNavigation('stuff'));
- return $next($request, $response);
+ return $handler->handle($request);
}
}
diff --git a/lib/classes/JsonApi/Models/Studip.php b/lib/classes/JsonApi/Models/Studip.php
index 7e28263..ce5fa1c 100644
--- a/lib/classes/JsonApi/Models/Studip.php
+++ b/lib/classes/JsonApi/Models/Studip.php
@@ -4,13 +4,6 @@ namespace JsonApi\Models;
class Studip
{
- private $container;
-
- public function __construct($container)
- {
- $this->container = $container;
- }
-
public function getId()
{
return 'studip';
diff --git a/lib/classes/JsonApi/NonJsonApiController.php b/lib/classes/JsonApi/NonJsonApiController.php
index cf91ec5..8384b54 100644
--- a/lib/classes/JsonApi/NonJsonApiController.php
+++ b/lib/classes/JsonApi/NonJsonApiController.php
@@ -4,7 +4,8 @@ namespace JsonApi;
use JsonApi\Errors\InternalServerError;
use JsonApi\Middlewares\Authentication;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface as SchemaContainerInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
use Neomerx\JsonApi\Exceptions\JsonApiException;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface as Response;
@@ -15,38 +16,55 @@ use Psr\Http\Message\ServerRequestInterface as Request;
*/
class NonJsonApiController
{
+ /** @var \Psr\Container\ContainerInterface */
+ protected $container;
+
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
- public function __invoke(Request $request, Response $response, $args)
+ /**
+ * @return \Psr\Http\Message\ResponseInterface
+ */
+ public function __invoke(Request $request, Response $response, array $args)
{
try {
$response = $this->invoke($request, $response, $args);
} catch (JsonApiException $exception) {
$httpCode = $exception->getHttpCode();
$errors = $exception->getErrors();
- $reason = count($errors) ? $errors[0]->getId() : '';
+ $reason = count($errors) ? $errors[0]->getTitle() ?? '' : '';
- $response = $response->withStatus($httpCode)->write($reason);
+ $response->getBody()->write($reason);
+ $response = $response->withStatus($httpCode);
}
return $response;
}
- public function invoke(Request $request, Response $response, $args)
+ public function invoke(Request $request, Response $response, array $args): Response
{
throw new InternalServerError();
}
- protected function getUser($request)
+ /**
+ * @return mixed
+ */
+ protected function getUser(Request $request)
{
return $request->getAttribute(Authentication::USER_KEY, null);
}
- protected function getSchema($resource)
+ /**
+ * Gibt das Schema zu einer beliebigen Ressource zurück.
+ *
+ * @param mixed $resource die Ressource, zu der das Schema geliefert werden soll
+ *
+ * @return SchemaInterface das Schema zur Ressource
+ */
+ protected function getSchema($resource): SchemaInterface
{
- return $this->container[SchemaContainerInterface::class]->getSchema($resource);
+ return $this->container->get(SchemaContainerInterface::class)->getSchema($resource);
}
}
diff --git a/lib/classes/JsonApi/Providers/JsonApiConfig.php b/lib/classes/JsonApi/Providers/JsonApiConfig.php
deleted file mode 100644
index 3a8e93a..0000000
--- a/lib/classes/JsonApi/Providers/JsonApiConfig.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-namespace JsonApi\Providers;
-
-/**
- * Diese Klasse konfiguriert die JSON-API in der Slim-Applikation um
- * die Zuordnung von Schemata zu Stud.IP-Model-Klassen und setzt das
- * URL-Prefix für die interne Generierung von URIs.
- */
-class JsonApiConfig implements \Pimple\ServiceProviderInterface
-{
- /** Config key for schema list */
- const SCHEMAS = 'json-api-integration-schemas';
-
- /** Config key for URL prefix that will be added to all document links which have $treatAsHref flag set to false */
- const JSON_URL_PREFIX = 'json-api-integration-urlPrefix';
-
- /**
- * Diese Methode wird automatisch aufgerufen, wenn diese Klasse dem
- * Dependency Container der Slim-Applikation hinzugefügt wird.
- *
- * Hier werden die Schema-Abbildungen und das JSON-API-URL-Präfix gesetzt.
- *
- * @param \Pimple\Container $container der Dependency Container
- */
- public function register(\Pimple\Container $container)
- {
- $container[self::SCHEMAS] = new \JsonApi\SchemaMap();
- $container[self::JSON_URL_PREFIX] = rtrim(\URLHelper::getUrl('jsonapi.php/v1'), '/');
- }
-}
diff --git a/lib/classes/JsonApi/Providers/JsonApiServices.php b/lib/classes/JsonApi/Providers/JsonApiServices.php
deleted file mode 100644
index 15b9eed..0000000
--- a/lib/classes/JsonApi/Providers/JsonApiServices.php
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-
-namespace JsonApi\Providers;
-
-use JsonApi\Contracts\JsonApiPlugin;
-use JsonApi\JsonApiIntegration\Factory;
-use JsonApi\JsonApiIntegration\Responses;
-use JsonApi\Providers\JsonApiConfig as C;
-use Neomerx\JsonApi\Contracts\Codec\CodecMatcherInterface;
-use Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface;
-use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\HeadersCheckerInterface;
-use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
-use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
-use Neomerx\JsonApi\Encoder\EncoderOptions;
-use Neomerx\JsonApi\Http\Headers\MediaType;
-use Neomerx\JsonApi\Http\Headers\SupportedExtensions;
-use Neomerx\JsonApi\Decoders\ArrayDecoder;
-
-class JsonApiServices implements \Pimple\ServiceProviderInterface
-{
- /**
- * @SuppressWarnings(PHPMD.ShortVariable)
- */
- public function register(\Pimple\Container $container)
- {
- // register factory
- $container[FactoryInterface::class] = function ($c) {
- $factory = new Factory();
-
- $factory->setDependencyInjectionContainer(new \Pimple\Psr11\Container($c));
-
- if ($c->has('logger')) {
- $factory->setLogger($c['logger']);
- }
-
- return $factory;
- };
-
- // register schemas
- $container[ContainerInterface::class] = function ($c) {
- $schemas = isset($c[C::SCHEMAS]) ? $c[C::SCHEMAS] : [];
- $schemaContainer = $c[FactoryInterface::class]->createContainer($schemas);
-
- $pluginSchemas = \PluginEngine::sendMessage(JsonApiPlugin::class, 'registerSchemas', $schemaContainer);
- if (is_array($pluginSchemas) && count($pluginSchemas)) {
- foreach ($pluginSchemas as $arrayOfSchemas) {
- $schemaContainer->registerArray($arrayOfSchemas);
- }
- }
-
- return $schemaContainer;
- };
-
- // register codec matcher
- $container[CodecMatcherInterface::class] = function ($c) {
- return $this->createCodecMatcher($c);
- };
-
- // TODO wo wird das gebraucht
- $container[HeadersCheckerInterface::class] = function ($c) {
- return $c[FactoryInterface::class]->createHeadersChecker($c[CodecMatcherInterface::class]);
- };
-
- // register query params
- $container[EncodingParametersInterface::class] = function ($c) {
- return $c[FactoryInterface::class]->createQueryParametersParser()->parse($c['request']);
- };
-
- $container[HeaderParametersInterface::class] = function ($c) {
- return $c[FactoryInterface::class]->createHeaderParametersParser()->parse($c['request']);
- };
-
- // register responses
- $container[ResponsesInterface::class] = function ($c) {
- return $this->createResponses($c);
- };
- }
-
- /**
- * @param ContainerInterface $container
- *
- * @return ResponsesInterface
- */
- protected function createResponses($container)
- {
- $codecMatcher = $container[CodecMatcherInterface::class];
- $parameters = $container[EncodingParametersInterface::class];
- $params = $container[HeaderParametersInterface::class];
-
- $codecMatcher->matchEncoder($params->getAcceptHeader());
- $encoder = $codecMatcher->getEncoder();
-
- $schemaContainer = $container[ContainerInterface::class];
- $urlPrefix = $container[C::JSON_URL_PREFIX];
-
- $responses = new Responses(
- new MediaType(MediaTypeInterface::JSON_API_TYPE, MediaTypeInterface::JSON_API_SUB_TYPE),
- new SupportedExtensions(),
- $encoder,
- $schemaContainer,
- $parameters,
- $urlPrefix
- );
-
- return $responses;
- }
-
- /**
- * @param ContainerInterface $schemaContainer
- *
- * @return CodecMatcherInterface
- */
- protected function createCodecMatcher($container)
- {
- $factory = $container[FactoryInterface::class];
- $schemaContainer = $container[ContainerInterface::class];
-
- $encoderOptions = new EncoderOptions(0, $container[C::JSON_URL_PREFIX]);
-
- $decoderClosure = $this->getDecoderClosure();
- $encoderClosure = $this->getEncoderClosure($factory, $schemaContainer, $encoderOptions);
- $codecMatcher = $factory->createCodecMatcher();
- $jsonApiType = $factory->createMediaType(
- MediaTypeInterface::JSON_API_TYPE,
- MediaTypeInterface::JSON_API_SUB_TYPE
- );
- $jsonApiTypeUtf8 = $factory->createMediaType(
- MediaTypeInterface::JSON_API_TYPE,
- MediaTypeInterface::JSON_API_SUB_TYPE,
- ['charset' => 'UTF-8']
- );
- $codecMatcher->registerEncoder($jsonApiType, $encoderClosure);
- $codecMatcher->registerDecoder($jsonApiType, $decoderClosure);
- $codecMatcher->registerEncoder($jsonApiTypeUtf8, $encoderClosure);
- $codecMatcher->registerDecoder($jsonApiTypeUtf8, $decoderClosure);
-
- return $codecMatcher;
- }
-
- /**
- * @return Closure
- */
- protected function getDecoderClosure()
- {
- return function () {
- return new ArrayDecoder();
- };
- }
-
- /**
- * @param FactoryInterface $factory
- * @param ContainerInterface $container
- * @param EncoderOptions $encoderOptions
- *
- * @return Closure
- */
- private function getEncoderClosure(
- FactoryInterface $factory,
- ContainerInterface $container,
- EncoderOptions $encoderOptions
- ) {
- return function () use ($factory, $container, $encoderOptions) {
- return $factory->createEncoder($container, $encoderOptions);
- };
- }
-}
diff --git a/lib/classes/JsonApi/Providers/StudipConfig.php b/lib/classes/JsonApi/Providers/StudipConfig.php
deleted file mode 100644
index 99b3f7e..0000000
--- a/lib/classes/JsonApi/Providers/StudipConfig.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-namespace JsonApi\Providers;
-
-/**
- * Diese Klasse konfiguriert die JSON-API in der Slim-Applikation um
- * die Zuordnung von Schemata zu Stud.IP-Model-Klassen und setzt das
- * URL-Prefix für die interne Generierung von URIs.
- */
-class StudipConfig implements \Pimple\ServiceProviderInterface
-{
- /**
- * Diese Methode wird automatisch aufgerufen, wenn diese Klasse dem
- * Dependency Container der Slim-Applikation hinzugefügt wird.
- *
- * Hier werden die Schema-Abbildungen und das JSON-API-URL-Präfix gesetzt.
- *
- * @param \Pimple\Container $container der Dependency Container
- *
- * @SuppressWarnings(PHPMD.Superglobals)
- */
- public function register(\Pimple\Container $container)
- {
- $container['studip-system-object'] = function () {
- return new \JsonApi\Models\Studip($container);
- };
-
- $container['studip-current-user'] = function () {
- if ($user = $GLOBALS['user']) {
- return $user->getAuthenticatedUser();
- }
-
- return null;
- };
- }
-}
diff --git a/lib/classes/JsonApi/Providers/StudipServices.php b/lib/classes/JsonApi/Providers/StudipServices.php
deleted file mode 100644
index 57def54..0000000
--- a/lib/classes/JsonApi/Providers/StudipServices.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-namespace JsonApi\Providers;
-
-use StudipAuthAbstract;
-use User;
-
-/**
- * Diese Klasse stellt Stud.IP-Spezifika zum Beispiel für die
- * Authentifizierung zur Verfügung.
- */
-class StudipServices implements \Pimple\ServiceProviderInterface
-{
- /**
- * Schlüssel für den Stud.IP-Authentifizierungservice.
- */
- const AUTHENTICATOR = 'studip-authenticator';
-
- /**
- * Diese Methode wird automatisch aufgerufen, wenn diese Klasse dem
- * Dependency Container der Slim-Applikation hinzugefügt wird.
- *
- * Hier werden die Stud.IP-Spezifika gesetzt
- *
- * @param \Pimple\Container $container der Dependency Container
- */
- public function register(\Pimple\Container $container)
- {
- $container[self::AUTHENTICATOR] = function ($c) {
- return function ($username, $password) {
- $check = StudipAuthAbstract::CheckAuthentication($username, $password);
-
- if ($check['uid'] && $check['uid'] != 'nobody') {
- return User::find($check['uid']);
- }
-
- return null;
- };
- };
- }
-}
diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php
index b91c698..a258b10 100644
--- a/lib/classes/JsonApi/RouteMap.php
+++ b/lib/classes/JsonApi/RouteMap.php
@@ -7,7 +7,7 @@ use JsonApi\Middlewares\Authentication;
use JsonApi\Middlewares\DangerousRouteHandler;
use JsonApi\Middlewares\JsonApi as JsonApiMiddleware;
use JsonApi\Middlewares\StudipMockNavigation;
-use JsonApi\Providers\StudipServices;
+use Slim\Routing\RouteCollectorProxy;
/**
* Diese Klasse ist die JSON-API-Routemap, in der alle Routen
@@ -48,7 +48,6 @@ use JsonApi\Providers\StudipServices;
*
* $this->app->post('/article/{id}/comments', MeineRoute::class);
*
- *
* @see \JsonApi\Middlewares\JsonApi
* @see \JsonApi\Middlewares\Authentication
* @see \JsonApi\Contracts\JsonApiPlugin
@@ -58,6 +57,9 @@ use JsonApi\Providers\StudipServices;
*/
class RouteMap
{
+ /** @var \Slim\App */
+ private $app;
+
/**
* Der Konstruktor.
*
@@ -76,40 +78,12 @@ class RouteMap
* RouteMap::authenticatedRoutes eingetragen. Routen ohne
* Autorisierung werden in RouteMap::unauthenticatedRoutes vermerkt.
*/
- public function __invoke()
+ public function __invoke(RouteCollectorProxy $group): void
{
- $corsOrigin = \Config::get()->getValue('JSONAPI_CORS_ORIGIN');
- if (is_array($corsOrigin) && count($corsOrigin)) {
- $this->app->add(
- new \Tuupola\Middleware\Cors(
- [
- 'origin' => $corsOrigin,
- 'methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
- 'headers.allow' => [
- 'Accept',
- 'Accept-Encoding',
- 'Accept-Language',
- 'Authorization',
- 'Content-Type',
- 'Origin',
- ],
- 'headers.expose' => ['Etag'],
- 'credentials' => true,
- 'cache' => 86400,
- ]
- )
- );
- }
-
- $this->app->add(new JsonApiMiddleware($this->app));
-
- $this->app->add(new StudipMockNavigation());
-
- $this->app->group('', [$this, 'authenticatedRoutes'])
- ->add(new Authentication($this->getAuthenticator()));
- $this->app->group('', [$this, 'unauthenticatedRoutes']);
-
- $this->app->get('/discovery', Routes\DiscoveryIndex::class);
+ $group->group('', [$this, 'authenticatedRoutes'])->add(new Authentication($this->getAuthenticator()));
+ $group->group('', [$this, 'unauthenticatedRoutes']);
+
+ $group->get('/discovery', Routes\DiscoveryIndex::class);
}
/**
@@ -117,44 +91,43 @@ class RouteMap
* Außerdem wird über die \PluginEngine allen JsonApiPlugins die
* Möglichkeit gegeben, sich hier einzutragen.
*/
- public function authenticatedRoutes()
+ public function authenticatedRoutes(RouteCollectorProxy $group): void
{
\PluginEngine::sendMessage(JsonApiPlugin::class, 'registerAuthenticatedRoutes', $this->app);
- $this->app->get('/users', Routes\Users\UsersIndex::class);
- $this->app->get('/users/me', Routes\Users\UsersShow::class);
- $this->app->get('/users/{id}', Routes\Users\UsersShow::class);
- $this->app->delete('/users/{id}', Routes\Users\UsersDelete::class)->add(DangerousRouteHandler::class);
-
- $this->app->get('/users/{id}/activitystream', Routes\ActivityStreamShow::class);
- $this->app->get('/users/{id}/institute-memberships', Routes\InstituteMemberships\ByUserIndex::class);
- $this->app->get('/users/{id}/course-memberships', Routes\CourseMemberships\ByUserIndex::class);
- $this->app->get('/course-memberships/{id}', Routes\CourseMemberships\CourseMembershipsShow::class);
- $this->app->patch('/course-memberships/{id}', Routes\CourseMemberships\CourseMembershipsUpdate::class);
-
- $this->app->get('/users/{id}/schedule', Routes\Schedule\UserScheduleShow::class)->setName('get-schedule');
- $this->app->get('/schedule-entries/{id}', Routes\Schedule\ScheduleEntriesShow::class);
- $this->app->get('/seminar-cycle-dates/{id}', Routes\Schedule\SeminarCycleDatesShow::class);
-
- $this->app->get('/users/{id}/config-values', Routes\ConfigValues\ByUserIndex::class);
- $this->app->get('/config-values/{id}', Routes\ConfigValues\ConfigValuesShow::class);
- $this->app->patch('/config-values/{id}', Routes\ConfigValues\ConfigValuesUpdate::class);
-
-
- $this->addAuthenticatedBlubberRoutes();
-// $this->addAuthenticatedConsultationRoutes();
- $this->addAuthenticatedContactsRoutes();
- $this->addAuthenticatedCoursesRoutes();
- $this->addAuthenticatedCoursewareRoutes();
- $this->addAuthenticatedEventsRoutes();
- $this->addAuthenticatedFeedbackRoutes();
- $this->addAuthenticatedFilesRoutes();
- $this->addAuthenticatedForumRoutes();
- $this->addAuthenticatedInstitutesRoutes();
- $this->addAuthenticatedMessagesRoutes();
- $this->addAuthenticatedNewsRoutes();
- $this->addAuthenticatedStudyAreasRoutes();
- $this->addAuthenticatedWikiRoutes();
+ $group->get('/users', Routes\Users\UsersIndex::class);
+ $group->get('/users/me', Routes\Users\UsersShow::class)->setName('get-myself');
+ $group->get('/users/{id}', Routes\Users\UsersShow::class);
+ $group->delete('/users/{id}', Routes\Users\UsersDelete::class)->add(DangerousRouteHandler::class);
+
+ $group->get('/users/{id}/activitystream', Routes\ActivityStreamShow::class);
+ $group->get('/users/{id}/institute-memberships', Routes\InstituteMemberships\ByUserIndex::class);
+ $group->get('/users/{id}/course-memberships', Routes\CourseMemberships\ByUserIndex::class);
+ $group->get('/course-memberships/{id}', Routes\CourseMemberships\CourseMembershipsShow::class);
+ $group->patch('/course-memberships/{id}', Routes\CourseMemberships\CourseMembershipsUpdate::class);
+
+ $group->get('/users/{id}/schedule', Routes\Schedule\UserScheduleShow::class)->setName('get-schedule');
+ $group->get('/schedule-entries/{id}', Routes\Schedule\ScheduleEntriesShow::class);
+ $group->get('/seminar-cycle-dates/{id}', Routes\Schedule\SeminarCycleDatesShow::class);
+
+ $group->get('/users/{id}/config-values', Routes\ConfigValues\ByUserIndex::class);
+ $group->get('/config-values/{id}', Routes\ConfigValues\ConfigValuesShow::class);
+ $group->patch('/config-values/{id}', Routes\ConfigValues\ConfigValuesUpdate::class);
+
+ $this->addAuthenticatedBlubberRoutes($group);
+ // $this->addAuthenticatedConsultationRoutes($group);
+ $this->addAuthenticatedContactsRoutes($group);
+ $this->addAuthenticatedCoursesRoutes($group);
+ $this->addAuthenticatedCoursewareRoutes($group);
+ $this->addAuthenticatedEventsRoutes($group);
+ $this->addAuthenticatedFeedbackRoutes($group);
+ $this->addAuthenticatedFilesRoutes($group);
+ $this->addAuthenticatedForumRoutes($group);
+ $this->addAuthenticatedInstitutesRoutes($group);
+ $this->addAuthenticatedMessagesRoutes($group);
+ $this->addAuthenticatedNewsRoutes($group);
+ $this->addAuthenticatedStudyAreasRoutes($group);
+ $this->addAuthenticatedWikiRoutes($group);
}
/**
@@ -162,341 +135,357 @@ class RouteMap
* Außerdem wird über die \PluginEngine allen JsonApiPlugins die
* Möglichkeit gegeben, sich hier einzutragen.
*/
- public function unauthenticatedRoutes()
+ public function unauthenticatedRoutes(RouteCollectorProxy $group): void
{
- \PluginEngine::sendMessage(JsonApiPlugin::class, 'registerUnauthenticatedRoutes', $this->app);
+ \PluginEngine::sendMessage(JsonApiPlugin::class, 'registerUnauthenticatedRoutes', $group);
- $this->app->get('/semesters', Routes\SemestersIndex::class);
- $this->app->get('/semesters/{id}', Routes\SemestersShow::class);
+ $group->get('/semesters', Routes\SemestersIndex::class);
+ $group->get('/semesters/{id}', Routes\SemestersShow::class)->setName('get-semester');
- $this->app->get('/studip/properties', Routes\Studip\PropertiesIndex::class);
+ $group->get('/studip/properties', Routes\Studip\PropertiesIndex::class);
}
- private function getAuthenticator()
+ private function getAuthenticator(): callable
{
- $container = $this->app->getContainer();
-
- return $container[StudipServices::AUTHENTICATOR];
+ return $this->app->getContainer()->get('studip-authenticator');
}
- private function addAuthenticatedBlubberRoutes()
+ private function addAuthenticatedBlubberRoutes(RouteCollectorProxy $group): void
{
// find BlubberThreads
- $this->app->get('/courses/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)
- ->setArgument('type', 'course');
- $this->app->get('/institutes/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)
- ->setArgument('type', 'institute');
- $this->app->get('/studip/blubber-threads', Routes\Blubber\ThreadsIndex::class)
- ->setArgument('type', 'public');
- $this->app->get('/users/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)
- ->setArgument('type', 'private');
- $this->app->get('/blubber-threads', Routes\Blubber\ThreadsIndex::class)
- ->setArgument('type', 'all');
- $this->app->get('/blubber-threads/{id}', Routes\Blubber\ThreadsShow::class);
+ $group->get('/courses/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)->setArgument('type', 'course');
+ $group
+ ->get('/institutes/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)
+ ->setArgument('type', 'institute');
+ $group->get('/studip/blubber-threads', Routes\Blubber\ThreadsIndex::class)->setArgument('type', 'public');
+ $group->get('/users/{id}/blubber-threads', Routes\Blubber\ThreadsIndex::class)->setArgument('type', 'private');
+ $group->get('/blubber-threads', Routes\Blubber\ThreadsIndex::class)->setArgument('type', 'all');
+ $group->get('/blubber-threads/{id}', Routes\Blubber\ThreadsShow::class);
// create, read, update and delete BlubberComments
- $this->app->get('/blubber-threads/{id}/comments', Routes\Blubber\CommentsByThreadIndex::class);
- $this->app->post('/blubber-threads/{id}/comments', Routes\Blubber\CommentsCreate::class);
- $this->app->get('/blubber-comments', Routes\Blubber\CommentsIndex::class);
- $this->app->get('/blubber-comments/{id}', Routes\Blubber\CommentsShow::class);
- $this->app->patch('/blubber-comments/{id}', Routes\Blubber\CommentsUpdate::class);
- $this->app->delete('/blubber-comments/{id}', Routes\Blubber\CommentsDelete::class);
+ $group->get('/blubber-threads/{id}/comments', Routes\Blubber\CommentsByThreadIndex::class);
+ $group->post('/blubber-threads/{id}/comments', Routes\Blubber\CommentsCreate::class);
+ $group->get('/blubber-comments', Routes\Blubber\CommentsIndex::class);
+ $group->get('/blubber-comments/{id}', Routes\Blubber\CommentsShow::class);
+ $group->patch('/blubber-comments/{id}', Routes\Blubber\CommentsUpdate::class);
+ $group->delete('/blubber-comments/{id}', Routes\Blubber\CommentsDelete::class);
// REL mentions
- $this->addRelationship('/blubber-threads/{id}/relationships/mentions', Routes\Blubber\Rel\Mentions::class);
+ $this->addRelationship(
+ $group,
+ '/blubber-threads/{id}/relationships/mentions',
+ Routes\Blubber\Rel\Mentions::class
+ );
}
- private function addAuthenticatedConsultationRoutes()
+ private function addAuthenticatedConsultationRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/users/{id}/consultations', Routes\Consultations\BlocksByUserIndex::class);
-
- $this->app->get('/consultation-blocks/{id}', Routes\Consultations\BlockShow::class);
- $this->app->get('/consultation-blocks/{id}/slots', Routes\Consultations\SlotsByBlockIndex::class);
+ $group->get('/users/{id}/consultations', Routes\Consultations\BlocksByUserIndex::class);
- $this->app->get('/consultation-slots/{id}', Routes\Consultations\SlotShow::class);
- $this->app->get('/consultation-slots/{id}/bookings', Routes\Consultations\BookingsBySlotIndex::class);
- $this->app->post('/consultation-slots/{id}/bookings', Routes\Consultations\BookingsCreate::class);
+ $group->get('/consultation-blocks/{id}', Routes\Consultations\BlockShow::class);
+ $group->get('/consultation-blocks/{id}/slots', Routes\Consultations\SlotsByBlockIndex::class);
- $this->app->get('/consultation-bookings/{id}', Routes\Consultations\BookingsShow::class);
- $this->app->delete('/consultation-bookings/{id}', Routes\Consultations\BookingsDelete::class);
+ $group->get('/consultation-slots/{id}', Routes\Consultations\SlotShow::class);
+ $group->get('/consultation-slots/{id}/bookings', Routes\Consultations\BookingsBySlotIndex::class);
+ $group->post('/consultation-slots/{id}/bookings', Routes\Consultations\BookingsCreate::class);
-// $this->addRelationship('/users/{id}/relationships/contacts', Routes\Users\Rel\Contacts::class);
+ $group->get('/consultation-bookings/{id}', Routes\Consultations\BookingsShow::class);
+ $group->delete('/consultation-bookings/{id}', Routes\Consultations\BookingsDelete::class);
}
- private function addAuthenticatedContactsRoutes()
+ private function addAuthenticatedContactsRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/users/{id}/contacts', Routes\Users\ContactsIndex::class);
- $this->addRelationship('/users/{id}/relationships/contacts', Routes\Users\Rel\Contacts::class);
+ $group->get('/users/{id}/contacts', Routes\Users\ContactsIndex::class);
+ $this->addRelationship($group, '/users/{id}/relationships/contacts', Routes\Users\Rel\Contacts::class);
}
- private function addAuthenticatedEventsRoutes()
+ private function addAuthenticatedEventsRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/courses/{id}/events', Routes\Events\CourseEventsIndex::class);
- $this->app->get('/users/{id}/events', Routes\Events\UserEventsIndex::class);
+ $group->get('/courses/{id}/events', Routes\Events\CourseEventsIndex::class);
+ $group->get('/users/{id}/events', Routes\Events\UserEventsIndex::class);
// not a JSON:API route
- $this->app->get('/users/{id}/events.ics', Routes\Events\UserEventsIcal::class);
+ $group->get('/users/{id}/events.ics', Routes\Events\UserEventsIcal::class);
}
- private function addAuthenticatedFeedbackRoutes()
+ private function addAuthenticatedFeedbackRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/feedback-elements/{id}', Routes\Feedback\FeedbackElementsShow::class);
- $this->app->get('/feedback-elements/{id}/entries', Routes\Feedback\FeedbackEntriesIndex::class);
- $this->app->get('/courses/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByCourseIndex::class);
- $this->app->get('/file-refs/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByFileRefIndex::class);
- $this->app->get('/folders/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByFolderIndex::class);
+ $group->get('/feedback-elements/{id}', Routes\Feedback\FeedbackElementsShow::class);
+ $group->get('/feedback-elements/{id}/entries', Routes\Feedback\FeedbackEntriesIndex::class);
+ $group->get('/courses/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByCourseIndex::class);
+ $group->get('/file-refs/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByFileRefIndex::class);
+ $group->get('/folders/{id}/feedback-elements', Routes\Feedback\FeedbackElementsByFolderIndex::class);
- $this->app->get('/feedback-entries/{id}', Routes\Feedback\FeedbackEntriesShow::class);
+ $group->get('/feedback-entries/{id}', Routes\Feedback\FeedbackEntriesShow::class);
}
- private function addAuthenticatedInstitutesRoutes()
+ private function addAuthenticatedInstitutesRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/institute-memberships/{id}', Routes\InstituteMemberships\InstituteMembershipsShow::class);
- $this->app->get('/institutes/{id}', Routes\Institutes\InstitutesShow::class);
- $this->app->get('/institutes', Routes\Institutes\InstitutesIndex::class);
+ $group->get('/institute-memberships/{id}', Routes\InstituteMemberships\InstituteMembershipsShow::class);
+ $group->get('/institutes/{id}', Routes\Institutes\InstitutesShow::class);
+ $group->get('/institutes', Routes\Institutes\InstitutesIndex::class);
- $this->app->get('/institutes/{id}/status-groups', Routes\Institutes\StatusGroupsOfInstitutes::class);
+ $group->get('/institutes/{id}/status-groups', Routes\Institutes\StatusGroupsOfInstitutes::class);
}
- private function addAuthenticatedNewsRoutes()
+ private function addAuthenticatedNewsRoutes(RouteCollectorProxy $group): void
{
- $this->app->post('/courses/{id}/news', Routes\News\CourseNewsCreate::class);
- $this->app->post('/users/{id}/news', Routes\News\UserNewsCreate::class);
- $this->app->post('/news', Routes\News\StudipNewsCreate::class);
- $this->app->post('/news/{id}/comments', Routes\News\CommentCreate::class);
- $this->app->patch('/news/{id}', Routes\News\NewsUpdate::class);
- $this->app->get('/news/{id}', Routes\News\NewsShow::class);
- $this->app->get('/courses/{id}/news', Routes\News\ByCourseIndex::class);
- $this->app->get('/users/{id}/news', Routes\News\ByUserIndex::class);
- $this->app->get('/news/{id}/comments', Routes\News\CommentsIndex::class);
- $this->app->get('/news', Routes\News\ByCurrentUser::class);
- $this->app->get('/studip/news', Routes\News\GlobalNewsShow::class);
- $this->app->delete('/news/{id}', Routes\News\NewsDelete::class);
- $this->app->delete('/comments/{id}', Routes\News\CommentsDelete::class);
+ $group->post('/courses/{id}/news', Routes\News\CourseNewsCreate::class);
+ $group->post('/users/{id}/news', Routes\News\UserNewsCreate::class);
+ $group->post('/news', Routes\News\StudipNewsCreate::class);
+ $group->post('/news/{id}/comments', Routes\News\CommentCreate::class);
+ $group->patch('/news/{id}', Routes\News\NewsUpdate::class);
+ $group->get('/news/{id}', Routes\News\NewsShow::class);
+ $group->get('/courses/{id}/news', Routes\News\ByCourseIndex::class);
+ $group->get('/users/{id}/news', Routes\News\ByUserIndex::class);
+ $group->get('/news/{id}/comments', Routes\News\CommentsIndex::class);
+ $group->get('/news', Routes\News\ByCurrentUser::class);
+ $group->get('/studip/news', Routes\News\GlobalNewsShow::class);
+ $group->delete('/news/{id}', Routes\News\NewsDelete::class);
+ $group->delete('/comments/{id}', Routes\News\CommentsDelete::class);
// RELATIONSHIP: 'ranges'
- $this->addRelationship('/news/{id}/relationships/ranges', Routes\News\Rel\Ranges::class);
+ $this->addRelationship($group, '/news/{id}/relationships/ranges', Routes\News\Rel\Ranges::class);
}
- private function addAuthenticatedStudyAreasRoutes()
+ private function addAuthenticatedStudyAreasRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/study-areas', Routes\StudyAreas\StudyAreasIndex::class);
- $this->app->get('/study-areas/{id}', Routes\StudyAreas\StudyAreasShow::class);
+ $group->get('/study-areas', Routes\StudyAreas\StudyAreasIndex::class);
+ $group->get('/study-areas/{id}', Routes\StudyAreas\StudyAreasShow::class);
- $this->app->get('/study-areas/{id}/children', Routes\StudyAreas\ChildrenOfStudyAreas::class);
- $this->app->get('/study-areas/{id}/courses', Routes\StudyAreas\CoursesOfStudyAreas::class);
- $this->app->get('/study-areas/{id}/institute', Routes\StudyAreas\InstituteOfStudyAreas::class);
- $this->app->get('/study-areas/{id}/parent', Routes\StudyAreas\ParentOfStudyAreas::class);
+ $group->get('/study-areas/{id}/children', Routes\StudyAreas\ChildrenOfStudyAreas::class);
+ $group->get('/study-areas/{id}/courses', Routes\StudyAreas\CoursesOfStudyAreas::class);
+ $group->get('/study-areas/{id}/institute', Routes\StudyAreas\InstituteOfStudyAreas::class);
+ $group->get('/study-areas/{id}/parent', Routes\StudyAreas\ParentOfStudyAreas::class);
}
- private function addAuthenticatedWikiRoutes()
+ private function addAuthenticatedWikiRoutes(RouteCollectorProxy $group): void
{
- $this->addRelationship('/wiki-pages/{id:.+}/relationships/parent', Routes\Wiki\Rel\ParentPage::class);
- $this->app->get('/wiki-pages/{id:.+}/children', Routes\Wiki\ChildrenIndex::class);
- $this->app->get('/wiki-pages/{id:.+}/descendants', Routes\Wiki\DescendantsIndex::class);
+ $this->addRelationship($group, '/wiki-pages/{id:.+}/relationships/parent', Routes\Wiki\Rel\ParentPage::class);
+ $group->get('/wiki-pages/{id:.+}/children', Routes\Wiki\ChildrenIndex::class);
+ $group->get('/wiki-pages/{id:.+}/descendants', Routes\Wiki\DescendantsIndex::class);
- $this->app->get('/courses/{id}/wiki-pages', Routes\Wiki\WikiIndex::class);
- $this->app->get('/wiki-pages/{id:.+}', Routes\Wiki\WikiShow::class)->setName('get-wiki-page');
+ $group->get('/courses/{id}/wiki-pages', Routes\Wiki\WikiIndex::class);
+ $group->get('/wiki-pages/{id:.+}', Routes\Wiki\WikiShow::class)->setName('get-wiki-page');
- $this->app->post('/courses/{id}/wiki-pages', Routes\Wiki\WikiCreate::class);
- $this->app->patch('/wiki-pages/{id:.+}', Routes\Wiki\WikiUpdate::class);
- $this->app->delete('/wiki-pages/{id:.+}', Routes\Wiki\WikiDelete::class);
+ $group->post('/courses/{id}/wiki-pages', Routes\Wiki\WikiCreate::class);
+ $group->patch('/wiki-pages/{id:.+}', Routes\Wiki\WikiUpdate::class);
+ $group->delete('/wiki-pages/{id:.+}', Routes\Wiki\WikiDelete::class);
}
- private function addAuthenticatedCoursesRoutes()
+ private function addAuthenticatedCoursesRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/courses', Routes\Courses\CoursesIndex::class);
- $this->app->get('/courses/{id}', Routes\Courses\CoursesShow::class);
+ $group->get('/courses', Routes\Courses\CoursesIndex::class);
+ $group->get('/courses/{id}', Routes\Courses\CoursesShow::class);
- $this->app->get('/users/{id}/courses', Routes\Courses\CoursesByUserIndex::class);
+ $group->get('/users/{id}/courses', Routes\Courses\CoursesByUserIndex::class);
- $this->app->get('/courses/{id}/memberships', Routes\Courses\CoursesMembershipsIndex::class);
- $this->addRelationship('/courses/{id}/relationships/memberships', Routes\Courses\Rel\Memberships::class);
+ $group->get('/courses/{id}/memberships', Routes\Courses\CoursesMembershipsIndex::class);
+ $this->addRelationship(
+ $group,
+ '/courses/{id}/relationships/memberships',
+ Routes\Courses\Rel\Memberships::class
+ );
- $this->app->get('/courses/{id}/status-groups', Routes\Courses\StatusGroupsOfCourses::class);
+ $group->get('/courses/{id}/status-groups', Routes\Courses\StatusGroupsOfCourses::class);
- $this->app->get('/sem-classes', Routes\Courses\SemClassesIndex::class);
- $this->app->get('/sem-classes/{id}', Routes\Courses\SemClassesShow::class);
- $this->app->get('/sem-classes/{id}/sem-types', Routes\Courses\SemTypesBySemClassIndex::class);
- $this->app->get('/sem-types', Routes\Courses\SemTypesIndex::class);
- $this->app->get('/sem-types/{id}', Routes\Courses\SemTypesShow::class);
+ $group->get('/sem-classes', Routes\Courses\SemClassesIndex::class);
+ $group->get('/sem-classes/{id}', Routes\Courses\SemClassesShow::class);
+ $group->get('/sem-classes/{id}/sem-types', Routes\Courses\SemTypesBySemClassIndex::class);
+ $group->get('/sem-types', Routes\Courses\SemTypesIndex::class);
+ $group->get('/sem-types/{id}', Routes\Courses\SemTypesShow::class);
}
- private function addAuthenticatedCoursewareRoutes()
+ private function addAuthenticatedCoursewareRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/{type:courses|users}/{id}/courseware', Routes\Courseware\CoursewareInstancesShow::class);
- $this->app->patch('/courseware-instances/{id}', Routes\Courseware\CoursewareInstancesUpdate::class);
+ $group->get('/{type:courses|users}/{id}/courseware', Routes\Courseware\CoursewareInstancesShow::class);
+ $group->patch('/courseware-instances/{id}', Routes\Courseware\CoursewareInstancesUpdate::class);
$this->addRelationship(
+ $group,
'/courseware-instances/{id}/relationships/bookmarks',
Routes\Courseware\Rel\BookmarkedStructuralElements::class
);
- $this->app->get(
- '/courseware-instances/{id}/bookmarks',
- Routes\Courseware\BookmarkedStructuralElementsIndex::class
- );
+ $group->get('/courseware-instances/{id}/bookmarks', Routes\Courseware\BookmarkedStructuralElementsIndex::class);
- $this->app->get('/courseware-blocks/{id}', Routes\Courseware\BlocksShow::class);
- $this->app->post('/courseware-blocks', Routes\Courseware\BlocksCreate::class);
- $this->app->patch('/courseware-blocks/{id}', Routes\Courseware\BlocksUpdate::class);
- $this->app->delete('/courseware-blocks/{id}', Routes\Courseware\BlocksDelete::class);
+ $group->get('/courseware-blocks/{id}', Routes\Courseware\BlocksShow::class);
+ $group->post('/courseware-blocks', Routes\Courseware\BlocksCreate::class);
+ $group->patch('/courseware-blocks/{id}', Routes\Courseware\BlocksUpdate::class);
+ $group->delete('/courseware-blocks/{id}', Routes\Courseware\BlocksDelete::class);
$this->addRelationship(
+ $group,
'/courseware-blocks/{id}/relationships/edit-blocker',
Routes\Courseware\Rel\BlocksEditBlocker::class
);
$this->addRelationship(
+ $group,
'/courseware-blocks/{id}/relationships/file-refs',
Routes\Courseware\Rel\BlocksFilerefs::class
);
- $this->app->get('/courseware-blocks/{id}/file-refs', Routes\Courseware\BlocksListFiles::class);
+ $group->get('/courseware-blocks/{id}/file-refs', Routes\Courseware\BlocksListFiles::class);
// not a JSON route
- $this->app->post('/courseware-blocks/{id}/copy', Routes\Courseware\BlocksCopy::class);
+ $group->post('/courseware-blocks/{id}/copy', Routes\Courseware\BlocksCopy::class);
- $this->app->get('/courseware-containers/{id}', Routes\Courseware\ContainersShow::class);
- $this->app->post('/courseware-containers', Routes\Courseware\ContainersCreate::class);
- $this->app->patch('/courseware-containers/{id}', Routes\Courseware\ContainersUpdate::class);
- $this->app->delete('/courseware-containers/{id}', Routes\Courseware\ContainersDelete::class);
- $this->app->get('/courseware-containers/{id}/blocks', Routes\Courseware\BlocksIndex::class);
+ $group->get('/courseware-containers/{id}', Routes\Courseware\ContainersShow::class);
+ $group->post('/courseware-containers', Routes\Courseware\ContainersCreate::class);
+ $group->patch('/courseware-containers/{id}', Routes\Courseware\ContainersUpdate::class);
+ $group->delete('/courseware-containers/{id}', Routes\Courseware\ContainersDelete::class);
+ $group->get('/courseware-containers/{id}/blocks', Routes\Courseware\BlocksIndex::class);
$this->addRelationship(
+ $group,
'/courseware-containers/{id}/relationships/blocks',
Routes\Courseware\Rel\ContainersBlocks::class
);
$this->addRelationship(
+ $group,
'/courseware-containers/{id}/relationships/edit-blocker',
Routes\Courseware\Rel\ContainersEditBlocker::class
);
// not a JSON route
- $this->app->post('/courseware-containers/{id}/copy', Routes\Courseware\ContainersCopy::class);
+ $group->post('/courseware-containers/{id}/copy', Routes\Courseware\ContainersCopy::class);
- $this->app->get('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsShow::class);
- $this->app->get('/courseware-structural-elements', Routes\Courseware\StructuralElementsIndex::class);
- $this->app->post('/courseware-structural-elements', Routes\Courseware\StructuralElementsCreate::class);
- $this->app->patch('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsUpdate::class);
- $this->app->delete('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsDelete::class);
+ $group->get('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsShow::class);
+ $group->get('/courseware-structural-elements', Routes\Courseware\StructuralElementsIndex::class);
+ $group->post('/courseware-structural-elements', Routes\Courseware\StructuralElementsCreate::class);
+ $group->patch('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsUpdate::class);
+ $group->delete('/courseware-structural-elements/{id}', Routes\Courseware\StructuralElementsDelete::class);
- $this->app->get(
+ $group->get(
'/courseware-structural-elements/{id}/children',
Routes\Courseware\ChildrenOfStructuralElementsIndex::class
);
- $this->app->get('/courseware-structural-elements/{id}/containers', Routes\Courseware\ContainersIndex::class);
+ $group->get('/courseware-structural-elements/{id}/containers', Routes\Courseware\ContainersIndex::class);
$this->addRelationship(
+ $group,
'/courseware-structural-elements/{id}/relationships/containers',
Routes\Courseware\Rel\StructuralElementsContainers::class
);
$this->addRelationship(
+ $group,
'/courseware-structural-elements/{id}/relationships/children',
Routes\Courseware\Rel\StructuralElementsChildren::class
);
- $this->app->get(
+ $group->get(
'/courseware-structural-elements/{id}/descendants',
Routes\Courseware\DescendantsOfStructuralElementsIndex::class
);
$this->addRelationship(
+ $group,
'/courseware-structural-elements/{id}/relationships/edit-blocker',
Routes\Courseware\Rel\StructuralElementsEditBlocker::class
);
- $this->app->post('/courseware-structural-elements/{id}/image', Routes\Courseware\StructuralElementsImageUpload::class);
- $this->app->delete('/courseware-structural-elements/{id}/image', Routes\Courseware\StructuralElementsImageDelete::class);
+ $group->post(
+ '/courseware-structural-elements/{id}/image',
+ Routes\Courseware\StructuralElementsImageUpload::class
+ );
+ $group->delete(
+ '/courseware-structural-elements/{id}/image',
+ Routes\Courseware\StructuralElementsImageDelete::class
+ );
// not a JSON route
- $this->app->post('/courseware-structural-elements/{id}/copy', Routes\Courseware\StructuralElementsCopy::class);
+ $group->post('/courseware-structural-elements/{id}/copy', Routes\Courseware\StructuralElementsCopy::class);
- $this->app->get('/courseware-blocks/{id}/user-data-field', Routes\Courseware\UserDataFieldOfBlocksShow::class);
- $this->app->get('/courseware-user-data-fields/{id}', Routes\Courseware\UserDataFieldsShow::class);
- $this->app->patch('/courseware-user-data-fields/{id}', Routes\Courseware\UserDataFieldsUpdate::class);
+ $group->get('/courseware-blocks/{id}/user-data-field', Routes\Courseware\UserDataFieldOfBlocksShow::class);
+ $group->get('/courseware-user-data-fields/{id}', Routes\Courseware\UserDataFieldsShow::class);
+ $group->patch('/courseware-user-data-fields/{id}', Routes\Courseware\UserDataFieldsUpdate::class);
- $this->app->get('/courseware-blocks/{id}/user-progress', Routes\Courseware\UserProgressOfBlocksShow::class);
- $this->app->get('/courseware-user-progresses/{id}', Routes\Courseware\UserProgressesShow::class);
- $this->app->patch('/courseware-user-progresses/{id}', Routes\Courseware\UserProgressesUpdate::class);
+ $group->get('/courseware-blocks/{id}/user-progress', Routes\Courseware\UserProgressOfBlocksShow::class);
+ $group->get('/courseware-user-progresses/{id}', Routes\Courseware\UserProgressesShow::class);
+ $group->patch('/courseware-user-progresses/{id}', Routes\Courseware\UserProgressesUpdate::class);
- $this->app->get('/courseware-blocks/{id}/comments', Routes\Courseware\BlockCommentsOfBlocksIndex::class);
- $this->app->post('/courseware-block-comments', Routes\Courseware\BlockCommentsCreate::class);
- $this->app->get('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsShow::class);
- $this->app->patch('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsUpdate::class);
- $this->app->delete('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsDelete::class);
+ $group->get('/courseware-blocks/{id}/comments', Routes\Courseware\BlockCommentsOfBlocksIndex::class);
+ $group->post('/courseware-block-comments', Routes\Courseware\BlockCommentsCreate::class);
+ $group->get('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsShow::class);
+ $group->patch('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsUpdate::class);
+ $group->delete('/courseware-block-comments/{id}', Routes\Courseware\BlockCommentsDelete::class);
- $this->app->get('/courseware-blocks/{id}/feedback', Routes\Courseware\BlockFeedbacksOfBlocksIndex::class);
- $this->app->post('/courseware-block-feedback', Routes\Courseware\BlockFeedbacksCreate::class);
- $this->app->get('/courseware-block-feedback/{id}', Routes\Courseware\BlockFeedbacksShow::class);
+ $group->get('/courseware-blocks/{id}/feedback', Routes\Courseware\BlockFeedbacksOfBlocksIndex::class);
+ $group->post('/courseware-block-feedback', Routes\Courseware\BlockFeedbacksCreate::class);
+ $group->get('/courseware-block-feedback/{id}', Routes\Courseware\BlockFeedbacksShow::class);
}
- private function addAuthenticatedFilesRoutes()
+ private function addAuthenticatedFilesRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/terms-of-use', Routes\Files\TermsOfUseIndex::class);
- $this->app->get('/terms-of-use/{id}', Routes\Files\TermsOfUseShow::class);
+ $group->get('/terms-of-use', Routes\Files\TermsOfUseIndex::class);
+ $group->get('/terms-of-use/{id}', Routes\Files\TermsOfUseShow::class);
- $this->app->get('/{type:courses|institutes|users}/{id}/file-refs', Routes\Files\RangeFileRefsIndex::class);
- $this->app->get('/{type:courses|institutes|users}/{id}/folders', Routes\Files\RangeFoldersIndex::class);
+ $group->get('/{type:courses|institutes|users}/{id}/file-refs', Routes\Files\RangeFileRefsIndex::class);
+ $group->get('/{type:courses|institutes|users}/{id}/folders', Routes\Files\RangeFoldersIndex::class);
- $this->app->post('/{type:courses|institutes|users}/{id}/folders', Routes\Files\RangeFoldersCreate::class);
+ $group->post('/{type:courses|institutes|users}/{id}/folders', Routes\Files\RangeFoldersCreate::class);
- $this->app->get('/file-refs/{id}', Routes\Files\FileRefsShow::class);
- $this->app->patch('/file-refs/{id}', Routes\Files\FileRefsUpdate::class);
- $this->app->delete('/file-refs/{id}', Routes\Files\FileRefsDelete::class);
- $this->addRelationship('/file-refs/{id}/relationships/terms-of-use', Routes\Files\Rel\TermsOfFileRef::class);
+ $group->get('/file-refs/{id}', Routes\Files\FileRefsShow::class);
+ $group->patch('/file-refs/{id}', Routes\Files\FileRefsUpdate::class);
+ $group->delete('/file-refs/{id}', Routes\Files\FileRefsDelete::class);
+ $this->addRelationship(
+ $group,
+ '/file-refs/{id}/relationships/terms-of-use',
+ Routes\Files\Rel\TermsOfFileRef::class
+ );
- $this->app->map(['HEAD'], '/file-refs/{id}/content', Routes\Files\FileRefsContentHead::class);
- $this->app->get('/file-refs/{id}/content', Routes\Files\FileRefsContentShow::class);
- $this->app->post('/file-refs/{id}/content', Routes\Files\FileRefsContentUpdate::class);
+ $group->map(['HEAD'], '/file-refs/{id}/content', Routes\Files\FileRefsContentHead::class);
+ $group->get('/file-refs/{id}/content', Routes\Files\FileRefsContentShow::class);
+ $group->post('/file-refs/{id}/content', Routes\Files\FileRefsContentUpdate::class);
- $this->app->get('/folders/{id}', Routes\Files\FoldersShow::class);
- $this->app->patch('/folders/{id}', Routes\Files\FoldersUpdate::class);
- $this->app->delete('/folders/{id}', Routes\Files\FoldersDelete::class);
+ $group->get('/folders/{id}', Routes\Files\FoldersShow::class);
+ $group->patch('/folders/{id}', Routes\Files\FoldersUpdate::class);
+ $group->delete('/folders/{id}', Routes\Files\FoldersDelete::class);
// not a JSON route
- $this->app->post('/folders/{id}/copy', Routes\Files\FoldersCopy::class);
+ $group->post('/folders/{id}/copy', Routes\Files\FoldersCopy::class);
- $this->app->get('/folders/{id}/file-refs', Routes\Files\SubfilerefsIndex::class);
- $this->app->get('/folders/{id}/folders', Routes\Files\SubfoldersIndex::class);
+ $group->get('/folders/{id}/file-refs', Routes\Files\SubfilerefsIndex::class);
+ $group->get('/folders/{id}/folders', Routes\Files\SubfoldersIndex::class);
- $this->app->post('/folders/{id}/file-refs', Routes\Files\NegotiateFileRefsCreate::class);
- $this->app->post('/folders/{id}/folders', Routes\Files\SubfoldersCreate::class);
+ $group->post('/folders/{id}/file-refs', Routes\Files\NegotiateFileRefsCreate::class);
+ $group->post('/folders/{id}/folders', Routes\Files\SubfoldersCreate::class);
- $this->app->get('/files/{id}', Routes\Files\FilesShow::class);
- $this->app->get('/files/{id}/file-refs', Routes\Files\FileRefsOfFilesShow::class);
- $this->addRelationship('/files/{id}/relationships/file-refs', Routes\Files\Rel\FileRefsOfFile::class);
+ $group->get('/files/{id}', Routes\Files\FilesShow::class);
+ $group->get('/files/{id}/file-refs', Routes\Files\FileRefsOfFilesShow::class);
+ $this->addRelationship($group, '/files/{id}/relationships/file-refs', Routes\Files\Rel\FileRefsOfFile::class);
}
- private function addAuthenticatedMessagesRoutes()
+ private function addAuthenticatedMessagesRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/users/{id}/inbox', Routes\Messages\InboxShow::class);
+ $group->get('/users/{id}/inbox', Routes\Messages\InboxShow::class);
- $this->app->get('/users/{id}/outbox', Routes\Messages\OutboxShow::class);
+ $group->get('/users/{id}/outbox', Routes\Messages\OutboxShow::class);
- $this->app->post('/messages', Routes\Messages\MessageCreate::class);
- $this->app->get('/messages/{id}', Routes\Messages\MessageShow::class);
- $this->app->patch('/messages/{id}', Routes\Messages\MessageUpdate::class);
- $this->app->delete('/messages/{id}', Routes\Messages\MessageDelete::class);
+ $group->post('/messages', Routes\Messages\MessageCreate::class);
+ $group->get('/messages/{id}', Routes\Messages\MessageShow::class);
+ $group->patch('/messages/{id}', Routes\Messages\MessageUpdate::class);
+ $group->delete('/messages/{id}', Routes\Messages\MessageDelete::class);
}
- private function addAuthenticatedForumRoutes()
+ private function addAuthenticatedForumRoutes(RouteCollectorProxy $group): void
{
- $this->app->get('/courses/{id}/forum-categories', Routes\Forum\ForumCategoriesIndex::class);
+ $group->get('/courses/{id}/forum-categories', Routes\Forum\ForumCategoriesIndex::class);
- $this->app->get('/forum-entries/{id}', Routes\Forum\ForumEntriesShow::class);
- $this->app->get('/forum-entries/{id}/entries', Routes\Forum\ForumEntryEntriesIndex::class);
+ $group->get('/forum-entries/{id}', Routes\Forum\ForumEntriesShow::class);
+ $group->get('/forum-entries/{id}/entries', Routes\Forum\ForumEntryEntriesIndex::class);
- $this->app->get('/forum-categories/{id}', Routes\Forum\ForumCategoriesShow::class);
+ $group->get('/forum-categories/{id}', Routes\Forum\ForumCategoriesShow::class);
- $this->app->get('/forum-categories/{id}/entries', Routes\Forum\ForumCategoryEntriesIndex::class);
+ $group->get('/forum-categories/{id}/entries', Routes\Forum\ForumCategoryEntriesIndex::class);
- $this->app->post('/forum-entries/{id}/entries', Routes\Forum\ForumEntryEntriesCreate::class);
- $this->app->post('/forum-categories/{id}/entries', Routes\Forum\ForumCategoryEntriesCreate::class);
- $this->app->post('/courses/{id}/forum-categories', Routes\Forum\ForumCategoriesCreate::class);
+ $group->post('/forum-entries/{id}/entries', Routes\Forum\ForumEntryEntriesCreate::class);
+ $group->post('/forum-categories/{id}/entries', Routes\Forum\ForumCategoryEntriesCreate::class);
+ $group->post('/courses/{id}/forum-categories', Routes\Forum\ForumCategoriesCreate::class);
- $this->app->patch('/forum-categories/{id}', Routes\Forum\ForumCategoriesUpdate::class);
- $this->app->patch('/forum-entries/{id}', Routes\Forum\ForumEntriesUpdate::class);
+ $group->patch('/forum-categories/{id}', Routes\Forum\ForumCategoriesUpdate::class);
+ $group->patch('/forum-entries/{id}', Routes\Forum\ForumEntriesUpdate::class);
- $this->app->delete('/forum-categories/{id}', Routes\Forum\ForumCategoriesDelete::class);
- $this->app->delete('/forum-entries/{id}', Routes\Forum\ForumEntriesDelete::class);
+ $group->delete('/forum-categories/{id}', Routes\Forum\ForumCategoriesDelete::class);
+ $group->delete('/forum-entries/{id}', Routes\Forum\ForumEntriesDelete::class);
}
- private function addRelationship($url, $handler)
+ private function addRelationship(RouteCollectorProxy $group, string $url, string $handler): void
{
- $this->app->map(['GET', 'PATCH', 'POST', 'DELETE'], $url, $handler);
+ $group->map(['GET', 'PATCH', 'POST', 'DELETE'], $url, $handler);
}
}
diff --git a/lib/classes/JsonApi/Routes/ActivityStreamShow.php b/lib/classes/JsonApi/Routes/ActivityStreamShow.php
index 1d889cc..2a1a557 100644
--- a/lib/classes/JsonApi/Routes/ActivityStreamShow.php
+++ b/lib/classes/JsonApi/Routes/ActivityStreamShow.php
@@ -14,7 +14,7 @@ use Studip\Activity\InstituteContext;
use Studip\Activity\Stream;
use Studip\Activity\UserContext;
-function canShowActivityStream(\User $observer, $userId)
+function canShowActivityStream(\User $observer, string $userId): bool
{
if (!$GLOBALS['perm']->have_perm('root', $observer->id)) {
return true;
@@ -31,7 +31,7 @@ class ActivityStreamShow extends JsonApiController
protected $allowedPagingParameters = ['offset', 'limit'];
- public function __invoke(Request $request, Response $response, $args)
+ public function __invoke(Request $request, Response $response, array $args): Response
{
if (!canShowActivityStream($this->getUser($request), $userId = $args['id'])) {
throw new AuthorizationFailedException();
@@ -41,28 +41,18 @@ class ActivityStreamShow extends JsonApiController
throw new RecordNotFoundException();
}
- $urlFilter = $this->getUrlFilter($request);
+ $urlFilter = $this->getUrlFilter();
+ /** @var \User $user */
$contexts = $this->createContexts($user);
$filter = $this->createFilter($urlFilter);
try {
- if (!$stream = $this->createStream($contexts, $filter)) {
- $data = [];
- $total = 0;
- } else {
- list($offset, $limit) = $this->getOffsetAndLimit();
- $total = count($stream);
- $data = array_slice($stream->getIterator()->getArrayCopy(), $offset, $limit);
- }
+ $stream = $this->createStream($contexts, $filter);
+ list($offset, $limit) = $this->getOffsetAndLimit();
+ $total = count($stream);
+ $data = array_slice($stream->getIterator()->getArrayCopy(), $offset, $limit);
} catch (\Exception $exception) {
- $error = new \Neomerx\JsonApi\Document\Error(
- 'internal-server-error',
- null,
- 500,
- 'internal-server-error',
- $exception->getMessage()
- );
- throw new \Neomerx\JsonApi\Exceptions\JsonApiException($error, 500);
+ throw new \JsonApi\Errors\InternalServerError($exception->getMessage());
}
$meta = ['filter' => $urlFilter];
@@ -70,7 +60,7 @@ class ActivityStreamShow extends JsonApiController
return $this->getPaginatedContentResponse($data, $total, 200, null, $meta);
}
- private function getUrlFilter()
+ private function getUrlFilter(): array
{
$params = $this->getQueryParameters();
$filtering = $params->getFilteringParameters();
@@ -100,7 +90,7 @@ class ActivityStreamShow extends JsonApiController
return $filter;
}
- private function createContexts(\User $user)
+ private function createContexts(\User $user): array
{
$contexts = [
new SystemContext($user),
@@ -125,7 +115,7 @@ class ActivityStreamShow extends JsonApiController
return $contexts;
}
- private function createFilter($urlFilter)
+ private function createFilter(array $urlFilter): Filter
{
$filter = new Filter();
@@ -137,8 +127,6 @@ class ActivityStreamShow extends JsonApiController
$word,
[
'activity',
- // TODO: Polishing
- // 'blubber',
'documents',
'forum',
'message',
@@ -162,7 +150,7 @@ class ActivityStreamShow extends JsonApiController
return $filter;
}
- private function createStream($contexts, $filter)
+ private function createStream(array $contexts, Filter $filter): Stream
{
return new Stream($contexts, $filter);
}
diff --git a/lib/classes/JsonApi/Routes/ArrayHelperTrait.php b/lib/classes/JsonApi/Routes/ArrayHelperTrait.php
index 46ec41b..f39dabf 100644
--- a/lib/classes/JsonApi/Routes/ArrayHelperTrait.php
+++ b/lib/classes/JsonApi/Routes/ArrayHelperTrait.php
@@ -1,7 +1,5 @@
<?php
-// TODO: das gehört bestimmt nicht in Routes
-
namespace JsonApi\Routes;
trait ArrayHelperTrait
diff --git a/lib/classes/JsonApi/Routes/Blubber/FilterTrait.php b/lib/classes/JsonApi/Routes/Blubber/FilterTrait.php
index 5e12b83..1f04338 100644
--- a/lib/classes/JsonApi/Routes/Blubber/FilterTrait.php
+++ b/lib/classes/JsonApi/Routes/Blubber/FilterTrait.php
@@ -2,6 +2,8 @@
namespace JsonApi\Routes\Blubber;
+use Psr\Http\Message\ServerRequestInterface as Request;
+
trait FilterTrait
{
private function validateFilters()
@@ -21,7 +23,7 @@ trait FilterTrait
}
}
- private function getFilters()
+ private function getFilters(): array
{
$filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
diff --git a/lib/classes/JsonApi/Routes/Blubber/ThreadsIndex.php b/lib/classes/JsonApi/Routes/Blubber/ThreadsIndex.php
index 8c12031..74f4069 100644
--- a/lib/classes/JsonApi/Routes/Blubber/ThreadsIndex.php
+++ b/lib/classes/JsonApi/Routes/Blubber/ThreadsIndex.php
@@ -25,8 +25,6 @@ class ThreadsIndex extends JsonApiController
*/
public function __invoke(Request $request, Response $response, $args)
{
- $this->validateFilters();
-
$contextType = $args['type'];
if (!in_array($contextType, ['all', 'public', 'private', 'course', 'institute'])) {
throw new BadRequestException('Wrong context type.');
@@ -34,7 +32,9 @@ class ThreadsIndex extends JsonApiController
switch ($contextType) {
case 'all':
- list($threads, $total) = $this->getAllThreads($this->getUser($request));
+ $this->validateFilters();
+ $filters = $this->getFilters();
+ list($threads, $total) = $this->getAllThreads($filters, $this->getUser($request));
break;
case 'public':
@@ -57,9 +57,8 @@ class ThreadsIndex extends JsonApiController
return $this->getPaginatedContentResponse($threads, $total);
}
- private function getAllThreads(\User $observer)
+ private function getAllThreads(array $filters, \User $observer)
{
- $filters = $this->getFilters();
list($offset, $limit) = $this->getOffsetAndLimit();
$threads = \BlubberThread::findMyGlobalThreads(
diff --git a/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php b/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
index 2be3e1d..2adf6d7 100644
--- a/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
+++ b/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
@@ -34,7 +34,7 @@ class CoursesByUserIndex extends JsonApiController
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function __invoke(Request $request, Response $response, $args)
+ public function __invoke(Request $request, Response $response, array $args): Response
{
if (!$user = \User::find($args['id'])) {
throw new RecordNotFoundException();
diff --git a/lib/classes/JsonApi/Routes/DiscoveryIndex.php b/lib/classes/JsonApi/Routes/DiscoveryIndex.php
index 5323a22..e5c74b1 100644
--- a/lib/classes/JsonApi/Routes/DiscoveryIndex.php
+++ b/lib/classes/JsonApi/Routes/DiscoveryIndex.php
@@ -8,9 +8,9 @@ use JsonApi\JsonApiController;
class DiscoveryIndex extends JsonApiController
{
- public function __invoke(Request $request, Response $response, $args)
+ public function __invoke(Request $request, Response $response)
{
- $routes = $this->container->get('router')->getRoutes();
+ $routes = $this->container->get(\Slim\App::class)->getRouteCollector()->getRoutes();
return $this->getContentResponse($routes);
}
diff --git a/lib/classes/JsonApi/Routes/Events/UserEventsIcal.php b/lib/classes/JsonApi/Routes/Events/UserEventsIcal.php
index a4e6da7..2dbc4c2 100644
--- a/lib/classes/JsonApi/Routes/Events/UserEventsIcal.php
+++ b/lib/classes/JsonApi/Routes/Events/UserEventsIcal.php
@@ -31,9 +31,9 @@ class UserEventsIcal extends NonJsonApiController
}
$content = implode($export->getExport());
+ $response->getBody()->write($content);
return $response->withHeader('Content-Type', 'text/calendar')
- ->withHeader('Content-Disposition', 'attachment; '.encode_header_parameter('filename', 'studip.ics'))
- ->write($content);
+ ->withHeader('Content-Disposition', 'attachment; ' . encode_header_parameter('filename', 'studip.ics'));
}
}
diff --git a/lib/classes/JsonApi/Routes/Files/FileRefsContentHead.php b/lib/classes/JsonApi/Routes/Files/FileRefsContentHead.php
index a0343f5..93aaa95 100644
--- a/lib/classes/JsonApi/Routes/Files/FileRefsContentHead.php
+++ b/lib/classes/JsonApi/Routes/Files/FileRefsContentHead.php
@@ -12,7 +12,7 @@ class FileRefsContentHead extends NonJsonApiController
{
use EtagHelperTrait;
- public function invoke(Request $request, Response $response, $args)
+ public function invoke(Request $request, Response $response, array $args): Response
{
if (!$fileRef = \FileRef::find($args['id'])) {
throw new RecordNotFoundException();
@@ -21,7 +21,6 @@ class FileRefsContentHead extends NonJsonApiController
if (!Authority::canDownloadFileRef($this->getUser($request), $fileRef)) {
throw new AuthorizationFailedException();
}
-
list(, $response) = $this->handleEtag($request, $response, $fileRef, true);
return $response;
diff --git a/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php b/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
index 880354c..3bb00d1 100644
--- a/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
+++ b/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
@@ -12,7 +12,7 @@ class FileRefsCreateByUpload extends NonJsonApiController
{
use RoutesHelperTrait;
- public function invoke(Request $request, Response $response, $args)
+ public function invoke(Request $request, Response $response, array $args): Response
{
if (!$folder = \FileManager::getTypedFolder($args['id'])) {
throw new RecordNotFoundException();
diff --git a/lib/classes/JsonApi/Routes/Files/FoldersCopy.php b/lib/classes/JsonApi/Routes/Files/FoldersCopy.php
index 60d0f79..046fac1 100644
--- a/lib/classes/JsonApi/Routes/Files/FoldersCopy.php
+++ b/lib/classes/JsonApi/Routes/Files/FoldersCopy.php
@@ -8,7 +8,6 @@ use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\BadRequestException;
use JsonApi\Errors\RecordNotFoundException;
use JsonApi\NonJsonApiController;
-use JsonApi\Providers\JsonApiConfig as C;
class FoldersCopy extends NonJsonApiController
{
@@ -45,7 +44,7 @@ class FoldersCopy extends NonJsonApiController
{
$pathinfo = $this->getSchema($folder)->getSelfSubLink($folder)->getSubHref();
$old = \URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']);
- $url = \URLHelper::getURL($this->container->get(C::JSON_URL_PREFIX).$pathinfo, [], true);
+ $url = \URLHelper::getURL($this->container->get('json-api-integration-urlPrefix').$pathinfo, [], true);
\URLHelper::setBaseURL($old);
return $response->withRedirect($url, 201);
diff --git a/lib/classes/JsonApi/Routes/Files/NegotiateFileRefsCreate.php b/lib/classes/JsonApi/Routes/Files/NegotiateFileRefsCreate.php
index 22add9e..89e00e1 100644
--- a/lib/classes/JsonApi/Routes/Files/NegotiateFileRefsCreate.php
+++ b/lib/classes/JsonApi/Routes/Files/NegotiateFileRefsCreate.php
@@ -3,11 +3,14 @@
namespace JsonApi\Routes\Files;
use Psr\Container\ContainerInterface;
-use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
class NegotiateFileRefsCreate
{
+ /** @var ContainerInterface */
+ private $container;
+
/**
* Der Konstruktor.
*
@@ -18,13 +21,13 @@ class NegotiateFileRefsCreate
$this->container = $container;
}
- public function __invoke(Request $request, Response $response, $args)
+ public function __invoke(Request $request, Response $response, array $args): Response
{
$contentType = $request->getHeaderLine('Content-Type');
if ('multipart/form-data' === substr($contentType, 0, strlen('multipart/form-data'))) {
- $route = new FileRefsCreateByUpload($this->container);
+ $route = $this->container->get(FileRefsCreateByUpload::class);
} else {
- $route = new FileRefsCreate($this->container);
+ $route = $this->container->get(FileRefsCreate::class);
}
return $route($request, $response, $args);
diff --git a/lib/classes/JsonApi/Routes/Files/RoutesHelperTrait.php b/lib/classes/JsonApi/Routes/Files/RoutesHelperTrait.php
index 3590e14..8122ec5 100644
--- a/lib/classes/JsonApi/Routes/Files/RoutesHelperTrait.php
+++ b/lib/classes/JsonApi/Routes/Files/RoutesHelperTrait.php
@@ -4,13 +4,12 @@ namespace JsonApi\Routes\Files;
use JsonApi\Errors\BadRequestException;
use JsonApi\Errors\InternalServerError;
-use JsonApi\Providers\JsonApiConfig as C;
use JsonApi\Schemas\FileRef as FileRefSchema;
use JsonApi\Schemas\Folder as FolderSchema;
use JsonApi\Schemas\ContentTermsOfUse as ContentTermsOfUseSchema;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
-use Slim\Http\UploadedFile;
+use Slim\Psr7\UploadedFile;
trait RoutesHelperTrait
{
@@ -292,11 +291,11 @@ trait RoutesHelperTrait
*/
private function redirectToFileRef(Response $response, \FileRef $fileRef)
{
- $pathinfo = $this->getSchema($fileRef)->getSelfSubLink($fileRef)->getSubHref();
+ $pathinfo = $this->getSchema($fileRef)->getSelfLink($fileRef)->getStringRepresentation($this->container->get('json-api-integration-urlPrefix'));
$old = \URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']);
- $url = \URLHelper::getURL($this->container->get(C::JSON_URL_PREFIX).$pathinfo, [], true);
+ $url = \URLHelper::getURL($pathinfo, [], true);
\URLHelper::setBaseURL($old);
- return $response->withRedirect($url, 201);
+ return $response->withHeader('Location', $url)->withStatus(201);
}
}
diff --git a/lib/classes/JsonApi/Routes/News/Rel/Ranges.php b/lib/classes/JsonApi/Routes/News/Rel/Ranges.php
index 1ab24a4..3f90dcd 100644
--- a/lib/classes/JsonApi/Routes/News/Rel/Ranges.php
+++ b/lib/classes/JsonApi/Routes/News/Rel/Ranges.php
@@ -105,7 +105,7 @@ class Ranges extends RelationshipsController
return array_filter(
$news->news_ranges->map(function ($range) use ($types) {
if ('global' === $range->type) {
- return $this->container['studip-system-object'];
+ return $this->getGlobalRange();
} elseif (isset($types[$range->type])) {
$klass = $types[$range->type];
@@ -172,7 +172,7 @@ class Ranges extends RelationshipsController
{
switch ($type) {
case \JsonApi\Schemas\Studip::TYPE:
- return $this->container['studip-system-object'];
+ return $this->getGlobalRange();
case \JsonApi\Schemas\Course::TYPE:
return \Course::find($rangeId);
@@ -187,6 +187,11 @@ class Ranges extends RelationshipsController
return null;
}
+ private function getGlobalRange()
+ {
+ return new \JsonApi\Model\Studip();
+ }
+
private function addRanges(\StudipNews $news, array $ranges)
{
foreach ($ranges as $range) {
diff --git a/lib/classes/JsonApi/Routes/RelationshipsController.php b/lib/classes/JsonApi/Routes/RelationshipsController.php
index 1a42113..47b546c 100644
--- a/lib/classes/JsonApi/Routes/RelationshipsController.php
+++ b/lib/classes/JsonApi/Routes/RelationshipsController.php
@@ -5,7 +5,7 @@ namespace JsonApi\Routes;
use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\UnsupportedRequestError;
use JsonApi\JsonApiController;
-use Neomerx\JsonApi\Contracts\Document\DocumentInterface;
+use Neomerx\JsonApi\Contracts\Schema\DocumentInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
diff --git a/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php b/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
index 48477c6..85cf911 100644
--- a/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
+++ b/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
@@ -7,8 +7,7 @@ use JsonApi\Errors\RecordNotFoundException;
use JsonApi\JsonApiController;
use JsonApi\Models\ScheduleEntry;
use JsonApi\Routes\Users\Authority;
-use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Schema\Link;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
@@ -48,13 +47,13 @@ class UserScheduleShow extends JsonApiController
ScheduleEntry::findByUser_id($otherUser->id),
$this->getCycles($otherUser, $semester)
),
- ResponsesInterface::HTTP_OK,
+ 200,
[Link::SELF => $this->getSelfLink($otherUser, $semester)],
$this->getMeta($semester)
);
}
- private function getCycles(\User $user, \Semester $semester)
+ private function getCycles(\User $user, \Semester $semester): array
{
// get all virtually added seminars
$stmt = \DBManager::get()->prepare(
@@ -76,42 +75,41 @@ class UserScheduleShow extends JsonApiController
AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)
');
$stmt->execute([
- 'userid' => $user->id,
- 'begin' => $semester->beginn,
+ 'userid' => $user->id,
+ 'begin' => $semester->beginn,
'semester_id' => $semester->id,
]);
return array_reduce(
array_unique(array_merge($ids, $stmt->fetchFirst())),
function ($cycles, $seminarId) {
- return array_merge($cycles,
- array_filter(
- \Course::find($seminarId)->cycles->getArrayCopy(),
- function ($cycle) {
- return $cycle['is_visible'];
- }
- )
+ return array_merge(
+ $cycles,
+ array_filter(
+ \Course::find($seminarId)->cycles->getArrayCopy(),
+ function ($cycle) {
+ return $cycle['is_visible'];
+ }
+ )
);
},
[]
);
}
- private function getSelfLink($user, $semester)
+ private function getSelfLink(\User $user, \Semester $semester): Link
{
- $url = $this->container['router']->pathFor(
- 'get-schedule',
- ['id' => $user->id],
- ['filter[timestamp]' => $semester->beginn]
- );
+ $routeParser = $this->app->getRouteCollector()->getRouteParser();
+ $url = $routeParser->urlFor('get-schedule', ['id' => $user->id], ['filter[timestamp]' => $semester->beginn]);
- return new Link($url);
+ return new Link(false, $url, false);
}
- private function getMeta($semester)
+ private function getMeta(\Semester $semester): array
{
- return [
- 'semester' => $this->getResourceLocationUrl($semester),
- ];
+ $routeParser = $this->app->getRouteCollector()->getRouteParser();
+ $url = $routeParser->urlFor('get-semester', ['id' => $semester->id]);
+
+ return [ 'semester' => $url ];
}
}
diff --git a/lib/classes/JsonApi/Routes/Studip/PropertiesIndex.php b/lib/classes/JsonApi/Routes/Studip/PropertiesIndex.php
index 9ca30dc..8758446 100644
--- a/lib/classes/JsonApi/Routes/Studip/PropertiesIndex.php
+++ b/lib/classes/JsonApi/Routes/Studip/PropertiesIndex.php
@@ -16,7 +16,7 @@ class PropertiesIndex extends JsonApiController
*/
public function __invoke(Request $request, Response $response, $args)
{
- $studip = $this->container['studip-system-object'];
+ $studip = new \JsonApi\Models\Studip();
return $this->getContentResponse($studip->getProperties());
}
diff --git a/lib/classes/JsonApi/Routes/Users/UsersIndex.php b/lib/classes/JsonApi/Routes/Users/UsersIndex.php
index f430eea..1418354 100644
--- a/lib/classes/JsonApi/Routes/Users/UsersIndex.php
+++ b/lib/classes/JsonApi/Routes/Users/UsersIndex.php
@@ -26,7 +26,7 @@ class UsersIndex extends JsonApiController
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function __invoke(Request $request, Response $response, $args)
+ public function __invoke(Request $request, Response $response, $args): Response
{
if (!Authority::canIndexUsers($this->getUser($request))) {
throw new AuthorizationFailedException();
@@ -37,13 +37,17 @@ class UsersIndex extends JsonApiController
list($offset, $limit) = $this->getOffsetAndLimit();
$partSQL = \GlobalSearchUsers::getSQL($filters['search'], [], $limit + $offset);
- $users = \User::findMany(array_map(function ($array) { return $array['user_id']; }, \DBManager::get()->fetchAll($partSQL)));
+ $users = \User::findMany(
+ array_map(function ($array) {
+ return $array['user_id'];
+ }, \DBManager::get()->fetchAll($partSQL))
+ );
$total = (int) \DBManager::get()->fetchColumn('SELECT FOUND_ROWS() as found_rows');
return $this->getPaginatedContentResponse($users, $total);
}
- private function validateFilters()
+ private function validateFilters(): void
{
$filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
diff --git a/lib/classes/JsonApi/Routes/Users/UsersShow.php b/lib/classes/JsonApi/Routes/Users/UsersShow.php
index be9f1af..f22aaf3 100644
--- a/lib/classes/JsonApi/Routes/Users/UsersShow.php
+++ b/lib/classes/JsonApi/Routes/Users/UsersShow.php
@@ -2,12 +2,13 @@
namespace JsonApi\Routes\Users;
-use Psr\Http\Message\ResponseInterface as Response;
-use Psr\Http\Message\ServerRequestInterface as Request;
-use JsonApi\JsonApiController;
use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\RecordNotFoundException;
+use JsonApi\JsonApiController;
use JsonApi\Schemas\User as UserSchema;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
+use Slim\Routing\RouteContext;
class UsersShow extends JsonApiController
{
@@ -21,12 +22,18 @@ class UsersShow extends JsonApiController
UserSchema::REL_SCHEDULE,
];
- public function __invoke(Request $request, Response $response, $args)
+ /**
+ * @return \Psr\Http\Message\ResponseInterface
+ */
+ public function __invoke(Request $request, Response $response, array $args)
{
- if (isset($args['id'])) {
- $observedUser = \User::find($args['id']);
- } else {
+ $routeName = RouteContext::fromRequest($request)
+ ->getRoute()
+ ->getName();
+ if ($routeName === 'get-myself') {
$observedUser = $this->getUser($request);
+ } else {
+ $observedUser = \User::find($args['id']);
}
if (!$observedUser) {
throw new RecordNotFoundException();
diff --git a/lib/classes/JsonApi/Routes/Wiki/WikiShow.php b/lib/classes/JsonApi/Routes/Wiki/WikiShow.php
index 4c2a5c1..a01c06f 100644
--- a/lib/classes/JsonApi/Routes/Wiki/WikiShow.php
+++ b/lib/classes/JsonApi/Routes/Wiki/WikiShow.php
@@ -3,10 +3,7 @@
namespace JsonApi\Routes\Wiki;
use JsonApi\Errors\AuthorizationFailedException;
-use JsonApi\Errors\BadRequestException;
use JsonApi\JsonApiController;
-use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
-use Neomerx\JsonApi\Document\Link;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
diff --git a/lib/classes/JsonApi/SchemaMap.php b/lib/classes/JsonApi/SchemaMap.php
index 2354a0e..042ee58 100644
--- a/lib/classes/JsonApi/SchemaMap.php
+++ b/lib/classes/JsonApi/SchemaMap.php
@@ -7,58 +7,55 @@ namespace JsonApi;
*/
class SchemaMap
{
- /**
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- public function __invoke(\Slim\Container $container)
+ public function __invoke(): array
{
return [
- \Slim\Route::class => \JsonApi\Schemas\SlimRoute::class,
+ \Slim\Routing\Route::class => Schemas\SlimRoute::class,
- \JsonApi\Models\ScheduleEntry::class => \JsonApi\Schemas\ScheduleEntry::class,
+ \JsonApi\Models\ScheduleEntry::class => Schemas\ScheduleEntry::class,
- \BlubberComment::class => \JsonApi\Schemas\BlubberComment::class,
- \BlubberStatusgruppeThread::class => \JsonApi\Schemas\BlubberStatusgruppeThread::class,
- \BlubberThread::class => \JsonApi\Schemas\BlubberThread::class,
+ \BlubberComment::class => Schemas\BlubberComment::class,
+ \BlubberStatusgruppeThread::class => Schemas\BlubberStatusgruppeThread::class,
+ \BlubberThread::class => Schemas\BlubberThread::class,
- \CalendarEvent::class => \JsonApi\Schemas\CalendarEvent::class,
- \ConfigValue::class => \JsonApi\Schemas\ConfigValue::class,
- \CourseEvent::class => \JsonApi\Schemas\CourseEvent::class,
- \ContentTermsOfUse::class => \JsonApi\Schemas\ContentTermsOfUse::class,
- \Course::class => \JsonApi\Schemas\Course::class,
- \CourseMember::class => \JsonApi\Schemas\CourseMember::class,
- \FeedbackElement::class => \JsonApi\Schemas\FeedbackElement::class,
- \FeedbackEntry::class => \JsonApi\Schemas\FeedbackEntry::class,
- \JsonApi\Models\ForumCat::class => \JsonApi\Schemas\ForumCategory::class,
- \JsonApi\Models\ForumEntry::class => \JsonApi\Schemas\ForumEntry::class,
- \Institute::class => \JsonApi\Schemas\Institute::class,
- \InstituteMember::class => \JsonApi\Schemas\InstituteMember::class,
- \Message::class => \JsonApi\Schemas\Message::class,
- \SemClass::class => \JsonApi\Schemas\SemClass::class,
- \Semester::class => \JsonApi\Schemas\Semester::class,
- \SemType::class => \JsonApi\Schemas\SemType::class,
- \SeminarCycleDate::class => \JsonApi\Schemas\SeminarCycleDate::class,
- \Statusgruppen::class => \JsonApi\Schemas\StatusGroup::class,
- \JsonApi\Models\Studip::class => \JsonApi\Schemas\Studip::class,
- \JsonApi\Models\StudipProperty::class => \JsonApi\Schemas\StudipProperty::class,
- \StudipComment::class => \JsonApi\Schemas\StudipComment::class,
- \StudipNews::class => \JsonApi\Schemas\StudipNews::class,
- \StudipStudyArea::class => \JsonApi\Schemas\StudyArea::class,
- \WikiPage::class => \JsonApi\Schemas\WikiPage::class,
- \Studip\Activity\Activity::class => \JsonApi\Schemas\Activity::class,
- \User::class => \JsonApi\Schemas\User::class,
- \File::class => \JsonApi\Schemas\File::class,
- \FileRef::class => \JsonApi\Schemas\FileRef::class,
- \FolderType::class => \JsonApi\Schemas\Folder::class,
+ \CalendarEvent::class => Schemas\CalendarEvent::class,
+ \ConfigValue::class => Schemas\ConfigValue::class,
+ \CourseEvent::class => Schemas\CourseEvent::class,
+ \ContentTermsOfUse::class => Schemas\ContentTermsOfUse::class,
+ \Course::class => Schemas\Course::class,
+ \CourseMember::class => Schemas\CourseMember::class,
+ \FeedbackElement::class => Schemas\FeedbackElement::class,
+ \FeedbackEntry::class => Schemas\FeedbackEntry::class,
+ \JsonApi\Models\ForumCat::class => Schemas\ForumCategory::class,
+ \JsonApi\Models\ForumEntry::class => Schemas\ForumEntry::class,
+ \Institute::class => Schemas\Institute::class,
+ \InstituteMember::class => Schemas\InstituteMember::class,
+ \Message::class => Schemas\Message::class,
+ \SemClass::class => Schemas\SemClass::class,
+ \Semester::class => Schemas\Semester::class,
+ \SemType::class => Schemas\SemType::class,
+ \SeminarCycleDate::class => Schemas\SeminarCycleDate::class,
+ \Statusgruppen::class => Schemas\StatusGroup::class,
+ \JsonApi\Models\Studip::class => Schemas\Studip::class,
+ \JsonApi\Models\StudipProperty::class => Schemas\StudipProperty::class,
+ \StudipComment::class => Schemas\StudipComment::class,
+ \StudipNews::class => Schemas\StudipNews::class,
+ \StudipStudyArea::class => Schemas\StudyArea::class,
+ \WikiPage::class => Schemas\WikiPage::class,
+ \Studip\Activity\Activity::class => Schemas\Activity::class,
+ \User::class => Schemas\User::class,
+ \File::class => Schemas\File::class,
+ \FileRef::class => Schemas\FileRef::class,
+ \FolderType::class => Schemas\Folder::class,
- \Courseware\Block::class => \JsonApi\Schemas\Courseware\Block::class,
- \Courseware\BlockComment::class => \JsonApi\Schemas\Courseware\BlockComment::class,
- \Courseware\BlockFeedback::class => \JsonApi\Schemas\Courseware\BlockFeedback::class,
- \Courseware\Container::class => \JsonApi\Schemas\Courseware\Container::class,
- \Courseware\Instance::class => \JsonApi\Schemas\Courseware\Instance::class,
- \Courseware\StructuralElement::class => \JsonApi\Schemas\Courseware\StructuralElement::class,
- \Courseware\UserDataField::class => \JsonApi\Schemas\Courseware\UserDataField::class,
- \Courseware\UserProgress::class => \JsonApi\Schemas\Courseware\UserProgress::class,
+ \Courseware\Block::class => Schemas\Courseware\Block::class,
+ \Courseware\BlockComment::class => Schemas\Courseware\BlockComment::class,
+ \Courseware\BlockFeedback::class => Schemas\Courseware\BlockFeedback::class,
+ \Courseware\Container::class => Schemas\Courseware\Container::class,
+ \Courseware\Instance::class => Schemas\Courseware\Instance::class,
+ \Courseware\StructuralElement::class => Schemas\Courseware\StructuralElement::class,
+ \Courseware\UserDataField::class => Schemas\Courseware\UserDataField::class,
+ \Courseware\UserProgress::class => Schemas\Courseware\UserProgress::class,
];
}
}
diff --git a/lib/classes/JsonApi/Schemas/Activity.php b/lib/classes/JsonApi/Schemas/Activity.php
index 300dc15..ae95e0c 100644
--- a/lib/classes/JsonApi/Schemas/Activity.php
+++ b/lib/classes/JsonApi/Schemas/Activity.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
use Studip\Activity\Activity as StudipActivity;
class Activity extends SchemaProvider
@@ -16,14 +17,14 @@ class Activity extends SchemaProvider
* Hier wird der Typ des Schemas festgelegt.
* {@inheritdoc}
*/
- protected $resourceType = self::TYPE;
+
/**
* Diese Method entscheidet über die JSON-API-spezifische ID von
* Activity-Objekten.
* {@inheritdoc}
*/
- public function getId($activity)
+ public function getId($activity): ?string
{
return $activity->id;
}
@@ -33,7 +34,7 @@ class Activity extends SchemaProvider
* für die Ausgabe vorbereitet werden.
* {@inheritdoc}
*/
- public function getAttributes($activity)
+ public function getAttributes($activity, ContextInterface $context): iterable
{
if (preg_match('/\\\\([^\\\\]+)Provider$/', $activity->provider, $matches)) {
$activityType = strtolower($matches[1]);
@@ -57,8 +58,11 @@ class Activity extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($activity, $isPrimary, array $includeList)
+ public function getRelationships($activity, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -78,9 +82,10 @@ class Activity extends SchemaProvider
$actorId = $activity->actor_id;
if ($actorType === 'user') {
+ $actor = $include ? \User::findFull($actorId) : \User::build(['id' => $actorId], false);
$relationships[self::REL_ACTOR] = [
- self::LINKS => [Link::RELATED => new Link('/users/'.$actorId)],
- self::DATA => $include ? \User::findFull($actorId) : \User::build(['id' => $actorId], false),
+ self::RELATIONSHIP_LINKS => [Link::RELATED => $this->createLinkToResource($actor)],
+ self::RELATIONSHIP_DATA => $actor
];
}
@@ -90,8 +95,6 @@ class Activity extends SchemaProvider
private function getObjectRelationship(array $relationships, StudipActivity $activity, $include)
{
$mapping = [
- // TODO: Polishing
- // 'blubber' => \BlubberPosting::class,
'documents' => \FileRef::class,
'forum' => \JsonApi\Models\ForumEntry::class,
'message' => \Message::class,
@@ -114,17 +117,17 @@ class Activity extends SchemaProvider
}
if ($data) {
- $link = $this->getSchemaContainer()->getSchema($data)->getSelfSubLink($data);
+ $link = $this->createLinkToResource($data);
$relationships[self::REL_OBJECT] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $link
],
- self::DATA => $data,
+ self::RELATIONSHIP_DATA => $data,
];
}
} else {
$relationships[self::REL_OBJECT] = [
- self::META => [
+ self::RELATIONSHIP_META => [
'object-type' => $activity->object_type,
'object-id' => $activity->object_id,
],
@@ -137,12 +140,12 @@ class Activity extends SchemaProvider
private function getContextRelationship(array $relationships, StudipActivity $activity, $include)
{
if ($data = $this->getContext($activity, $include)) {
- $link = $this->getSchemaContainer()->getSchema($data)->getSelfSubLink($data);
+ $link = $this->createLinkToResource($data);
$relationships[self::REL_CONTEXT] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $link
],
- self::DATA => $data,
+ self::RELATIONSHIP_DATA => $data,
];
}
diff --git a/lib/classes/JsonApi/Schemas/BlubberComment.php b/lib/classes/JsonApi/Schemas/BlubberComment.php
index 7d6e994..2aabd5e 100644
--- a/lib/classes/JsonApi/Schemas/BlubberComment.php
+++ b/lib/classes/JsonApi/Schemas/BlubberComment.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Schema\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
class BlubberComment extends SchemaProvider
{
@@ -11,14 +12,12 @@ class BlubberComment extends SchemaProvider
const REL_MENTIONS = 'mentions';
const REL_THREAD = 'thread';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
# `network` VARCHAR(64) COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
@@ -37,8 +36,11 @@ class BlubberComment extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -62,12 +64,12 @@ class BlubberComment extends SchemaProvider
{
if (!$resource['external_contact']) {
$userId = $resource['user_id'];
-
+ $data = $includeData ? \User::find($userId) : \User::build(['id' => $userId], false);
$relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => new Link('/users/'.$userId),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($data),
],
- self::DATA => $includeData ? \User::find($userId) : \User::build(['id' => $userId], false),
+ self::RELATIONSHIP_DATA => $data,
];
}
@@ -85,10 +87,10 @@ class BlubberComment extends SchemaProvider
}
$relationships[self::REL_MENTIONS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_MENTIONS),
],
- self::DATA => $relatedUsers,
+ self::RELATIONSHIP_DATA => $relatedUsers,
];
return $relationships;
@@ -103,11 +105,10 @@ class BlubberComment extends SchemaProvider
}
$relationships[self::REL_THREAD] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)->getSelfSubLink($related),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related),
],
- self::DATA => $related,
+ self::RELATIONSHIP_DATA => $related,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/BlubberStatusgruppeThread.php b/lib/classes/JsonApi/Schemas/BlubberStatusgruppeThread.php
index 88cd38e..484cb69 100644
--- a/lib/classes/JsonApi/Schemas/BlubberStatusgruppeThread.php
+++ b/lib/classes/JsonApi/Schemas/BlubberStatusgruppeThread.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas;
use JsonApi\Errors\InternalServerError;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class BlubberStatusgruppeThread extends BlubberThread
{
@@ -14,12 +15,15 @@ class BlubberStatusgruppeThread extends BlubberThread
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
- $relationships = parent::getRelationships($resource, $isPrimary, $includeList);
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
+ $relationships = parent::getRelationships($resource, $context);
$relationships[self::REL_STATUSGRUPPE] = [
- self::DATA => \Statusgruppen::build(
+ self::RELATIONSHIP_DATA => \Statusgruppen::build(
[
'statusgruppe_id' => $resource['metadata']['statusgruppe_id']
],
diff --git a/lib/classes/JsonApi/Schemas/BlubberThread.php b/lib/classes/JsonApi/Schemas/BlubberThread.php
index 575da93..386b51e 100644
--- a/lib/classes/JsonApi/Schemas/BlubberThread.php
+++ b/lib/classes/JsonApi/Schemas/BlubberThread.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas;
use JsonApi\Errors\InternalServerError;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Schema\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
class BlubberThread extends SchemaProvider
{
@@ -13,25 +14,25 @@ class BlubberThread extends SchemaProvider
const REL_CONTEXT = 'context';
const REL_MENTIONS = 'mentions';
- protected $resourceType = self::TYPE;
- public function getId($resource)
+
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $userId = $this->currentUser->id;
$attributes = [
'context-type' => $resource['context_type'],
'content' => $resource['content'],
'content-html' => formatReady($resource['content']),
- 'is-commentable' => (bool) $resource->isCommentable($user->id),
- 'is-readable' => (bool) $resource->isReadable($user->id),
- 'is-writable' => (bool) $resource->isWritable($user->id),
+ 'is-commentable' => (bool) $resource->isCommentable($userId),
+ 'is-readable' => (bool) $resource->isReadable($userId),
+ 'is-writable' => (bool) $resource->isWritable($userId),
'is-visible-in-stream' => (bool) $resource->isVisibleInStream(),
@@ -47,8 +48,11 @@ class BlubberThread extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -75,11 +79,10 @@ class BlubberThread extends SchemaProvider
$userId = $resource['user_id'];
$related = $includeData ? \User::find($userId) : \User::build(['id' => $userId], false);
$relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)->getSelfSubLink($related),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related),
],
- self::DATA => $related,
+ self::RELATIONSHIP_DATA => $related,
];
}
@@ -98,9 +101,9 @@ class BlubberThread extends SchemaProvider
}
$relationships[self::REL_MENTIONS] = [
- self::SHOW_SELF => true,
- self::LINKS => [],
- self::DATA => $relatedUsers,
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [],
+ self::RELATIONSHIP_DATA => $relatedUsers,
];
return $relationships;
@@ -109,13 +112,13 @@ class BlubberThread extends SchemaProvider
private function getCommentsRelationship(array $relationships, \BlubberThread $resource, $includeData)
{
$relationship = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_COMMENTS),
],
];
if ($includeData) {
- $relationship[self::DATA] = $resource->comments;
+ $relationship[self::RELATIONSHIP_DATA] = $resource->comments;
}
$relationships[self::REL_COMMENTS] = $relationship;
@@ -135,7 +138,7 @@ class BlubberThread extends SchemaProvider
throw new InternalServerError('Inconsistent data in BlubberThread.');
}
- $related = new Link('/courses/'.$course->id);
+ $related = $this->createLinkToResource($course);
$data = $course;
}
@@ -144,17 +147,17 @@ class BlubberThread extends SchemaProvider
throw new InternalServerError('Inconsistent data in BlubberThread.');
}
- $related = new Link('/institutes/'.$institute->id);
+ $related = $this->createLinkToResource($institute);
$data = $institute;
}
if ($related && $data) {
$relationships[self::REL_CONTEXT] = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $related,
],
- self::DATA => $data,
+ self::RELATIONSHIP_DATA => $data,
];
}
diff --git a/lib/classes/JsonApi/Schemas/CalendarEvent.php b/lib/classes/JsonApi/Schemas/CalendarEvent.php
index 95fb1d9..3ee6ab5 100644
--- a/lib/classes/JsonApi/Schemas/CalendarEvent.php
+++ b/lib/classes/JsonApi/Schemas/CalendarEvent.php
@@ -2,21 +2,20 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class CalendarEvent extends SchemaProvider
{
const TYPE = 'calendar-events';
const REL_OWNER = 'owner';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'title' => $resource->title,
@@ -36,14 +35,17 @@ class CalendarEvent extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($owner = $resource->getOwner()) {
- $link = $this->getSchemaContainer()->getSchema($owner)->getSelfSubLink($owner);
+ $link = $this->createLinkToResource($owner);
$relationships = [
- self::REL_OWNER => [self::LINKS => [Link::RELATED => $link], self::DATA => $owner],
+ self::REL_OWNER => [self::RELATIONSHIP_LINKS => [Link::RELATED => $link], self::RELATIONSHIP_DATA => $owner],
];
}
diff --git a/lib/classes/JsonApi/Schemas/ConfigValue.php b/lib/classes/JsonApi/Schemas/ConfigValue.php
index 3e75317..e24c594 100644
--- a/lib/classes/JsonApi/Schemas/ConfigValue.php
+++ b/lib/classes/JsonApi/Schemas/ConfigValue.php
@@ -2,18 +2,18 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class ConfigValue extends SchemaProvider
{
const TYPE = 'config-values';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return join('_', [$resource['range_id'], $resource['field']]);
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$i18nAwareCast = function ($mixed) use ($resource) {
return 'i18n' === $resource->entry['type'] ? (string) $mixed : $mixed;
@@ -29,4 +29,9 @@ class ConfigValue extends SchemaProvider
'chdate' => date('c', $resource['chdate']),
];
}
+
+ public function getRelationships($user, ContextInterface $context): iterable
+ {
+ return [];
+ }
}
diff --git a/lib/classes/JsonApi/Schemas/ConsultationBlock.php b/lib/classes/JsonApi/Schemas/ConsultationBlock.php
index fd01004..75a29df 100644
--- a/lib/classes/JsonApi/Schemas/ConsultationBlock.php
+++ b/lib/classes/JsonApi/Schemas/ConsultationBlock.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class ConsultationBlock extends SchemaProvider
{
@@ -10,14 +11,12 @@ class ConsultationBlock extends SchemaProvider
const REL_SLOTS = 'slots';
const REL_RANGE = 'range';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'start' => date('c', $resource->start),
@@ -47,8 +46,11 @@ class ConsultationBlock extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -78,10 +80,10 @@ class ConsultationBlock extends SchemaProvider
}
$relationships[self::REL_SLOTS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_SLOTS),
],
- self::DATA => $relatedSlots,
+ self::RELATIONSHIP_DATA => $relatedSlots,
];
return $relationships;
@@ -92,10 +94,10 @@ class ConsultationBlock extends SchemaProvider
$range = $resource->range;
$relationships[self::REL_RANGE] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getLinkForRange($range),
],
- self::DATA => $includeData ? $range : $this->getMinimalRange($range),
+ self::RELATIONSHIP_DATA => $includeData ? $range : $this->getMinimalRange($range),
];
return $relationships;
@@ -103,16 +105,12 @@ class ConsultationBlock extends SchemaProvider
private function getLinkForRange(Range $range)
{
- if ($range instanceof \Course) {
- return new Link("/courses/{$range->id}");
- }
-
- if ($range instanceof \Institute) {
- return new Link("/institutes/{$range->id}");
- }
-
- if ($range instanceof \User) {
- return new Link("/users/{$range->id}");
+ if (
+ $range instanceof \Course ||
+ $range instanceof \Institute ||
+ $range instanceof \User
+ ) {
+ return $this->createLinkToResource($range);
}
throw new \Exception('Unknown range type');
diff --git a/lib/classes/JsonApi/Schemas/ConsultationBooking.php b/lib/classes/JsonApi/Schemas/ConsultationBooking.php
index 7fbc3c9..318f306 100644
--- a/lib/classes/JsonApi/Schemas/ConsultationBooking.php
+++ b/lib/classes/JsonApi/Schemas/ConsultationBooking.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class ConsultationBooking extends SchemaProvider
{
@@ -10,14 +11,12 @@ class ConsultationBooking extends SchemaProvider
const REL_SLOT = 'slot';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'reason' => $resource->reason,
@@ -34,8 +33,11 @@ class ConsultationBooking extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -54,10 +56,10 @@ class ConsultationBooking extends SchemaProvider
$slot = $resource->slot;
$relationships[self::REL_SLOT] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_SLOT),
],
- self::DATA => $includeData ? $slot : \ConsultationSlot::build(['id' => $slot->id], false),
+ self::RELATIONSHIP_DATA => $includeData ? $slot : \ConsultationSlot::build(['id' => $slot->id], false),
];
return $relationships;
@@ -68,10 +70,10 @@ class ConsultationBooking extends SchemaProvider
$user = $resource->user;
$relationships[self::REL_USER] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_USER),
],
- self::DATA => $includeData ? $user : \User::build(['id' => $user->id], false),
+ self::RELATIONSHIP_DATA => $includeData ? $user : \User::build(['id' => $user->id], false),
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/ConsultationSlot.php b/lib/classes/JsonApi/Schemas/ConsultationSlot.php
index 7f4f7b8..1adf912 100644
--- a/lib/classes/JsonApi/Schemas/ConsultationSlot.php
+++ b/lib/classes/JsonApi/Schemas/ConsultationSlot.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class ConsultationSlot extends SchemaProvider
{
@@ -10,14 +11,14 @@ class ConsultationSlot extends SchemaProvider
const REL_BLOCK = 'block';
const REL_BOOKINGS = 'bookings';
- protected $resourceType = self::TYPE;
- public function getId($resource)
+
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'note' => $resource->note,
@@ -38,8 +39,11 @@ class ConsultationSlot extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -63,10 +67,10 @@ class ConsultationSlot extends SchemaProvider
$block = $resource->block;
$relationships[self::REL_BLOCK] = [
- self::LINKS => [
- Link::RELATED => new Link("/consultation-block/{$block->id}"),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($block),
],
- self::DATA => $includeData ? $block : \ConsultationBlock::build(['id' => $block->id], false),
+ self::RELATIONSHIP_DATA => $includeData ? $block : \ConsultationBlock::build(['id' => $block->id], false),
];
return $relationships;
@@ -83,10 +87,10 @@ class ConsultationSlot extends SchemaProvider
}
$relationships[self::REL_BOOKINGS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_BOOKINGS),
],
- self::DATA => $relatedBookings,
+ self::RELATIONSHIP_DATA => $relatedBookings,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php b/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
index 651b408..b827788 100644
--- a/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
+++ b/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
@@ -2,18 +2,18 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class ContentTermsOfUse extends SchemaProvider
{
const TYPE = 'terms-of-use';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'name' => (string) $resource['name'],
@@ -24,4 +24,9 @@ class ContentTermsOfUse extends SchemaProvider
'chdate' => date('c', $resource['chdate']),
];
}
+
+ public function getRelationships($user, ContextInterface $context): iterable
+ {
+ return [];
+ }
}
diff --git a/lib/classes/JsonApi/Schemas/Course.php b/lib/classes/JsonApi/Schemas/Course.php
index 3aa6711..98c8909 100644
--- a/lib/classes/JsonApi/Schemas/Course.php
+++ b/lib/classes/JsonApi/Schemas/Course.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas;
use JsonApi\Routes\Files\Authority as FilesAuth;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Course extends SchemaProvider
{
@@ -26,14 +27,12 @@ class Course extends SchemaProvider
const REL_STATUS_GROUPS = 'status-groups';
const REL_WIKI_PAGES = 'wiki-pages';
- protected $resourceType = self::TYPE;
-
- public function getId($course)
+ public function getId($course): ?string
{
return $course->seminar_id;
}
- public function getAttributes($course)
+ public function getAttributes($course, ContextInterface $context): iterable
{
$stringOrNull = function ($item) {
return trim($item) != '' ? (string) $item : null;
@@ -54,8 +53,12 @@ class Course extends SchemaProvider
];
}
- public function getRelationships($course, $isPrimary, array $includeList)
+ public function getRelationships($course, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
+
$relationships = [];
$relationships[self::REL_INSTITUTE] = $this->getInstitute($course, in_array(self::REL_INSTITUTE, $includeList));
@@ -89,10 +92,10 @@ class Course extends SchemaProvider
private function getInstitute(\Course $course, $shouldInclude)
{
return [
- self::LINKS => [
- Link::RELATED => new Link('/institutes/'.$course->institut_id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($course->home_institut),
],
- self::DATA => $course->home_institut,
+ self::RELATIONSHIP_DATA => $course->home_institut,
];
}
@@ -103,10 +106,10 @@ class Course extends SchemaProvider
}
return [
- self::LINKS => [
- Link::RELATED => new Link('/semesters/'.$semester->id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($semester),
],
- self::DATA => $semester,
+ self::RELATIONSHIP_DATA => $semester,
];
}
@@ -117,29 +120,29 @@ class Course extends SchemaProvider
}
return [
- self::LINKS => [
- Link::RELATED => new Link('/semesters/'.$semester->id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($semester),
],
- self::DATA => $semester,
+ self::RELATIONSHIP_DATA => $semester,
];
}
private function getFilesRelationship(array $relationships, \Course $resource)
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
if ($user && FilesAuth::canShowFileArea($user, $resource)) {
$filesLink = $this->getRelationshipRelatedLink($resource, self::REL_FILES);
$relationships[self::REL_FILES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $filesLink,
],
];
$foldersLink = $this->getRelationshipRelatedLink($resource, self::REL_FOLDERS);
$relationships[self::REL_FOLDERS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $foldersLink,
],
];
@@ -157,7 +160,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_FORUM_CATEGORIES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_FORUM_CATEGORIES)
],
];
@@ -174,7 +177,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_BLUBBER] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_BLUBBER),
],
];
@@ -191,7 +194,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_EVENTS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_EVENTS)
],
];
@@ -210,7 +213,7 @@ class Course extends SchemaProvider
if (\Feedback::isActivated($course->id)) {
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_FEEDBACK)
],
];
@@ -228,8 +231,8 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_MEMBERSHIPS] = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_MEMBERSHIPS)
],
];
@@ -246,7 +249,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_NEWS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_NEWS)
],
];
@@ -263,7 +266,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_WIKI_PAGES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_WIKI_PAGES)
],
];
@@ -286,7 +289,7 @@ class Course extends SchemaProvider
);
$relationships[self::REL_PARTICIPATING_INSTITUTES] = [
- self::DATA => $institutes
+ self::RELATIONSHIP_DATA => $institutes
];
return $relationships;
@@ -301,7 +304,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_SEM_CLASS] = [
- self::DATA => $course->getSemClass()
+ self::RELATIONSHIP_DATA => $course->getSemClass()
];
return $relationships;
@@ -316,7 +319,7 @@ class Course extends SchemaProvider
$includeData
) {
$relationships[self::REL_SEM_TYPE] = [
- self::DATA => $course->getSemType()
+ self::RELATIONSHIP_DATA => $course->getSemType()
];
return $relationships;
@@ -328,13 +331,13 @@ class Course extends SchemaProvider
$includeData
) {
$relation = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_STATUS_GROUPS),
]
];
if (in_array(self::REL_STATUS_GROUPS, $includeData)) {
$related = \Statusgruppen::findBySeminar_id($resource->id);
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
return array_merge($relationships, [self::REL_STATUS_GROUPS => $relation]);
diff --git a/lib/classes/JsonApi/Schemas/CourseEvent.php b/lib/classes/JsonApi/Schemas/CourseEvent.php
index 470d86b..d2ec52d 100644
--- a/lib/classes/JsonApi/Schemas/CourseEvent.php
+++ b/lib/classes/JsonApi/Schemas/CourseEvent.php
@@ -2,21 +2,20 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class CourseEvent extends SchemaProvider
{
const TYPE = 'course-events';
const REL_OWNER = 'owner';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'title' => $resource->title,
@@ -35,14 +34,17 @@ class CourseEvent extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($owner = $resource->course) {
- $link = $this->getSchemaContainer()->getSchema($owner)->getSelfSubLink($owner);
+ $link = $this->createLinkToResource($owner);
$relationships = [
- self::REL_OWNER => [self::LINKS => [Link::RELATED => $link], self::DATA => $owner],
+ self::REL_OWNER => [self::RELATIONSHIP_LINKS => [Link::RELATED => $link], self::RELATIONSHIP_DATA => $owner],
];
}
diff --git a/lib/classes/JsonApi/Schemas/CourseMember.php b/lib/classes/JsonApi/Schemas/CourseMember.php
index 8882c84..1997e8b 100644
--- a/lib/classes/JsonApi/Schemas/CourseMember.php
+++ b/lib/classes/JsonApi/Schemas/CourseMember.php
@@ -4,7 +4,8 @@ namespace JsonApi\Schemas;
use JsonApi\Routes\Courses\Authority as CourseAuthority;
use JsonApi\Routes\CourseMemberships\Authority as MembershipAuthority;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class CourseMember extends SchemaProvider
{
@@ -12,14 +13,12 @@ class CourseMember extends SchemaProvider
const REL_COURSE = 'course';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
- public function getId($membership)
+ public function getId($membership): ?string
{
return $membership->id;
}
- public function getAttributes($membership)
+ public function getAttributes($membership, ContextInterface $context): iterable
{
$attributes = [
'permission' => $membership->status,
@@ -28,14 +27,13 @@ class CourseMember extends SchemaProvider
'mkdate' => date('c', $membership->mkdate),
'label' => $membership->label,
];
- // TODO: "bind_calendar": "1",
- if ($user = $this->getDiContainer()->get('studip-current-user')) {
- if (MembershipAuthority::canIndexMembershipsOfUser($user, $membership->user)) {
+ if ($this->currentUser) {
+ if (MembershipAuthority::canIndexMembershipsOfUser($this->currentUser, $membership->user)) {
# TODO: $attributes['notification'] = (int) $membership->notification;
$attributes['visible'] = $membership->visible;
}
- if (CourseAuthority::canEditCourse($user, $membership->course)) {
+ if (CourseAuthority::canEditCourse($this->currentUser, $membership->course)) {
$attributes['comment'] = $membership->comment;
$attributes['visible'] = $membership->visible;
}
@@ -44,23 +42,26 @@ class CourseMember extends SchemaProvider
return $attributes;
}
- public function getRelationships($membership, $isPrimary, array $includeList)
+ public function getRelationships($membership, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
$relationships[self::REL_COURSE] = [
- self::LINKS => [
- Link::RELATED => new Link('/courses/'.$membership->seminar_id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($membership->course)
],
- self::DATA => $membership->course,
+ self::RELATIONSHIP_DATA => $membership->course,
];
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => new Link('/users/'.$membership->user_id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($membership->user)
],
- self::DATA => $membership->user,
+ self::RELATIONSHIP_DATA => $membership->user,
];
}
diff --git a/lib/classes/JsonApi/Schemas/Courseware/Block.php b/lib/classes/JsonApi/Schemas/Courseware/Block.php
index 23c4eae..89434d9 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/Block.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/Block.php
@@ -5,7 +5,8 @@ namespace JsonApi\Schemas\Courseware;
use Courseware\UserDataField;
use Courseware\UserProgress;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Block extends SchemaProvider
{
@@ -21,12 +22,10 @@ class Block extends SchemaProvider
const REL_USERPROGRESS = 'user-progress';
const REL_FILES = 'file-refs';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -34,7 +33,7 @@ class Block extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'position' => (int) $resource['position'],
@@ -50,87 +49,82 @@ class Block extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships[self::REL_COMMENTS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_COMMENTS),
],
- self::DATA => $resource->comments,
+ self::RELATIONSHIP_DATA => $resource->comments,
];
$relationships[self::REL_CONTAINER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->container)
- ->getSelfSubLink($resource->container),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->container),
],
- self::DATA => $resource->container,
+ self::RELATIONSHIP_DATA => $resource->container,
];
$relationships[self::REL_OWNER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)
- ->getSelfSubLink($resource->owner),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
],
- self::DATA => $resource->owner,
+ self::RELATIONSHIP_DATA => $resource->owner,
];
$relationships[self::REL_EDITOR] = $resource['editor_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->editor)
- ->getSelfSubLink($resource->editor),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->editor),
],
- self::DATA => $resource->editor,
+ self::RELATIONSHIP_DATA => $resource->editor,
]
- : [self::DATA => null];
+ : [self::RELATIONSHIP_DATA => null];
$relationships[self::REL_EDITBLOCKER] = $resource['edit_blocker_id']
? [
- self::SHOW_SELF => true,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->edit_blocker)
- ->getSelfSubLink($resource->edit_blocker),
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->edit_blocker),
],
- self::DATA => $resource->edit_blocker,
+ self::RELATIONSHIP_DATA => $resource->edit_blocker,
]
- : [self::SHOW_SELF => true, self::DATA => null];
+ : [self::RELATIONSHIP_LINKS_SELF => true, self::RELATIONSHIP_DATA => null];
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FEEDBACK),
],
];
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
$userDataField = UserDataField::getUserDataField($user, $resource);
$relationships[self::REL_USERDATAFIELD] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_USERDATAFIELD),
],
- self::DATA => $userDataField,
+ self::RELATIONSHIP_DATA => $userDataField,
];
$userProgress = UserProgress::getUserProgress($user, $resource);
$relationships[self::REL_USERPROGRESS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_USERPROGRESS),
],
- self::DATA => $userProgress,
+ self::RELATIONSHIP_DATA => $userProgress,
];
if ($resource->files) {
$filesLink = $this->getRelationshipRelatedLink($resource, self::REL_FILES);
$relationships[self::REL_FILES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $filesLink,
],
];
diff --git a/lib/classes/JsonApi/Schemas/Courseware/BlockComment.php b/lib/classes/JsonApi/Schemas/Courseware/BlockComment.php
index fa13d55..c2abd5b 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/BlockComment.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/BlockComment.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class BlockComment extends SchemaProvider
{
@@ -12,12 +13,10 @@ class BlockComment extends SchemaProvider
const REL_BLOCK = 'block';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -25,7 +24,7 @@ class BlockComment extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'comment' => (string) $resource['comment'],
@@ -37,26 +36,25 @@ class BlockComment extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships[self::REL_BLOCK] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->block)
- ->getSelfSubLink($resource->block),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->block),
],
- self::DATA => $resource->block,
+ self::RELATIONSHIP_DATA => $resource->block,
];
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->user)
- ->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Courseware/BlockFeedback.php b/lib/classes/JsonApi/Schemas/Courseware/BlockFeedback.php
index 5e5b2c6..b5992b7 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/BlockFeedback.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/BlockFeedback.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class BlockFeedback extends SchemaProvider
{
@@ -12,12 +13,10 @@ class BlockFeedback extends SchemaProvider
const REL_USER = 'user';
const REL_BLOCK = 'block';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -25,7 +24,7 @@ class BlockFeedback extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'feedback' => (string) $resource['feedback'],
@@ -37,26 +36,25 @@ class BlockFeedback extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships[self::REL_BLOCK] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->block)
- ->getSelfSubLink($resource->block),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->block),
],
- self::DATA => $resource->block,
+ self::RELATIONSHIP_DATA => $resource->block,
];
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->user)
- ->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Courseware/Container.php b/lib/classes/JsonApi/Schemas/Courseware/Container.php
index db68fc7..ea6ab96 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/Container.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/Container.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Container extends SchemaProvider
{
@@ -15,12 +16,10 @@ class Container extends SchemaProvider
const REL_EDITBLOCKER = 'edit-blocker';
const REL_STRUCTURAL_ELEMENT = 'structural-element';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -28,7 +27,7 @@ class Container extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'position' => (int) $resource['position'],
@@ -46,8 +45,11 @@ class Container extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($includeList) {
@@ -58,48 +60,40 @@ class Container extends SchemaProvider
$relationships[self::REL_OWNER] = $resource['owner_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)
- ->getSelfSubLink($resource->owner),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
],
- self::DATA => $resource->owner,
+ self::RELATIONSHIP_DATA => $resource->owner,
]
- : [self::DATA => $resource->owner];
+ : [self::RELATIONSHIP_DATA => $resource->owner];
$relationships[self::REL_EDITOR] = $resource['editor_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->editor)
- ->getSelfSubLink($resource->editor),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->editor),
],
- self::DATA => $resource->editor,
+ self::RELATIONSHIP_DATA => $resource->editor,
]
- : [self::DATA => null];
+ : [self::RELATIONSHIP_DATA => null];
$relationships[self::REL_EDITBLOCKER] = $resource['edit_blocker_id']
? [
- self::SHOW_SELF => true,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->edit_blocker)
- ->getSelfSubLink($resource->edit_blocker),
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->edit_blocker),
],
- self::DATA => $resource->edit_blocker,
+ self::RELATIONSHIP_DATA => $resource->edit_blocker,
]
- : [self::SHOW_SELF => true, self::DATA => null];
+ : [self::RELATIONSHIP_LINKS_SELF => true, self::RELATIONSHIP_DATA => null];
$relationships[self::REL_STRUCTURAL_ELEMENT] = $resource['structural_element_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->structural_element)
- ->getSelfSubLink($resource->structural_element),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->structural_element),
],
- self::DATA => $resource->structural_element,
+ self::RELATIONSHIP_DATA => $resource->structural_element,
]
- : [self::DATA => null];
+ : [self::RELATIONSHIP_DATA => null];
return $relationships;
}
@@ -107,13 +101,13 @@ class Container extends SchemaProvider
private function addBlocksRelationship(array $relationships, $resource, $includeData)
{
$relation = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_BLOCKS),
],
];
- $relation[self::DATA] = $resource->blocks;
+ $relation[self::RELATIONSHIP_DATA] = $resource->blocks;
$relationships[self::REL_BLOCKS] = $relation;
diff --git a/lib/classes/JsonApi/Schemas/Courseware/Instance.php b/lib/classes/JsonApi/Schemas/Courseware/Instance.php
index 55a70f6..2fba0e3 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/Instance.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/Instance.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Instance extends SchemaProvider
{
@@ -12,12 +13,10 @@ class Instance extends SchemaProvider
const REL_BOOKMARKS = 'bookmarks';
const REL_ROOT = 'root';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
$root = $resource->getRoot();
@@ -27,9 +26,9 @@ class Instance extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
return [
'block-types' => array_map([$this, 'mapBlockType'], $resource->getBlockTypes()),
@@ -70,26 +69,27 @@ class Instance extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
$relationships[self::REL_BOOKMARKS] = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_BOOKMARKS),
],
- self::DATA => $resource->getUsersBookmarks($user),
+ self::RELATIONSHIP_DATA => $resource->getUsersBookmarks($user),
];
$relationships[self::REL_ROOT] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->getRoot())
- ->getSelfSubLink($resource->getRoot()),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->getRoot()),
],
- self::DATA => $resource->getRoot(),
+ self::RELATIONSHIP_DATA => $resource->getRoot(),
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
index 6089b47..ed3e32d 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class StructuralElement extends SchemaProvider
{
@@ -21,12 +22,10 @@ class StructuralElement extends SchemaProvider
const REL_PARENT = 'parent';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -34,9 +33,9 @@ class StructuralElement extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
return [
'position' => (int) $resource['position'],
@@ -65,8 +64,11 @@ class StructuralElement extends SchemaProvider
* @param bool $isPrimary
* @param array $includeList
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($includeList) {
@@ -74,86 +76,74 @@ class StructuralElement extends SchemaProvider
};
$relationships[self::REL_CHILDREN] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_CHILDREN),
],
- self::DATA => $resource->children,
+ self::RELATIONSHIP_DATA => $resource->children,
];
$relationships[self::REL_CONTAINERS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_CONTAINERS),
],
- self::DATA => $resource->containers,
+ self::RELATIONSHIP_DATA => $resource->containers,
];
if ($resource->course) {
$relationships[self::REL_COURSE] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->course)
- ->getSelfSubLink($resource->course),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->course),
],
- self::DATA => $resource->course,
+ self::RELATIONSHIP_DATA => $resource->course,
];
}
if ($resource->user) {
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->user)
- ->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
];
}
$relationships[self::REL_OWNER] = $resource['owner_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)
- ->getSelfSubLink($resource->owner),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
],
- self::DATA => $resource->owner,
+ self::RELATIONSHIP_DATA => $resource->owner,
]
- : [self::DATA => null];
+ : [self::RELATIONSHIP_DATA => null];
$relationships[self::REL_EDITOR] = $resource['editor_id']
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->editor)
- ->getSelfSubLink($resource->editor),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->editor),
],
- self::DATA => $resource->editor,
+ self::RELATIONSHIP_DATA => $resource->editor,
]
- : [self::DATA => $resource->editor];
+ : [self::RELATIONSHIP_DATA => $resource->editor];
$relationships[self::REL_EDITBLOCKER] = $resource['edit_blocker_id']
? [
- self::SHOW_SELF => true,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->edit_blocker)
- ->getSelfSubLink($resource->edit_blocker),
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->edit_blocker),
],
- self::DATA => $resource->edit_blocker,
+ self::RELATIONSHIP_DATA => $resource->edit_blocker,
]
- : [self::SHOW_SELF => true, self::DATA => null];
+ : [self::RELATIONSHIP_LINKS_SELF => true, self::RELATIONSHIP_DATA => null];
$relationships[self::REL_PARENT] = $resource->parent_id
? [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->parent)
- ->getSelfSubLink($resource->parent),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->parent),
],
- self::DATA => $resource->parent,
+ self::RELATIONSHIP_DATA => $resource->parent,
]
- : [self::DATA => null];
+ : [self::RELATIONSHIP_DATA => null];
$relationships = $this->addAncestorsRelationship(
$relationships,
@@ -174,14 +164,14 @@ class StructuralElement extends SchemaProvider
private function addAncestorsRelationship(array $relationships, $resource, $includeData)
{
$relation = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_ANCESTORS),
],
];
if ($includeData) {
$related = $resource->findAncestors();
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
$relationships[self::REL_ANCESTORS] = $relation;
@@ -192,14 +182,14 @@ class StructuralElement extends SchemaProvider
private function addDescendantsRelationship(array $relationships, $resource, $includeData)
{
$relation = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_DESCENDANTS),
],
];
if ($includeData) {
$related = $resource->findDescendants();
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
$relationships[self::REL_DESCENDANTS] = $relation;
@@ -210,11 +200,11 @@ class StructuralElement extends SchemaProvider
private function addImageRelationship(array $relationships, $resource, $includeData)
{
$relation = [
- self::DATA => $resource->image ?: null,
+ self::RELATIONSHIP_DATA => $resource->image ?: null,
];
if ($resource->image) {
- $relation[self::META] = [
+ $relation[self::RELATIONSHIP_META] = [
'download-url' => $resource->image->getFileType()->getDownloadURL(),
];
}
diff --git a/lib/classes/JsonApi/Schemas/Courseware/UserDataField.php b/lib/classes/JsonApi/Schemas/Courseware/UserDataField.php
index d42a800..810e870 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/UserDataField.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/UserDataField.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class UserDataField extends SchemaProvider
{
@@ -12,12 +13,10 @@ class UserDataField extends SchemaProvider
const REL_BLOCK = 'block';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -25,7 +24,7 @@ class UserDataField extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'payload' => $resource['payload']->getIterator(),
@@ -37,26 +36,25 @@ class UserDataField extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships[self::REL_BLOCK] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->block)
- ->getSelfSubLink($resource->block),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->block),
],
- self::DATA => $resource->block,
+ self::RELATIONSHIP_DATA => $resource->block,
];
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->user)
- ->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Courseware/UserProgress.php b/lib/classes/JsonApi/Schemas/Courseware/UserProgress.php
index 6b8629d..5d6e68a 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/UserProgress.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/UserProgress.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas\Courseware;
use JsonApi\Schemas\SchemaProvider;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class UserProgress extends SchemaProvider
{
@@ -12,12 +13,10 @@ class UserProgress extends SchemaProvider
const REL_BLOCK = 'block';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
-
/**
* {@inheritdoc}
*/
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
@@ -25,7 +24,7 @@ class UserProgress extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'grade' => (float) $resource['grade'],
@@ -37,26 +36,25 @@ class UserProgress extends SchemaProvider
/**
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships[self::REL_BLOCK] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->block)
- ->getSelfSubLink($resource->block),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->block),
],
- self::DATA => $resource->block,
+ self::RELATIONSHIP_DATA => $resource->block,
];
$relationships[self::REL_USER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->user)
- ->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/FeedbackElement.php b/lib/classes/JsonApi/Schemas/FeedbackElement.php
index b8a0f78..0709611 100644
--- a/lib/classes/JsonApi/Schemas/FeedbackElement.php
+++ b/lib/classes/JsonApi/Schemas/FeedbackElement.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class FeedbackElement extends SchemaProvider
{
@@ -12,14 +13,14 @@ class FeedbackElement extends SchemaProvider
const REL_ENTRIES = 'entries';
const REL_RANGE = 'range';
- protected $resourceType = self::TYPE;
- public function getId($resource)
+
+ public function getId($resource): ?string
{
return (int) $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'question' => (string) $resource['question'],
@@ -38,7 +39,15 @@ class FeedbackElement extends SchemaProvider
/**
* @inheritdoc
*/
- public function getPrimaryMeta($resource)
+ public function hasResourceMeta($resource): bool
+ {
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getResourceMeta($resource)
{
return $resource['mode'] === 0
? null
@@ -55,8 +64,11 @@ class FeedbackElement extends SchemaProvider
* spezifiziert werden.
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -76,12 +88,10 @@ class FeedbackElement extends SchemaProvider
$userId = $resource['user_id'];
$related = $includeData ? \User::find($userId) : \User::build(['id' => $userId], false);
$relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related)
],
- self::DATA => $related
+ self::RELATIONSHIP_DATA => $related
];
return $relationships;
@@ -92,53 +102,47 @@ class FeedbackElement extends SchemaProvider
if ($courseId = $resource['course_id']) {
$related = $includeData ? \Course::find($courseId) : \Course::build(['id' => $courseId], false);
$relationships[self::REL_COURSE] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related)
],
- self::DATA => $related
+ self::RELATIONSHIP_DATA => $related
];
}
return $relationships;
}
- private function getEntriesRelationship(array $relationships, \FeedbackElement $resource, $includeData): array
+ private function getEntriesRelationship(array $relationships, \FeedbackElement $resource, bool $includeData): array
{
$relationships[self::REL_ENTRIES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_ENTRIES)
],
- self::DATA => $resource->entries
+ self::RELATIONSHIP_DATA => $resource->entries
];
return $relationships;
}
- private function getRangeRelationship(array $relationships, \FeedbackElement $resource, $includeData): array
+ private function getRangeRelationship(array $relationships, \FeedbackElement $resource, bool $includeData): array
{
$rangeType = $resource['range_type'];
- $rangeSchema = null;
+ $link = null;
try {
- $rangeSchema = $this->getSchemaContainer()->getSchemaByType($rangeType);
- } catch (\InvalidArgumentException $e) {
- }
-
- if (
- isset($rangeSchema) &&
- is_subclass_of($rangeType, \FeedbackRange::class) &&
- is_subclass_of($rangeType, \SimpleORMap::class)
- ) {
- if ($range = $rangeType::find($resource['range_id'])) {
- $link = $rangeSchema->getSelfSubLink($range);
-
- $relationships[self::REL_RANGE] = [
- self::LINKS => [Link::RELATED => $link],
- self::DATA => $range
- ];
+ $link = $this->createLinkToResource($rangeType);
+ if (
+ is_subclass_of($rangeType, \FeedbackRange::class) &&
+ is_subclass_of($rangeType, \SimpleORMap::class)
+ ) {
+ if ($range = $rangeType::find($resource['range_id'])) {
+ $relationships[self::REL_RANGE] = [
+ self::RELATIONSHIP_LINKS => [Link::RELATED => $link],
+ self::RELATIONSHIP_DATA => $range
+ ];
+ }
}
+ } catch (\InvalidArgumentException $e) {
}
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/FeedbackEntry.php b/lib/classes/JsonApi/Schemas/FeedbackEntry.php
index 5583952..e919c13 100644
--- a/lib/classes/JsonApi/Schemas/FeedbackEntry.php
+++ b/lib/classes/JsonApi/Schemas/FeedbackEntry.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class FeedbackEntry extends SchemaProvider
{
@@ -10,20 +11,18 @@ class FeedbackEntry extends SchemaProvider
const REL_AUTHOR = 'author';
const REL_FEEDBACK = 'feedback-element';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'comment' => (string) $resource['comment'],
- 'rating' => $resource->feedback->mode === 0 ? null : $resource['rating'],
+ 'rating' => 0 === $resource->feedback->mode ? null : $resource['rating'],
'mkdate' => date('c', $resource['mkdate']),
- 'chdate' => date('c', $resource['chdate'])
+ 'chdate' => date('c', $resource['chdate']),
];
return $attributes;
@@ -32,10 +31,14 @@ class FeedbackEntry extends SchemaProvider
/**
* In dieser Methode können Relationships zu anderen Objekten
* spezifiziert werden.
+ *
* {@inheritdoc}
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -57,12 +60,10 @@ class FeedbackEntry extends SchemaProvider
$userId = $resource['user_id'];
$related = $includeData ? \User::find($userId) : \User::build(['id' => $userId], false);
$relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related),
],
- self::DATA => $related
+ self::RELATIONSHIP_DATA => $related,
];
return $relationships;
@@ -78,12 +79,10 @@ class FeedbackEntry extends SchemaProvider
: \FeedbackElement::build(['id' => $resource->feedback_id], false);
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related),
],
- self::DATA => $related
+ self::RELATIONSHIP_DATA => $related,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/File.php b/lib/classes/JsonApi/Schemas/File.php
index 45bb2aa..8293b5f 100644
--- a/lib/classes/JsonApi/Schemas/File.php
+++ b/lib/classes/JsonApi/Schemas/File.php
@@ -3,7 +3,8 @@
namespace JsonApi\Schemas;
use JsonApi\Routes\Files\Authority as FilesAuthority;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class File extends SchemaProvider
{
@@ -12,19 +13,12 @@ class File extends SchemaProvider
const REL_FILE_REFS = 'file-refs';
const REL_OWNER = 'owner';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->getId();
}
- public function getInclusionMeta($resource)
- {
- return $this->getPrimaryMeta($resource);
- }
-
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'name' => $resource['name'],
@@ -36,8 +30,7 @@ class File extends SchemaProvider
];
if ($resource['metadata']['url']) {
- $user = $this->getDiContainer()->get('studip-current-user');
- if (FilesAuthority::canUpdateFile($user, $resource)) {
+ if (FilesAuthority::canUpdateFile($this->currentUser, $resource)) {
$attributes['url'] = $resource['metadata']['url'];
}
}
@@ -48,8 +41,11 @@ class File extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
@@ -65,8 +61,8 @@ class File extends SchemaProvider
$refs = $resource->refs;
$relationships[self::REL_FILE_REFS] = [
- self::SHOW_SELF => true,
- self::DATA => $refs,
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_DATA => $refs,
];
return $relationships;
@@ -76,11 +72,10 @@ class File extends SchemaProvider
{
if ($resource->user_id) {
$relationships[self::REL_OWNER] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)->getSelfSubLink($resource->owner),
- ],
- ];
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
+ ],
+ ];
}
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/FileRef.php b/lib/classes/JsonApi/Schemas/FileRef.php
index e928544..5da46f6 100644
--- a/lib/classes/JsonApi/Schemas/FileRef.php
+++ b/lib/classes/JsonApi/Schemas/FileRef.php
@@ -2,8 +2,8 @@
namespace JsonApi\Schemas;
-use JsonApi\Providers\JsonApiConfig as C;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class FileRef extends SchemaProvider
{
@@ -18,24 +18,27 @@ class FileRef extends SchemaProvider
const META_CONTENT = 'content';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->getId();
}
- public function getPrimaryMeta($resource)
+ /**
+ * @inheritdoc
+ */
+ public function hasResourceMeta($resource): bool
{
- $link = $this->getDiContainer()->get(C::JSON_URL_PREFIX)
- .$this->getRelationshipRelatedLink($resource, self::META_CONTENT)->getSubHref();
+ return true;
+ }
+ public function getResourceMeta($resource)
+ {
return [
- 'download-url' => $link,
+ 'download-url' => $resource->getDownloadURL(),
];
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'name' => $resource['name'],
@@ -50,7 +53,7 @@ class FileRef extends SchemaProvider
'mime-type' => $resource->file->mime_type
];
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
if ($folder = $resource->getFolderType()) {
$filetype = $resource->getFileType();
$attributes = array_merge(
@@ -70,8 +73,11 @@ class FileRef extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships = $this->getFeedbackRelationship($relationships, $resource);
@@ -94,7 +100,7 @@ class FileRef extends SchemaProvider
if ($folder = $resource->getFolderType()) {
if ($folder->range_id && $folder->range_type === 'course' && \Feedback::isActivated($folder->range_id)) {
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FEEDBACK)
],
];
@@ -108,11 +114,9 @@ class FileRef extends SchemaProvider
{
if ($resource->file) {
$relationships[self::REL_FILE] = [
- self::DATA => $resource->file,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->file)
- ->getSelfSubLink($resource->file),
+ self::RELATIONSHIP_DATA => $resource->file,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->file),
],
];
}
@@ -123,16 +127,15 @@ class FileRef extends SchemaProvider
private function addOwnerRelationship(array $relationships, \FileRef $resource)
{
$relationships[self::REL_OWNER] = [
- self::META => [
+ self::RELATIONSHIP_META => [
'name' => $resource->getAuthorName(),
],
- self::DATA => $resource->owner,
+ self::RELATIONSHIP_DATA => $resource->owner,
];
if (isset($resource->owner)) {
- $relationships[self::REL_OWNER][self::LINKS] = [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)->getSelfSubLink($resource->owner),
+ $relationships[self::REL_OWNER][self::RELATIONSHIP_LINKS] = [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
];
}
@@ -144,11 +147,9 @@ class FileRef extends SchemaProvider
if ($resource->folder_id) {
$folder = $resource->getFolderType();
$relationships[self::REL_PARENT] = [
- self::DATA => $folder,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($folder)
- ->getSelfSubLink($folder),
+ self::RELATIONSHIP_DATA => $folder,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($folder),
],
];
}
@@ -163,11 +164,10 @@ class FileRef extends SchemaProvider
try {
$rangeType = $folder->range_type;
if ($range = $folder->$rangeType) {
- $schema = $this->getSchemaContainer()->getSchema($range);
$relationships[self::REL_RANGE] = [
- self::DATA => $range,
- self::LINKS => [
- Link::RELATED => $schema->getSelfSubLink($range),
+ self::RELATIONSHIP_DATA => $range,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($range),
],
];
}
@@ -182,8 +182,8 @@ class FileRef extends SchemaProvider
private function addTermsRelationship(array $relationships, \FileRef $resource)
{
$relationships[self::REL_TERMS] = [
- self::DATA => $resource->content_terms_of_use_id ? $resource->terms_of_use : null,
- self::SHOW_SELF => true,
+ self::RELATIONSHIP_DATA => $resource->content_terms_of_use_id ? $resource->terms_of_use : null,
+ self::RELATIONSHIP_LINKS_SELF => true,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Folder.php b/lib/classes/JsonApi/Schemas/Folder.php
index b28884d..f2c5608 100644
--- a/lib/classes/JsonApi/Schemas/Folder.php
+++ b/lib/classes/JsonApi/Schemas/Folder.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Folder extends SchemaProvider
{
@@ -14,16 +15,14 @@ class Folder extends SchemaProvider
const REL_FILE_REFS = 'file-refs';
const REL_FOLDERS = 'folders';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->getId();
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
$attributes = [
'folder-type' => $resource->folder_type,
@@ -51,8 +50,11 @@ class Folder extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameters)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
@@ -71,11 +73,9 @@ class Folder extends SchemaProvider
{
if ($resource->user_id && $resource->owner) {
$relationships[self::REL_OWNER] = [
- self::DATA => $resource->owner,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)
- ->getSelfSubLink($resource->owner),
+ self::RELATIONSHIP_DATA => $resource->owner,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
],
];
}
@@ -88,11 +88,9 @@ class Folder extends SchemaProvider
if ($resource->parent_id) {
$parent = $resource->parentfolder->getTypedFolder();
$relationships[self::REL_PARENT] = [
- self::DATA => $parent,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($parent)
- ->getSelfSubLink($parent),
+ self::RELATIONSHIP_DATA => $parent,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($parent),
],
];
}
@@ -117,12 +115,11 @@ class Folder extends SchemaProvider
{
$rangeType = $resource->range_type;
if ($range = $resource->$rangeType) {
- $schema = $this->getSchemaContainer()->getSchema($range);
return [
- self::DATA => $range,
- self::LINKS => [
- Link::RELATED => $schema->getSelfSubLink($range),
+ self::RELATIONSHIP_DATA => $range,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($range),
],
];
}
@@ -133,7 +130,7 @@ class Folder extends SchemaProvider
private function getDefaultRangeRelationship($resource)
{
return [
- self::META => [
+ self::RELATIONSHIP_META => [
'range_id' => $resource->range_id,
'range_type' => $resource->range_type,
],
@@ -145,7 +142,7 @@ class Folder extends SchemaProvider
if ($resource->range_type === 'course') {
if (\Feedback::isActivated($resource->range_id)) {
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FEEDBACK)
],
];
@@ -158,7 +155,7 @@ class Folder extends SchemaProvider
private function getFoldersRelationship(array $relationships, $resource)
{
$relationships[self::REL_FOLDERS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FOLDERS),
],
];
@@ -169,7 +166,7 @@ class Folder extends SchemaProvider
private function getFilesRelationship(array $relationships, $resource)
{
$relationships[self::REL_FILE_REFS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FILE_REFS),
],
];
diff --git a/lib/classes/JsonApi/Schemas/ForumCategory.php b/lib/classes/JsonApi/Schemas/ForumCategory.php
index f26d70d..4111464 100644
--- a/lib/classes/JsonApi/Schemas/ForumCategory.php
+++ b/lib/classes/JsonApi/Schemas/ForumCategory.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
use JsonApi\Models\ForumEntry as Entry;
class ForumCategory extends SchemaProvider
@@ -11,14 +12,14 @@ class ForumCategory extends SchemaProvider
const REL_COURSE = 'course';
const REL_ENTRY = 'entries';
- protected $resourceType = self::TYPE;
- public function getId($category)
+
+ public function getId($category): ?string
{
return $category->id;
}
- public function getAttributes($category)
+ public function getAttributes($category, ContextInterface $context): iterable
{
return [
'title' => $category->entry_name,
@@ -26,8 +27,11 @@ class ForumCategory extends SchemaProvider
];
}
- public function getRelationships($category, $isPrimary, array $includeList)
+ public function getRelationships($category, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
$relationships = $this->addCourseRelationship($category, $isPrimary, $includeList);
@@ -39,14 +43,14 @@ class ForumCategory extends SchemaProvider
public function addCourseRelationship($category, $isPrimary, $includeList)
{
- $link = new Link('/courses/'.$category->seminar_id);
$data = $isPrimary && in_array(self::REL_COURSE, $includeList)
? \Course::find($category->seminar_id)
: \Course::buildExisting(['id' => $category->seminar_id]);
+ $link = $this->createLinkToResource($data);
$relationships = [
self::REL_COURSE => [
- self::LINKS => [Link::RELATED => $link],
- self::DATA => $data,
+ self::RELATIONSHIP_LINKS => [Link::RELATED => $link],
+ self::RELATIONSHIP_DATA => $data,
],
];
@@ -59,10 +63,10 @@ class ForumCategory extends SchemaProvider
private function addEntryRelationship($category, $isPrimary, $includeList)
{
$data = Entry::getEntriesFromCat($category);
- $link = new Link('/forum-categories/'.($category->id).'/entries');
+ $link = $this->getRelationshipRelatedLink($category, self::REL_ENTRY);
$relationships[self::REL_ENTRY] = [
- self::DATA => $data,
- self::LINKS => [
+ self::RELATIONSHIP_DATA => $data,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $link,
],
];
diff --git a/lib/classes/JsonApi/Schemas/ForumEntry.php b/lib/classes/JsonApi/Schemas/ForumEntry.php
index 10a6e21..e99be46 100644
--- a/lib/classes/JsonApi/Schemas/ForumEntry.php
+++ b/lib/classes/JsonApi/Schemas/ForumEntry.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Schema\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
use JsonApi\Models\ForumCat;
class ForumEntry extends SchemaProvider
@@ -11,14 +12,12 @@ class ForumEntry extends SchemaProvider
const REL_CAT = 'category';
const REL_ENTRY = 'entries';
- protected $resourceType = self::TYPE;
-
- public function getId($entry)
+ public function getId($entry): ?string
{
return $entry->topic_id;
}
- public function getAttributes($entry)
+ public function getAttributes($entry, ContextInterface $context): iterable
{
return [
'title' => $entry->name,
@@ -30,8 +29,11 @@ class ForumEntry extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($entry, $isPrimary, array $includeList)
+ public function getRelationships($entry, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
$relationships = $this->addCategoryRelationship($relationships, $entry, $includeList);
@@ -43,16 +45,16 @@ class ForumEntry extends SchemaProvider
private function addCategoryRelationship($relationships, $entry, $includeList)
{
- $cat_link = new Link('/forum-categories/'.($entry->category)->id);
+ $cat_link = $this->createLinkToResource($entry->category);
$cat_data = in_array(self::REL_CAT, $includeList)
? ForumCat::find($entry->category->id)
: ForumCat::buildExisting(['id' => $entry->category->id]);
$relationships[self::REL_CAT] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $cat_link,
],
- self::DATA => $cat_data,
+ self::RELATIONSHIP_DATA => $cat_data,
];
return $relationships;
@@ -64,9 +66,9 @@ class ForumEntry extends SchemaProvider
private function addChildEntryRelationship($relationships, $entry, $includeList)
{
$relationships[self::REL_ENTRY] = [
- self::DATA => $entry->getChildEntries($entry->id),
+ self::RELATIONSHIP_DATA => $entry->getChildEntries($entry->id),
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($entry, self::REL_ENTRY),
],
];
diff --git a/lib/classes/JsonApi/Schemas/Institute.php b/lib/classes/JsonApi/Schemas/Institute.php
index bc3c2e2..0ee99d9 100644
--- a/lib/classes/JsonApi/Schemas/Institute.php
+++ b/lib/classes/JsonApi/Schemas/Institute.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Institute extends SchemaProvider
{
@@ -13,14 +14,12 @@ class Institute extends SchemaProvider
const REL_FOLDERS = 'folders';
const REL_STATUS_GROUPS = 'status-groups';
- protected $resourceType = self::TYPE;
-
- public function getId($institute)
+ public function getId($institute): ?string
{
return $institute->id;
}
- public function getAttributes($institute)
+ public function getAttributes($institute, ContextInterface $context): iterable
{
return [
'name' => $institute['Name'],
@@ -37,8 +36,11 @@ class Institute extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
@@ -47,20 +49,20 @@ class Institute extends SchemaProvider
$filesLink = $this->getRelationshipRelatedLink($resource, self::REL_FILES);
$relationships[self::REL_FILES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $filesLink,
],
];
$foldersLink = $this->getRelationshipRelatedLink($resource, self::REL_FOLDERS);
$relationships[self::REL_FOLDERS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $foldersLink,
],
];
$relationships[self::REL_BLUBBER] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_BLUBBER),
],
];
@@ -80,13 +82,13 @@ class Institute extends SchemaProvider
$includeData
) {
$relation = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_STATUS_GROUPS),
]
];
if ($includeData) {
$related = $resource->status_groups;
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
return array_merge($relationships, [self::REL_STATUS_GROUPS => $relation]);
diff --git a/lib/classes/JsonApi/Schemas/InstituteMember.php b/lib/classes/JsonApi/Schemas/InstituteMember.php
index 190343d..dbfe917 100644
--- a/lib/classes/JsonApi/Schemas/InstituteMember.php
+++ b/lib/classes/JsonApi/Schemas/InstituteMember.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class InstituteMember extends SchemaProvider
{
@@ -10,14 +11,14 @@ class InstituteMember extends SchemaProvider
const REL_INSTITUTE = 'institute';
const REL_USER = 'user';
- protected $resourceType = self::TYPE;
- public function getId($membership)
+
+ public function getId($membership): ?string
{
return $membership->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$defaultNull = function ($key) use ($resource) {
return $resource->$key ?: null;
@@ -40,21 +41,24 @@ class InstituteMember extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [
self::REL_USER => [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()->getSchema($resource->user)->getSelfSubLink($resource->user),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->user),
],
- self::DATA => $resource->user,
+ self::RELATIONSHIP_DATA => $resource->user,
],
self::REL_INSTITUTE => [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()->getSchema($resource->institute)->getSelfSubLink($resource->institute),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->institute),
],
- self::DATA => $resource->institute,
+ self::RELATIONSHIP_DATA => $resource->institute,
],
];
diff --git a/lib/classes/JsonApi/Schemas/LibraryFile.php b/lib/classes/JsonApi/Schemas/LibraryFile.php
index fa151db..9073acb 100644
--- a/lib/classes/JsonApi/Schemas/LibraryFile.php
+++ b/lib/classes/JsonApi/Schemas/LibraryFile.php
@@ -2,8 +2,8 @@
namespace JsonApi\Schemas;
-use JsonApi\Providers\JsonApiConfig as C;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class LibraryFile extends SchemaProvider
{
@@ -18,24 +18,29 @@ class LibraryFile extends SchemaProvider
const META_CONTENT = 'content';
- protected $resourceType = self::TYPE;
- public function getId($resource)
+
+ public function getId($resource): ?string
{
return $resource->getId();
}
- public function getPrimaryMeta($resource)
+ /**
+ * @inheritdoc
+ */
+ public function hasResourceMeta($resource): bool
{
- $link = $this->getDiContainer()->get(C::JSON_URL_PREFIX)
- .$this->getRelationshipRelatedLink($resource, self::META_CONTENT)->getSubHref();
+ return true;
+ }
+ public function getResourceMeta($resource)
+ {
return [
- 'download-url' => $link,
+ 'download-url' => $resource->getDownloadURL(),
];
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$attributes = [
'name' => $resource->getFilename(),
@@ -49,16 +54,16 @@ class LibraryFile extends SchemaProvider
'filesize' => (int) $resource->getSize()
];
- $user = $this->getDiContainer()->get('studip-current-user');
+ $userId = $this->currentUser->id;
if ($folder = $resource->getFolderType()) {
$filetype = $resource->getFileType();
$attributes = array_merge(
$attributes,
[
- 'is-readable' => $folder->isReadable($user->id),
- 'is-downloadable' => $filetype->isDownloadable($user->id),
- 'is-editable' => $filetype->isEditable($user->id),
- 'is-writable' => $filetype->isWritable($user->id),
+ 'is-readable' => $folder->isReadable($userId),
+ 'is-downloadable' => $filetype->isDownloadable($userId),
+ 'is-editable' => $filetype->isEditable($userId),
+ 'is-writable' => $filetype->isWritable($userId),
]
);
}
@@ -69,8 +74,11 @@ class LibraryFile extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships = $this->getFeedbackRelationship($relationships, $resource);
@@ -93,7 +101,7 @@ class LibraryFile extends SchemaProvider
if ($folder = $resource->getFolderType()) {
if ($folder->range_id && $folder->range_type === 'course' && \Feedback::isActivated($folder->range_id)) {
$relationships[self::REL_FEEDBACK] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FEEDBACK)
],
];
@@ -107,11 +115,9 @@ class LibraryFile extends SchemaProvider
{
if ($resource->file) {
$relationships[self::REL_FILE] = [
- self::DATA => $resource->file,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->file)
- ->getSelfSubLink($resource->file),
+ self::RELATIONSHIP_DATA => $resource->file,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($resource->file),
],
];
}
@@ -122,16 +128,15 @@ class LibraryFile extends SchemaProvider
private function addOwnerRelationship(array $relationships, \FileRef $resource)
{
$relationships[self::REL_OWNER] = [
- self::META => [
+ self::RELATIONSHIP_META => [
'name' => $resource->getAuthorName(),
],
- self::DATA => $resource->owner,
+ self::RELATIONSHIP_DATA => $resource->owner,
];
if (isset($resource->owner)) {
- $relationships[self::REL_OWNER][self::LINKS] = [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($resource->owner)->getSelfSubLink($resource->owner),
+ $relationships[self::REL_OWNER][self::RELATIONSHIP_LINKS] = [
+ Link::RELATED => $this->createLinkToResource($resource->owner),
];
}
@@ -143,11 +148,9 @@ class LibraryFile extends SchemaProvider
if ($resource->folder_id) {
$folder = $resource->getFolderType();
$relationships[self::REL_PARENT] = [
- self::DATA => $folder,
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($folder)
- ->getSelfSubLink($folder),
+ self::RELATIONSHIP_DATA => $folder,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($folder),
],
];
}
@@ -155,18 +158,17 @@ class LibraryFile extends SchemaProvider
return $relationships;
}
- private function addRangeRelationship(array $relationships, \FileRef $resource)
+ private function addRangeRelationship(array $relationships, \FileRef $resource): array
{
if ($folder = $resource->getFolderType()) {
if ($folder->range_id) {
try {
$rangeType = $folder->range_type;
if ($range = $folder->$rangeType) {
- $schema = $this->getSchemaContainer()->getSchema($range);
$relationships[self::REL_RANGE] = [
- self::DATA => $range,
- self::LINKS => [
- Link::RELATED => $schema->getSelfSubLink($range),
+ self::RELATIONSHIP_DATA => $range,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($range),
],
];
}
@@ -181,8 +183,8 @@ class LibraryFile extends SchemaProvider
private function addTermsRelationship(array $relationships, \FileRef $resource)
{
$relationships[self::REL_TERMS] = [
- self::DATA => $resource->content_terms_of_use_id ? $resource->terms_of_use : null,
- self::SHOW_SELF => true,
+ self::RELATIONSHIP_DATA => $resource->content_terms_of_use_id ? $resource->terms_of_use : null,
+ self::RELATIONSHIP_LINKS_SELF => true,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Message.php b/lib/classes/JsonApi/Schemas/Message.php
index c7f053c..211cf85 100644
--- a/lib/classes/JsonApi/Schemas/Message.php
+++ b/lib/classes/JsonApi/Schemas/Message.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class Message extends SchemaProvider
{
@@ -10,16 +11,14 @@ class Message extends SchemaProvider
const REL_SENDER = 'sender';
const REL_RECIPIENTS = 'recipients';
- protected $resourceType = self::TYPE;
-
- public function getId($message)
+ public function getId($message): ?string
{
return $message->id;
}
- public function getAttributes($message)
+ public function getAttributes($message, ContextInterface $context): iterable
{
- $user = $this->getDiContainer()->get('studip-current-user');
+ $user = $this->currentUser;
return [
'subject' => $message->subject,
@@ -31,8 +30,11 @@ class Message extends SchemaProvider
];
}
- public function getRelationships($message, $isPrimary, array $includeList)
+ public function getRelationships($message, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -54,15 +56,15 @@ class Message extends SchemaProvider
$data = null;
if ($userId) {
$data = $includeData ? \User::find($userId) : \User::build(['id' => $userId], false);
- }
- $relationships[self::REL_SENDER] = [
- // self::SHOW_SELF => true,
- self::LINKS => [
- Link::RELATED => new Link('/users/'.$userId),
- ],
- self::DATA => $data,
- ];
+ $relationships[self::REL_SENDER] = [
+ // self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($data),
+ ],
+ self::RELATIONSHIP_DATA => $data,
+ ];
+ }
return $relationships;
}
@@ -73,11 +75,8 @@ class Message extends SchemaProvider
private function getRecipientsRelationship(array $relationships, \Message $message, $includeData)
{
$relationships[self::REL_RECIPIENTS] = [
- // self::SHOW_SELF => true,
- self::LINKS => [
- // Link::RELATED => new Link('/users/'.$userId),
- ],
- self::DATA => $message->receivers->map(function ($i) { return $i->user; }),
+ // self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_DATA => $message->receivers->map(function ($i) { return $i->user; }),
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/ScheduleEntry.php b/lib/classes/JsonApi/Schemas/ScheduleEntry.php
index 7e38ef6..e737e61 100644
--- a/lib/classes/JsonApi/Schemas/ScheduleEntry.php
+++ b/lib/classes/JsonApi/Schemas/ScheduleEntry.php
@@ -2,21 +2,22 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Schema\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
class ScheduleEntry extends SchemaProvider
{
const TYPE = 'schedule-entries';
const REL_OWNER = 'owner';
- protected $resourceType = self::TYPE;
- public function getId($entry)
+
+ public function getId($entry): ?string
{
return $entry->id;
}
- public function getAttributes($entry)
+ public function getAttributes($entry, ContextInterface $context): iterable
{
return [
'title' => $entry->title,
@@ -33,16 +34,19 @@ class ScheduleEntry extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($entry, $isPrimary, array $includeList)
+ public function getRelationships($entry, ContextInterface $context): iterable
{
- $link = $this->getSchemaContainer()->getSchema($entry->user)->getSelfSubLink($entry->user);
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
+ $link = $this->createLinkToResource($entry->user);
$relationships = [
self::REL_OWNER => [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $link,
],
- self::DATA => $entry->user,
+ self::RELATIONSHIP_DATA => $entry->user,
],
];
diff --git a/lib/classes/JsonApi/Schemas/SchemaProvider.php b/lib/classes/JsonApi/Schemas/SchemaProvider.php
index b6ebdf3..5e15886 100644
--- a/lib/classes/JsonApi/Schemas/SchemaProvider.php
+++ b/lib/classes/JsonApi/Schemas/SchemaProvider.php
@@ -2,38 +2,60 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
-use Neomerx\JsonApi\Contracts\Schema\SchemaFactoryInterface;
+use JsonApi\Errors\InternalServerError;
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Schema\LinkInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Neomerx\JsonApi\Schema\BaseSchema;
-abstract class SchemaProvider extends \Neomerx\JsonApi\Schema\SchemaProvider
+abstract class SchemaProvider extends BaseSchema
{
- private $schemaContainer;
- private $diContainer;
+ /** @var SchemaContainerInterface */
+ protected $schemaContainer;
- /**
- * @param SchemaFactoryInterface $factory
- * @param ContainerInterface $factory
- */
- public function __construct(SchemaFactoryInterface $factory, ContainerInterface $schemaContainer)
+ /** @var ?\User */
+ protected $currentUser;
+
+ public function __construct(FactoryInterface $factory, SchemaContainerInterface $schemaContainer, ?\User $user)
{
+ $this->schemaContainer = $schemaContainer;
+ $this->currentUser = $user;
+
parent::__construct($factory);
+ }
- $this->schemaContainer = $schemaContainer;
- $this->diContainer = $factory->getDependencyInjectionContainer();
+ const TYPE = '';
+
+ public function getType(): string
+ {
+ return static::TYPE;
}
/**
- * Return the set schema container.
- *
- * @return ContainerInterface the schema container
+ * @inheritdoc
*/
- protected function getSchemaContainer()
+ public function isAddSelfLinkInRelationshipByDefault(string $relationshipName): bool
{
- return $this->schemaContainer;
+ return false;
}
- public function getDiContainer()
+ /**
+ * @inheritdoc
+ */
+ public function isAddRelatedLinkInRelationshipByDefault(string $relationshipName): bool
+ {
+ return false;
+ }
+
+ /**
+ * @param mixed $resource
+ */
+ public function createLinkToResource($resource): LinkInterface
{
- return $this->diContainer;
+ if (!$this->schemaContainer->hasSchema($resource)) {
+ throw new InternalServerError('Cannot create links to objects without schema.');
+ }
+
+ return $this->schemaContainer->getSchema($resource)->getSelfLink($resource);
}
}
diff --git a/lib/classes/JsonApi/Schemas/SemClass.php b/lib/classes/JsonApi/Schemas/SemClass.php
index e7fc448..694d548 100644
--- a/lib/classes/JsonApi/Schemas/SemClass.php
+++ b/lib/classes/JsonApi/Schemas/SemClass.php
@@ -2,21 +2,20 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class SemClass extends SchemaProvider
{
const REL_SEM_TYPES = 'sem-types';
const TYPE = 'sem-classes';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource['id'];
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'name' => (string) $resource['name'],
@@ -32,8 +31,11 @@ class SemClass extends SchemaProvider
];
}
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
@@ -53,14 +55,14 @@ class SemClass extends SchemaProvider
private function addSemTypesRelationship(array $relationships, $resource, $includeData)
{
$relation = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_SEM_TYPES),
- ]
+ ],
];
if ($includeData) {
$related = $resource->getSemTypes();
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
$relationships[self::REL_SEM_TYPES] = $relation;
diff --git a/lib/classes/JsonApi/Schemas/SemType.php b/lib/classes/JsonApi/Schemas/SemType.php
index 0798d74..eb44e93 100644
--- a/lib/classes/JsonApi/Schemas/SemType.php
+++ b/lib/classes/JsonApi/Schemas/SemType.php
@@ -2,21 +2,22 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class SemType extends SchemaProvider
{
const REL_SEM_CLASS = 'sem-class';
const TYPE = 'sem-types';
- protected $resourceType = self::TYPE;
- public function getId($resource)
+
+ public function getId($resource): ?string
{
return $resource['id'];
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'name' => $resource['name'],
@@ -25,19 +26,20 @@ class SemType extends SchemaProvider
];
}
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
// SemClass
$related = $resource->getClass();
$relationships[self::REL_SEM_CLASS] = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related)
],
- self::DATA => $related,
+ self::RELATIONSHIP_DATA => $related,
];
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/Semester.php b/lib/classes/JsonApi/Schemas/Semester.php
index 10b45bd..f1bca9c 100644
--- a/lib/classes/JsonApi/Schemas/Semester.php
+++ b/lib/classes/JsonApi/Schemas/Semester.php
@@ -2,18 +2,18 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class Semester extends SchemaProvider
{
const TYPE = 'semesters';
- protected $resourceType = self::TYPE;
-
- public function getId($semester)
+ public function getId($semester): ?string
{
return $semester->id;
}
- public function getAttributes($semester)
+ public function getAttributes($semester, ContextInterface $context): iterable
{
return [
'title' => (string) $semester->name,
@@ -26,4 +26,9 @@ class Semester extends SchemaProvider
'visible' => (bool) $semester->visible,
];
}
+
+ public function getRelationships($user, ContextInterface $context): iterable
+ {
+ return [];
+ }
}
diff --git a/lib/classes/JsonApi/Schemas/SeminarCycleDate.php b/lib/classes/JsonApi/Schemas/SeminarCycleDate.php
index a7476f3..531b58b 100644
--- a/lib/classes/JsonApi/Schemas/SeminarCycleDate.php
+++ b/lib/classes/JsonApi/Schemas/SeminarCycleDate.php
@@ -2,21 +2,22 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class SeminarCycleDate extends SchemaProvider
{
const TYPE = 'seminar-cycle-dates';
const REL_OWNER = 'owner';
- protected $resourceType = self::TYPE;
- public function getId($entry)
+
+ public function getId($entry): ?string
{
return $entry->id;
}
- public function getAttributes($entry)
+ public function getAttributes($entry, ContextInterface $context): iterable
{
$course = \Course::find($entry->seminar_id);
@@ -37,14 +38,17 @@ class SeminarCycleDate extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($entry, $isPrimary, array $includeList)
+ public function getRelationships($entry, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($course = \Course::find($entry->seminar_id)) {
- $link = $this->getSchemaContainer()->getSchema($course)->getSelfSubLink($course);
+ $link = $this->createLinkToResource($course);
$relationships = [
- self::REL_OWNER => [self::LINKS => [Link::RELATED => $link], self::DATA => $course],
+ self::REL_OWNER => [self::RELATIONSHIP_LINKS => [Link::RELATED => $link], self::RELATIONSHIP_DATA => $course],
];
}
diff --git a/lib/classes/JsonApi/Schemas/SlimRoute.php b/lib/classes/JsonApi/Schemas/SlimRoute.php
index 3e055e5..cc05594 100644
--- a/lib/classes/JsonApi/Schemas/SlimRoute.php
+++ b/lib/classes/JsonApi/Schemas/SlimRoute.php
@@ -2,29 +2,35 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class SlimRoute extends SchemaProvider
{
const TYPE = 'slim-routes';
- protected $resourceType = self::TYPE;
-
- public function getId($route)
+ public function getId($route): ?string
{
return $route->getIdentifier();
}
- public function getAttributes($route)
+ public function getAttributes($route, ContextInterface $context): iterable
{
return [
'methods' => $route->getMethods(),
+ 'name' => $route->getName(),
'pattern' => $route->getPattern(),
];
}
+ public function getRelationships($user, ContextInterface $context): iterable
+ {
+ return [];
+ }
+
/**
* @inheritdoc
*/
- public function getResourceLinks($resource)
+ public function getLinks($resource): iterable
{
return [];
}
diff --git a/lib/classes/JsonApi/Schemas/StatusGroup.php b/lib/classes/JsonApi/Schemas/StatusGroup.php
index bb0026c..97993e1 100644
--- a/lib/classes/JsonApi/Schemas/StatusGroup.php
+++ b/lib/classes/JsonApi/Schemas/StatusGroup.php
@@ -2,21 +2,20 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class StatusGroup extends SchemaProvider
{
const REL_RANGE = 'range';
const TYPE = 'status-groups';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->id;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
$stringOrNull = function ($item) {
return trim($item) != '' ? (string) $item : null;
@@ -42,8 +41,11 @@ class StatusGroup extends SchemaProvider
];
}
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
@@ -68,14 +70,12 @@ class StatusGroup extends SchemaProvider
$related = $this->findRange($resource);
$relation = [
- self::LINKS => [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($related)
]
];
if ($includeData) {
- $relation[self::DATA] = $related;
+ $relation[self::RELATIONSHIP_DATA] = $related;
}
return array_merge($relationships, [self::REL_RANGE => $relation]);
diff --git a/lib/classes/JsonApi/Schemas/Studip.php b/lib/classes/JsonApi/Schemas/Studip.php
index 1bf3bae..a545504 100644
--- a/lib/classes/JsonApi/Schemas/Studip.php
+++ b/lib/classes/JsonApi/Schemas/Studip.php
@@ -2,13 +2,13 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class Studip extends SchemaProvider
{
const TYPE = 'global';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->getId();
}
@@ -16,7 +16,12 @@ class Studip extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getAttributes($news)
+ public function getAttributes($news, ContextInterface $context): iterable
+ {
+ return [];
+ }
+
+ public function getRelationships($user, ContextInterface $context): iterable
{
return [];
}
diff --git a/lib/classes/JsonApi/Schemas/StudipComment.php b/lib/classes/JsonApi/Schemas/StudipComment.php
index a02af31..7ba2a2d 100644
--- a/lib/classes/JsonApi/Schemas/StudipComment.php
+++ b/lib/classes/JsonApi/Schemas/StudipComment.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class StudipComment extends SchemaProvider
{
@@ -10,14 +11,12 @@ class StudipComment extends SchemaProvider
const REL_AUTHOR = 'author';
const REL_NEWS = 'news';
- protected $resourceType = self::TYPE;
-
- public function getId($comment)
+ public function getId($comment): ?string
{
return $comment->comment_id;
}
- public function getAttributes($comment)
+ public function getAttributes($comment, ContextInterface $context): iterable
{
return [
'content' => $comment->content,
@@ -26,25 +25,31 @@ class StudipComment extends SchemaProvider
];
}
- public function getRelationships($comment, $isPrimary, array $includeList)
+ public function getRelationships($comment, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
- $relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => new Link('/users/'.$comment->user_id),
- ],
- self::DATA => \User::build(['id' => $comment->user_id], false),
- ];
- $relationships[self::REL_NEWS] = [
- self::LINKS => [
- Link::RELATED => new Link('/news/'.$comment->object_id),
- ],
- self::DATA => in_array(self::REL_NEWS, $includeList)
- ? $comment->news :
- \StudipNews::build(['id' => $comment->object_id], false),
- ];
+ if ($author = \User::find($comment->user_id)) {
+ $relationships[self::REL_AUTHOR] = [
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($author),
+ ],
+ self::RELATIONSHIP_DATA => $author,
+ ];
+ }
+
+ if ($news = \StudipNews::find($comment->object_id)) {
+ $relationships[self::REL_NEWS] = [
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($news),
+ ],
+ self::RELATIONSHIP_DATA => $news,
+ ];
+ }
}
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/StudipNews.php b/lib/classes/JsonApi/Schemas/StudipNews.php
index 6803fd8..98b2dc5 100644
--- a/lib/classes/JsonApi/Schemas/StudipNews.php
+++ b/lib/classes/JsonApi/Schemas/StudipNews.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class StudipNews extends SchemaProvider
{
@@ -11,8 +12,6 @@ class StudipNews extends SchemaProvider
const REL_COMMENTS = 'comments';
const REL_RANGES = 'ranges';
- protected $resourceType = self::TYPE;
-
public static function getRangeClasses()
{
return [
@@ -34,12 +33,12 @@ class StudipNews extends SchemaProvider
];
}
- public function getId($news)
+ public function getId($news): ?string
{
- return $news->news_id;
+ return $news->getId();
}
- public function getAttributes($news)
+ public function getAttributes($news, ContextInterface $context): iterable
{
return [
'title' => (string) $news->topic,
@@ -55,8 +54,11 @@ class StudipNews extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function getRelationships($news, $isPrimary, array $includeList)
+ public function getRelationships($news, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$relationships = $this->addAuthorRelationship($relationships, $news, $includeList);
@@ -72,10 +74,10 @@ class StudipNews extends SchemaProvider
? $news->owner
: \User::build(['id' => $news->user_id], false);
$relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => new Link('/users/'.$news->user_id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($news->owner),
],
- self::DATA => $data,
+ self::RELATIONSHIP_DATA => $data,
];
return $relationships;
@@ -87,9 +89,9 @@ class StudipNews extends SchemaProvider
private function addCommentsRelationship($relationships, $news, $includeList)
{
$relationships[self::REL_COMMENTS] = [
- self::LINKS => [
- Link::RELATED => $this->getRelationshipRelatedLink($news, self::REL_COMMENTS)
- ]
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->getRelationshipRelatedLink($news, self::REL_COMMENTS),
+ ],
];
return $relationships;
@@ -98,8 +100,8 @@ class StudipNews extends SchemaProvider
private function addRangesRelationship($relationships, $news, $includeList)
{
$relationships[self::REL_RANGES] = [
- self::SHOW_SELF => true,
- self::DATA => $this->prepareRanges($news, $includeList),
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_DATA => $this->prepareRanges($news, $includeList),
];
return $relationships;
@@ -112,7 +114,7 @@ class StudipNews extends SchemaProvider
return $news->news_ranges->map(function ($range) use ($include) {
switch ($range->type) {
case 'global':
- return $this->getDiContainer()->get('studip-system-object');
+ return new \Jsonapi\Models\Studip();
case 'sem':
return $include
diff --git a/lib/classes/JsonApi/Schemas/StudipProperty.php b/lib/classes/JsonApi/Schemas/StudipProperty.php
index d76c47a..2f23fa2 100644
--- a/lib/classes/JsonApi/Schemas/StudipProperty.php
+++ b/lib/classes/JsonApi/Schemas/StudipProperty.php
@@ -2,18 +2,18 @@
namespace JsonApi\Schemas;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+
class StudipProperty extends SchemaProvider
{
const TYPE = 'studip-properties';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource->field;
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'description' => $resource->description,
@@ -21,10 +21,15 @@ class StudipProperty extends SchemaProvider
];
}
+ public function getRelationships($resource, ContextInterface $context): iterable
+ {
+ return [];
+ }
+
/**
* @inheritdoc
*/
- public function getResourceLinks($resource)
+ public function getLinks($resource): iterable
{
return [];
}
diff --git a/lib/classes/JsonApi/Schemas/StudyArea.php b/lib/classes/JsonApi/Schemas/StudyArea.php
index 39cfae9..6ad289b 100644
--- a/lib/classes/JsonApi/Schemas/StudyArea.php
+++ b/lib/classes/JsonApi/Schemas/StudyArea.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class StudyArea extends SchemaProvider
{
@@ -12,14 +13,12 @@ class StudyArea extends SchemaProvider
const REL_PARENT = 'parent';
const TYPE = 'study-areas';
- protected $resourceType = self::TYPE;
-
- public function getId($resource)
+ public function getId($resource): ?string
{
return $resource['id'];
}
- public function getAttributes($resource)
+ public function getAttributes($resource, ContextInterface $context): iterable
{
return [
'name' => (string) $resource['name'],
@@ -29,8 +28,11 @@ class StudyArea extends SchemaProvider
];
}
- public function getRelationships($resource, $isPrimary, array $includeList)
+ public function getRelationships($resource, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
@@ -48,14 +50,14 @@ class StudyArea extends SchemaProvider
private function addChildrenRelationship(array $relationships, $resource, $includeData)
{
$relationships[self::REL_CHILDREN] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_CHILDREN),
],
];
if ($includeData) {
$children = $resource->getChildren();
- $relationships[self::REL_CHILDREN][self::DATA] = $children;
+ $relationships[self::REL_CHILDREN][self::RELATIONSHIP_DATA] = $children;
}
return $relationships;
@@ -64,14 +66,14 @@ class StudyArea extends SchemaProvider
private function addCoursesRelationship(array $relationships, $resource, $includeData)
{
$relationships[self::REL_COURSES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_COURSES),
],
];
if ($includeData) {
$children = $resource->courses;
- $relationships[self::REL_COURSES][self::DATA] = $children;
+ $relationships[self::REL_COURSES][self::RELATIONSHIP_DATA] = $children;
}
return $relationships;
@@ -80,13 +82,13 @@ class StudyArea extends SchemaProvider
private function addInstituteRelationship(array $relationships, $resource, $includeData)
{
$relationships[self::REL_INSTITUTE] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_INSTITUTE),
],
];
if ($includeData) {
- $relationships[self::REL_INSTITUTE][self::DATA] = $resource->institute;
+ $relationships[self::REL_INSTITUTE][self::RELATIONSHIP_DATA] = $resource->institute;
}
return $relationships;
@@ -95,13 +97,13 @@ class StudyArea extends SchemaProvider
private function addParentRelationship(array $relationships, $resource, $includeData)
{
$relationships[self::REL_PARENT] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_PARENT),
],
];
if ($includeData) {
- $relationships[self::REL_PARENT][self::DATA] = $resource->getParent();
+ $relationships[self::REL_PARENT][self::RELATIONSHIP_DATA] = $resource->getParent();
}
return $relationships;
diff --git a/lib/classes/JsonApi/Schemas/User.php b/lib/classes/JsonApi/Schemas/User.php
index 3bc904c..67e64d5 100644
--- a/lib/classes/JsonApi/Schemas/User.php
+++ b/lib/classes/JsonApi/Schemas/User.php
@@ -2,7 +2,9 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class User extends SchemaProvider
{
@@ -24,17 +26,11 @@ class User extends SchemaProvider
const REL_SCHEDULE = 'schedule';
/**
- * Hier wird der Typ des Schemas festgelegt.
- * {@inheritdoc}
- */
- protected $resourceType = self::TYPE;
-
- /**
* Diese Method entscheidet über die JSON-API-spezifische ID von
* \User-Objekten.
* {@inheritdoc}
*/
- public function getId($user)
+ public function getId($user): ?string
{
return $user->id;
}
@@ -44,7 +40,7 @@ class User extends SchemaProvider
* für die Ausgabe vorbereitet werden.
* {@inheritdoc}
*/
- public function getAttributes($user)
+ public function getAttributes($user, ContextInterface $context): iterable
{
$attrs = [
'username' => $user->username,
@@ -60,10 +56,10 @@ class User extends SchemaProvider
return $attrs + iterator_to_array($this->getProfileAttributes($user));
}
- private function getProfileAttributes(\User $user)
+ private function getProfileAttributes(\User $user): iterable
{
$visibilities = $this->getVisibilities($user);
- $observer = $this->getDiContainer()->get('studip-current-user');
+ $observer = $this->currentUser;
$fields = [
['phone', 'privatnr', 'private_phone'],
@@ -72,13 +68,15 @@ class User extends SchemaProvider
];
foreach ($fields as list($attr, $field, $vis)) {
- $value = ($user[$field] && is_element_visible_for_user($observer->id, $user->id, $visibilities[$vis]))
- ? strip_tags((string) $user[$field]) : null;
+ $value =
+ $user[$field] && is_element_visible_for_user($observer->id, $user->id, $visibilities[$vis])
+ ? strip_tags((string) $user[$field])
+ : null;
yield $attr => $value;
}
}
- private function getVisibilities(\User $user)
+ private function getVisibilities(\User $user): array
{
$visibilities = get_local_visibility_by_id($user->id, 'homepage');
if (is_array(json_decode($visibilities, true))) {
@@ -91,26 +89,26 @@ class User extends SchemaProvider
/**
* @inheritdoc
*/
- public function getPrimaryMeta($resource)
+ public function hasResourceMeta($resource): bool
{
- $avatar = \Avatar::getAvatar($resource->id);
-
- return [
- 'avatar' => [
- 'small' => $avatar->getURL(\Avatar::SMALL),
- 'medium' => $avatar->getURL(\Avatar::MEDIUM),
- 'normal' => $avatar->getURL(\Avatar::NORMAL),
- 'original' => $avatar->getURL(\Avatar::ORIGINAL)
- ]
- ];
+ return true;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getInclusionMeta($resource)
+ public function getResourceMeta($resource)
{
- return $this->getPrimaryMeta($resource);
+ $avatar = \Avatar::getAvatar($resource->id);
+
+ return [
+ 'avatar' => [
+ 'small' => $avatar->getURL(\Avatar::SMALL),
+ 'medium' => $avatar->getURL(\Avatar::MEDIUM),
+ 'normal' => $avatar->getURL(\Avatar::NORMAL),
+ 'original' => $avatar->getURL(\Avatar::ORIGINAL),
+ ],
+ ];
}
/**
@@ -119,8 +117,11 @@ class User extends SchemaProvider
* eines Nutzers bei Bedarf am \User.
* {@inheritdoc}
*/
- public function getRelationships($user, $isPrimary, array $includeList)
+ public function getRelationships($user, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$shouldInclude = function ($key) use ($isPrimary, $includeList) {
return $isPrimary && in_array($key, $includeList);
};
@@ -140,7 +141,7 @@ class User extends SchemaProvider
$relationships = $this->getConfigValuesRelationship(
$relationships,
$user,
- $shouldInclude(self::REL_CONTACTS)
+ $shouldInclude(self::REL_CONFIG_VALUES)
);
$relationships = $this->getContactsRelationship(
$relationships,
@@ -157,46 +158,18 @@ class User extends SchemaProvider
$user,
$shouldInclude(self::REL_COURSE_MEMBERSHIPS)
);
- $relationships = $this->getEventsRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_EVENTS)
- );
- $relationships = $this->getFileRefsRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_FILES)
- );
- $relationships = $this->getFoldersRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_FOLDERS)
- );
- $relationships = $this->getInboxRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_INBOX)
- );
+ $relationships = $this->getEventsRelationship($relationships, $user, $shouldInclude(self::REL_EVENTS));
+ $relationships = $this->getFileRefsRelationship($relationships, $user, $shouldInclude(self::REL_FILES));
+ $relationships = $this->getFoldersRelationship($relationships, $user, $shouldInclude(self::REL_FOLDERS));
+ $relationships = $this->getInboxRelationship($relationships, $user, $shouldInclude(self::REL_INBOX));
$relationships = $this->getInstituteMembershipsRelationship(
$relationships,
$user,
$shouldInclude(self::REL_INSTITUTE_MEMBERSHIPS)
);
- $relationships = $this->getNewsRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_NEWS)
- );
- $relationships = $this->getOutboxRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_OUTBOX)
- );
- $relationships = $this->getScheduleRelationship(
- $relationships,
- $user,
- $shouldInclude(self::REL_SCHEDULE)
- );
+ $relationships = $this->getNewsRelationship($relationships, $user, $shouldInclude(self::REL_NEWS));
+ $relationships = $this->getOutboxRelationship($relationships, $user, $shouldInclude(self::REL_OUTBOX));
+ $relationships = $this->getScheduleRelationship($relationships, $user, $shouldInclude(self::REL_SCHEDULE));
}
return $relationships;
@@ -205,13 +178,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getActivityStreamRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getActivityStreamRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_ACTIVITYSTREAM] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_ACTIVITYSTREAM),
],
];
@@ -222,13 +192,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getBlubberRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getBlubberRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_BLUBBER] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_BLUBBER),
],
];
@@ -239,14 +206,11 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getConfigValuesRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getConfigValuesRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_CONFIG_VALUES] = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_CONFIG_VALUES),
],
];
@@ -257,14 +221,11 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getContactsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getContactsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_CONTACTS] = [
- self::SHOW_SELF => true,
- self::LINKS => [
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_CONTACTS),
],
];
@@ -275,13 +236,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getCoursesRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getCoursesRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_COURSES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_COURSES),
],
];
@@ -292,13 +250,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getCourseMembershipsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getCourseMembershipsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_COURSE_MEMBERSHIPS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_COURSE_MEMBERSHIPS),
],
];
@@ -309,13 +264,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getFileRefsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getFileRefsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_FILES] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_FILES),
],
];
@@ -326,13 +278,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getFoldersRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getFoldersRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_FOLDERS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_FOLDERS),
],
];
@@ -343,13 +292,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getInboxRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getInboxRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_INBOX] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_INBOX),
],
];
@@ -360,13 +306,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getInstituteMembershipsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getInstituteMembershipsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_INSTITUTE_MEMBERSHIPS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_INSTITUTE_MEMBERSHIPS),
],
];
@@ -377,13 +320,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getEventsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getEventsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_EVENTS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_EVENTS),
],
];
@@ -394,13 +334,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getNewsRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getNewsRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_NEWS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_NEWS),
],
];
@@ -411,13 +348,10 @@ class User extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getOutboxRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getOutboxRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_OUTBOX] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_OUTBOX),
],
];
@@ -425,17 +359,13 @@ class User extends SchemaProvider
return $relationships;
}
-
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function getScheduleRelationship(
- array $relationships,
- \User $user,
- $includeData
- ) {
+ private function getScheduleRelationship(array $relationships, \User $user, $includeData)
+ {
$relationships[self::REL_SCHEDULE] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($user, self::REL_SCHEDULE),
],
];
diff --git a/lib/classes/JsonApi/Schemas/WikiPage.php b/lib/classes/JsonApi/Schemas/WikiPage.php
index d68390f..30d3bb9 100644
--- a/lib/classes/JsonApi/Schemas/WikiPage.php
+++ b/lib/classes/JsonApi/Schemas/WikiPage.php
@@ -2,7 +2,8 @@
namespace JsonApi\Schemas;
-use Neomerx\JsonApi\Document\Link;
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
class WikiPage extends SchemaProvider
{
@@ -15,23 +16,7 @@ class WikiPage extends SchemaProvider
const REL_PARENT = 'parent';
const REL_RANGE = 'range';
- protected $resourceType = self::TYPE;
-
- /**
- * {@inheritdoc}
- */
- public function getResourceLinks($resource)
- {
- $url = $this->getDiContainer()->get('router')->pathFor(
- 'get-wiki-page',
- ['id' => sprintf("%s_%s", $resource->range_id, $resource->keyword)]
- );
- $links = [ Link::SELF => $this->createLink($url) ];
-
- return $links;
- }
-
- public static function getRangeClasses()
+ public static function getRangeClasses(): array
{
return [
'sem' => \Course::class,
@@ -39,7 +24,7 @@ class WikiPage extends SchemaProvider
];
}
- public static function getRangeTypes()
+ public static function getRangeTypes(): array
{
return [
'sem' => Course::TYPE,
@@ -47,6 +32,11 @@ class WikiPage extends SchemaProvider
];
}
+ /**
+ * @param mixed $resource
+ *
+ * @return ?string
+ */
public static function getRangeClass($resource)
{
$classes = self::getRangeClasses();
@@ -59,6 +49,11 @@ class WikiPage extends SchemaProvider
];
}
+ /**
+ * @param mixed $resource
+ *
+ * @return ?string
+ */
public static function getRangeType($resource)
{
$types = self::getRangeTypes();
@@ -71,7 +66,7 @@ class WikiPage extends SchemaProvider
];
}
- public function getId($wiki)
+ public function getId($wiki): ?string
{
return sprintf(
'%s_%s',
@@ -80,7 +75,7 @@ class WikiPage extends SchemaProvider
);
}
- public function getAttributes($wiki)
+ public function getAttributes($wiki, ContextInterface $context): iterable
{
return [
'keyword' => $wiki->keyword,
@@ -90,8 +85,11 @@ class WikiPage extends SchemaProvider
];
}
- public function getRelationships($wiki, $isPrimary, array $includeList)
+ public function getRelationships($wiki, ContextInterface $context): iterable
{
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ $includeList = $context->getIncludePaths();
+
$relationships = [];
if ($isPrimary) {
@@ -105,18 +103,16 @@ class WikiPage extends SchemaProvider
return $relationships;
}
- private function addParentRelationship($relationships, $wiki, $includeList)
+ private function addParentRelationship(array $relationships, \WikiPage $wiki, array $includeList): array
{
$related = $wiki->parent;
$relationships[self::REL_PARENT] = [
- self::SHOW_SELF => true,
- self::DATA => $related
+ self::RELATIONSHIP_LINKS_SELF => true,
+ self::RELATIONSHIP_DATA => $related
];
if ($related) {
- $relationships[self::REL_PARENT][self::LINKS] = [
- Link::RELATED => $this->getSchemaContainer()
- ->getSchema($related)
- ->getSelfSubLink($related)
+ $relationships[self::REL_PARENT][self::RELATIONSHIP_LINKS] = [
+ Link::RELATED => $this->createLinkToResource($related),
];
}
@@ -126,10 +122,10 @@ class WikiPage extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function addChildrenRelationship($relationships, $wiki, $includeList)
+ private function addChildrenRelationship(array $relationships, \WikiPage $wiki, array $includeList): array
{
$relationships[self::REL_CHILDREN] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($wiki, self::REL_CHILDREN),
],
];
@@ -140,10 +136,10 @@ class WikiPage extends SchemaProvider
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- private function addDescendantsRelationship($relationships, $wiki, $includeList)
+ private function addDescendantsRelationship(array $relationships, \WikiPage $wiki, array $includeList): array
{
$relationships[self::REL_DESCENDANTS] = [
- self::LINKS => [
+ self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($wiki, self::REL_DESCENDANTS),
],
];
@@ -151,37 +147,54 @@ class WikiPage extends SchemaProvider
return $relationships;
}
+ /**
+ * @param array $relationships
+ * @param \WikiPage $wiki
+ * @param array $includeList
+ *
+ * @return array
+ */
private function addAuthorRelationship($relationships, $wiki, $includeList)
{
- $data = in_array(self::REL_AUTHOR, $includeList)
- ? $wiki->author
- : \User::build(['id' => $wiki->user_id], false);
- $relationships[self::REL_AUTHOR] = [
- self::LINKS => [
- Link::RELATED => new Link('/users/' . $wiki->user_id),
- ],
- self::DATA => $data,
- ];
+ if ($wiki->author) {
+ $relationships[self::REL_AUTHOR] = [
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($wiki->author),
+ ],
+ self::RELATIONSHIP_DATA => $wiki->author,
+ ];
+ }
return $relationships;
}
+ /**
+ * @param array $relationships
+ * @param \WikiPage $wiki
+ * @param array $includeList
+ *
+ * @return array
+ */
private function addRangeRelationship($relationships, $wiki, $includeList)
{
+ $range = $this->prepareRange($wiki);
$relationships[self::REL_RANGE] = [
- self::LINKS => [
- Link::RELATED => new Link('/' . self::getRangeType($wiki) . '/' . $wiki->range_id),
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($range),
],
- self::DATA => $this->prepareRange($wiki, $includeList),
+ self::RELATIONSHIP_DATA => $range,
];
return $relationships;
}
- private function prepareRange($wiki)
+ private function prepareRange(\WikiPage $wiki): \Range
{
$class = self::getRangeClass($wiki);
- return $class::build(['id' => $wiki->range_id], false);
+ /** @var \Range $range */
+ $range = $class::build(['id' => $wiki->range_id], false);
+
+ return $range;
}
}
diff --git a/lib/classes/JsonApi/dependencies.php b/lib/classes/JsonApi/dependencies.php
new file mode 100644
index 0000000..904c817
--- /dev/null
+++ b/lib/classes/JsonApi/dependencies.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace JsonApi;
+
+use DI\ContainerBuilder;
+use JsonApi\JsonApiIntegration\QueryParser;
+use JsonApi\JsonApiIntegration\QueryParserInterface;
+use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface;
+use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
+use Neomerx\JsonApi\Contracts\Http\ResponsesInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Neomerx\JsonApi\Http\Headers\HeaderParametersParser;
+use Neomerx\JsonApi\Http\Headers\MediaType;
+use Psr\Container\ContainerInterface;
+
+return function (ContainerBuilder $containerBuilder) {
+ $containerBuilder->addDefinitions([
+ FactoryInterface::class => \DI\create(JsonApiIntegration\Factory::class),
+ HeaderParametersParserInterface::class => function (FactoryInterface $factory) {
+ return new HeaderParametersParser($factory);
+ },
+
+ SchemaContainerInterface::class => function (ContainerInterface $container, FactoryInterface $factory) {
+ $schemas = [];
+ $user = $container->get('studip-current-user');
+ foreach ($container->get('json-api-integration-schemas') as $key => $classname) {
+ $schemas[$key] = function ($schemaContainer) use ($classname, $factory, $user) {
+ return new $classname($factory, $schemaContainer, $user);
+ };
+ }
+
+ return $factory->createSchemaContainer($schemas);
+ },
+
+ EncoderInterface::class => function (
+ ContainerInterface $container,
+ FactoryInterface $factory,
+ SchemaContainerInterface $schemaContainer
+ ) {
+ $urlPrefix = $container->get('json-api-integration-urlPrefix');
+ $encoder = $factory->createEncoder($schemaContainer)->withUrlPrefix($urlPrefix);
+
+ return $encoder;
+ },
+
+ QueryParserInterface::class => function (ContainerInterface $container) {
+ $request = $container->get('request');
+ $parameters = $request->getQueryParams();
+ $queryParser = new QueryParser($parameters);
+
+ return $queryParser;
+ },
+
+ ResponsesInterface::class => function (EncoderInterface $encoder) {
+ $mediaType = new MediaType(MediaTypeInterface::JSON_API_TYPE, MediaTypeInterface::JSON_API_SUB_TYPE);
+
+ return new JsonApiIntegration\Responses($encoder, $mediaType);
+ },
+ ]);
+};
diff --git a/lib/classes/JsonApi/middleware.php b/lib/classes/JsonApi/middleware.php
new file mode 100644
index 0000000..7a318d5
--- /dev/null
+++ b/lib/classes/JsonApi/middleware.php
@@ -0,0 +1,50 @@
+<?php
+namespace JsonApi;
+
+use Slim\App;
+
+return function (App $app) {
+ /** @var \DI\Container */
+ $container = $app->getContainer();
+
+ $app->addBodyParsingMiddleware([
+ 'application/vnd.api+json' => function ($input) {
+ return json_decode($input, true);
+ },
+ ]);
+
+ // set 'request' in container
+ $app->add(function ($request, $handler) use ($container) {
+ $container->set('request', $request);
+
+ return $handler->handle($request);
+ });
+
+ $app->add(new Middlewares\StudipMockNavigation());
+ $app->add(new Middlewares\RemoveTrailingSlashes());
+
+ // Add Routing Middleware
+ $app->addRoutingMiddleware();
+
+ /** @var array|null */
+ $corsOrigin = \Config::get()->getValue('JSONAPI_CORS_ORIGIN');
+ if (is_array($corsOrigin) && count($corsOrigin)) {
+ $app->add(
+ new \Tuupola\Middleware\CorsMiddleware([
+ 'origin' => $corsOrigin,
+ 'methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
+ 'headers.allow' => [
+ 'Accept',
+ 'Accept-Encoding',
+ 'Accept-Language',
+ 'Authorization',
+ 'Content-Type',
+ 'Origin',
+ ],
+ 'headers.expose' => ['Etag'],
+ 'credentials' => true,
+ 'cache' => 86400,
+ ])
+ );
+ }
+};
diff --git a/lib/classes/JsonApi/routes.php b/lib/classes/JsonApi/routes.php
new file mode 100644
index 0000000..c0f5003
--- /dev/null
+++ b/lib/classes/JsonApi/routes.php
@@ -0,0 +1,8 @@
+<?php
+namespace JsonApi;
+
+use Slim\App;
+
+return function (App $app) {
+ $app->group('/v1', new RouteMap($app));
+};
diff --git a/lib/classes/JsonApi/settings.php b/lib/classes/JsonApi/settings.php
new file mode 100644
index 0000000..dfb8185
--- /dev/null
+++ b/lib/classes/JsonApi/settings.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace JsonApi;
+
+use DI\ContainerBuilder;
+use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
+use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
+use Psr\Container\ContainerInterface;
+
+return function (ContainerBuilder $containerBuilder) {
+ // Global Settings Object
+ $containerBuilder->addDefinitions([
+ 'studip-current-user' => function () {
+ if ($user = $GLOBALS['user']) {
+ return $user->getAuthenticatedUser();
+ }
+
+ return null;
+ },
+ 'studip-authenticator' => function () {
+ return function ($username, $password) {
+ $check = \StudipAuthAbstract::CheckAuthentication($username, $password);
+
+ if ($check['uid'] && 'nobody' != $check['uid']) {
+ return \User::find($check['uid']);
+ }
+
+ return null;
+ };
+ },
+
+ 'json-api-integration-schemas' => function () {
+ $schemaMap = new SchemaMap();
+ $coreSchemas = $schemaMap();
+
+ $allSchemas = $coreSchemas;
+ $pluginSchemas = \PluginEngine::sendMessage(Contracts\JsonApiPlugin::class, 'registerSchemas');
+ if (is_array($pluginSchemas) && count($pluginSchemas)) {
+ foreach ($pluginSchemas as $arrayOfSchemas) {
+ $allSchemas = array_merge($allSchemas, $arrayOfSchemas);
+ }
+ }
+
+ return $allSchemas;
+ },
+
+ 'json-api-integration-urlPrefix' => function () {
+ return rtrim(\URLHelper::getUrl('jsonapi.php/v1'), '/');
+ },
+
+ 'json-api-error-encoder' => function (FactoryInterface $factory) {
+ return $factory->createEncoder($factory->createSchemaContainer([]));
+ },
+ ]);
+};
diff --git a/public/jsonapi.php b/public/jsonapi.php
index 6bc8384..4b32370 100644
--- a/public/jsonapi.php
+++ b/public/jsonapi.php
@@ -1,30 +1,60 @@
<?php
-use JsonApi\AppFactory;
-use JsonApi\RouteMap;
+use DI\ContainerBuilder;
+use Slim\Factory\AppFactory;
require '../lib/bootstrap.php';
require '../composer/autoload.php';
-\StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].DIRECTORY_SEPARATOR.'vendor/oauth-php/library/');
+\StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'] . DIRECTORY_SEPARATOR . 'vendor/oauth-php/library/');
-page_open(
- [
- 'sess' => 'Seminar_Session',
- 'auth' => 'Seminar_Default_Auth',
- 'perm' => 'Seminar_Perm',
- 'user' => 'Seminar_User',
- ]
-);
+page_open([
+ 'sess' => 'Seminar_Session',
+ 'auth' => 'Seminar_Default_Auth',
+ 'perm' => 'Seminar_Perm',
+ 'user' => 'Seminar_User',
+]);
// Set base url for URLHelper class
URLHelper::setBaseUrl($GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP']);
-// create app
-$appFactory = new AppFactory();
-$app = $appFactory->makeApp();
+$containerBuilder = new ContainerBuilder();
-// add routes
-$app->group('/v1', new RouteMap($app));
+$settings = require 'lib/classes/JsonApi/settings.php';
+$settings($containerBuilder);
+$dependencies = require 'lib/classes/JsonApi/dependencies.php';
+$dependencies($containerBuilder);
+
+// Build PHP_DI Container
+$container = $containerBuilder->build();
+
+// Instantiate the app
+AppFactory::setContainer($container);
+$app = AppFactory::create();
+$container->set(\Slim\App::class, $app);
+
+// Set the base path
+$app->setBasePath('/jsonapi.php');
+
+// Register middleware
+$middleware = require 'lib/classes/JsonApi/middleware.php';
+$middleware($app);
+
+// Register routes
+$routes = require 'lib/classes/JsonApi/routes.php';
+$routes($app);
+
+// Add Error Middleware
+$displayErrors = false;
+if (defined('\\Studip\\ENV')) {
+ $displayErrors = constant('\\Studip\\ENV') === 'development';
+}
+$logError = true;
+$logErrorDetails = true;
+
+$errorMiddleware = $app->addErrorMiddleware($displayErrors, $logError, $logErrorDetails);
+$errorMiddleware->setDefaultErrorHandler(new \JsonApi\Errors\ErrorHandler($app));
+
+// Run app
$app->run();
diff --git a/tests/_support/Helper/Jsonapi.php b/tests/_support/Helper/Jsonapi.php
index 8cd78f7..e435cad 100644
--- a/tests/_support/Helper/Jsonapi.php
+++ b/tests/_support/Helper/Jsonapi.php
@@ -2,12 +2,14 @@
namespace Helper;
+use DI\ContainerBuilder;
+use JsonApi\Errors\JsonApiErrorRenderer;
use JsonApi\Middlewares\Authentication;
-use JsonApi\Middlewares\JsonApi as JsonApiMiddleware;
use Psr\Http\Message\ResponseInterface;
-use Slim\Http\Environment;
-use Slim\Http\Request;
-use Slim\Http\Response;
+use Slim\Factory\AppFactory;
+use Slim\Interfaces\ErrorHandlerInterface;
+use Slim\Psr7\Factory\ServerRequestFactory;
+use Slim\Psr7\Request;
use WoohooLabs\Yang\JsonApi\Request\JsonApiRequestBuilder;
use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
@@ -17,9 +19,15 @@ use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
class Jsonapi extends \Codeception\Module
{
/**
+ * @param array $credentials
+ * @param callable $function
+ *
+ * @return mixed
+ *
* @SuppressWarnings(PHPMD.Superglobals)
*/
- public function withPHPLib($credentials, $function) {
+ public function withPHPLib($credentials, $function)
+ {
// EVIL HACK
$oldPerm = $GLOBALS['perm'];
$oldUser = $GLOBALS['user'];
@@ -35,112 +43,154 @@ class Jsonapi extends \Codeception\Module
return $result;
}
+ /**
+ * @param array $credentials
+ * @param string $method
+ * @param string $pattern
+ * @param callable $callable
+ * @param ?string $name
+ *
+ * @return \Slim\App
+ */
public function createApp($credentials, $method, $pattern, $callable, $name = null)
{
- return $this->createApp0(
- $credentials,
- function () use ($method, $pattern, $callable, $name) {
- $route = $this->map([$method], $pattern, $callable);
- if (isset($name)) {
- $route->setName($name);
- }
+ return $this->createApp0($credentials, function ($app) use ($method, $pattern, $callable, $name) {
+ $route = $app->map([strtoupper($method)], $pattern, $callable);
+ if (isset($name)) {
+ $route->setName($name);
}
- );
+ });
}
+ /**
+ * @param array|null $credentials
+ *
+ * @return JsonApiRequestBuilder
+ */
public function createRequestBuilder($credentials = null)
{
- $env = [];
+ $serverParams = [];
if ($credentials) {
- $env = [
+ $serverParams = [
'PHP_AUTH_USER' => $credentials['username'],
'PHP_AUTH_PW' => $credentials['password'],
];
}
+ $factory = new ServerRequestFactory();
+ $request = $factory->createServerRequest('GET', '', $serverParams);
- $requestBuilder = new JsonApiRequestBuilder(
- Request::createFromEnvironment(
- Environment::mock($env)
- )
- );
+ $requestBuilder = new JsonApiRequestBuilder($request);
- $requestBuilder
- ->setProtocolVersion('1.0')
- ->setHeader('Accept-Charset', 'utf-8');
+ $requestBuilder->setProtocolVersion('1.0')->setHeader('Accept-Charset', 'utf-8');
return $requestBuilder;
}
+ /**
+ * @param \Slim\App $app
+ *
+ * @return JsonApiResponse
+ */
public function sendMockRequest($app, Request $request)
{
+ /** @var \DI\Container */
$container = $app->getContainer();
- $container['request'] = function ($container) use ($request) {
- return $request;
- };
- $response = $app($request, new Response());
+ $container->set('request', $request);
+
+ $response = $app->handle($request);
return new JsonApiResponse($response);
}
- private function createApp0($credentials, $routerFn)
+ /**
+ * @param array|null $credentials
+ *
+ * @SuppressWarnings(PHPMD.Superglobals)
+ */
+ private function createApp0($credentials, callable $routerFn): \Slim\App
{
$app = $this->appFactory();
- $authenticator = function ($username, $password) use ($credentials) {
- // must return a \User
- if ($username === $credentials['username'] && $password === $credentials['password']) {
- return \User::find($credentials['id']);
- }
-
- return null;
- };
-
$group = $app->group('', $routerFn);
if ($credentials) {
- $group->add(function ($request, $response, $next) {
- $user = $request->getAttribute(Authentication::USER_KEY, null);
-
- $GLOBALS['auth'] = new \Seminar_Auth();
- $GLOBALS['auth']->auth = array(
- 'uid' => $user->user_id,
- 'uname' => $user->username,
- 'perm' => $user->perms,
- );
-
- $GLOBALS['user'] = new \Seminar_User($user->user_id);
+ $authenticator = function ($username, $password) use ($credentials) {
+ // must return a \User
+ if ($username === $credentials['username'] && $password === $credentials['password']) {
+ $user = \User::find($credentials['id']);
- $GLOBALS['perm'] = new \Seminar_Perm();
- $GLOBALS['MAIL_VALIDATE_BOX'] = false;
+ return $user;
+ }
- return $next($request, $response);
- })->add(new Authentication($authenticator));
+ return null;
+ };
+
+ $group
+ ->add(function ($request, $handler) {
+ $user = $request->getAttribute(Authentication::USER_KEY, null);
+
+ $GLOBALS['auth'] = new \Seminar_Auth();
+ $GLOBALS['auth']->auth = [
+ 'uid' => $user->id,
+ 'uname' => $user->username,
+ 'perm' => $user->perms,
+ ];
+ $GLOBALS['user'] = new \Seminar_User($user->id);
+ $GLOBALS['perm'] = new \Seminar_Perm();
+ $GLOBALS['MAIL_VALIDATE_BOX'] = false;
+ $y = new \Seminar_User($user->id);
+ $x = $y->getAuthenticatedUser();
+
+
+ $dbManager = \DBManager::get();
+ $stmt = $dbManager->prepare("SELECT * FROM auth_user_md5 LEFT JOIN user_info USING (user_id) WHERE user_id = ?");
+ $stmt->execute([$user->id]);
+
+ return $handler->handle($request);
+ })
+ ->add(new Authentication($authenticator));
}
- $group->add(new JsonApiMiddleware($app));
-
return $app;
}
- private function appFactory()
+ private function appFactory(): \Slim\App
{
- $factory = new \JsonApi\AppFactory();
+ $containerBuilder = new ContainerBuilder();
+
+ $settings = require 'lib/classes/JsonApi/settings.php';
+ $settings($containerBuilder);
- return $factory->makeApp();
+ $dependencies = require 'lib/classes/JsonApi/dependencies.php';
+ $dependencies($containerBuilder);
+
+ // Build PHP_DI Container
+ $container = $containerBuilder->build();
+
+ // Instantiate the app
+ AppFactory::setContainer($container);
+ $app = AppFactory::create();
+ $container->set(\Slim\App::class, $app);
+
+ // Register middleware
+ $middleware = require 'lib/classes/JsonApi/middleware.php';
+ $middleware($app);
+
+ // Add Error Middleware
+ $errorMiddleware = $app->addErrorMiddleware(true, true, true);
+ $errorMiddleware->setDefaultErrorHandler(new \JsonApi\Errors\ErrorHandler($app));
+
+ return $app;
}
public function storeJsonMD(
- $filename,
+ string $filename,
ResponseInterface $response,
- $limit = null,
- $ellipsis = null
- ) {
+ int $limit = null,
+ string $ellipsis = null
+ ): string {
$body = "{$response->getBody()}";
- $body = preg_replace(
- '!plugins.php\\\\/argonautsplugin!',
- 'https:\\/\\/example.com',
- $body
- );
+ $body = preg_replace('!plugins.php\\\\/argonautsplugin!', 'https:\\/\\/example.com', $body);
$body = preg_replace('!\\\\/!', '/', $body);
$body = preg_replace(['!%5B!', '!%5D!'], ['[', ']'], $body);
@@ -156,19 +206,19 @@ class Jsonapi extends \Codeception\Module
$jsonPretty = new \Camspiers\JsonPretty\JsonPretty();
$json = $jsonPretty->prettify($jsonBody, JSON_UNESCAPED_SLASHES, ' ');
- $dirname = codecept_output_dir().'json-for-slate/';
+ $dirname = codecept_output_dir() . 'json-for-slate/';
if (!file_exists($dirname)) {
@mkdir($dirname);
}
if (file_exists($dirname)) {
- if (substr($filename, -3) !== '.md') {
+ if ('.md' !== substr($filename, -3)) {
$filename .= '.md';
}
- if ($filename[0] !== '_') {
- $filename = '_'.$filename;
+ if ('_' !== $filename[0]) {
+ $filename = '_' . $filename;
}
- file_put_contents($dirname.$filename, "```json\n".$json."\n```\n");
+ file_put_contents($dirname . $filename, "```json\n" . $json . "\n```\n");
}
return $json;
diff --git a/tests/_support/Helper/StudipPDO.php b/tests/_support/Helper/StudipPDO.php
deleted file mode 100644
index b090f3d..0000000
--- a/tests/_support/Helper/StudipPDO.php
+++ /dev/null
@@ -1,649 +0,0 @@
-<?php
-/**
- * StudipPDO.class.php - Stud.IP PDO class.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * @author Elmar Ludwig
- * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
- *
- * @category Stud.IP
- */
-
-/**
- * This is a special variant of the standard PDO class that does
- * not allow multiple statement execution.
- */
-class StudipPDO extends PDO
-{
- const PARAM_ARRAY = 100;
- const PARAM_COLUMN = 101;
-
- // Counter for the queries sent to the database
- public $query_count = 0;
-
- /**
- * Verifies that the given SQL query only contains a single statement.
- *
- * @param string SQL statement to check
- *
- * @throws PDOException when the query contains multiple statements
- */
- protected function verify($statement)
- {
- if (mb_strpos($statement, ';') !== false) {
- if (preg_match('/;\s*\S/', self::replaceStrings($statement))) {
- throw new PDOException('multiple statement execution not allowed');
- }
- }
-
- // Count executed queries (this is placed here since this is the only
- // method that is executed on every call to the database)
- $this->query_count += 1;
- }
-
- /**
- * Replaces all string literals in the statement with placeholders.
- *
- * @param string SQL statement
- *
- * @return string modified SQL statement
- */
- protected static function replaceStrings($statement)
- {
- $count = mb_substr_count($statement, '"') + mb_substr_count($statement, "'") + mb_substr_count($statement, '\\');
-
- // use fast preg_replace() variant if possible
- if ($count < 1000) {
- $result = preg_replace('/"(""|\\\\.|[^\\\\"]+)*"|\'(\'\'|\\\\.|[^\\\\\']+)*\'/s', '?', $statement);
- }
-
- if (!isset($result)) {
- // split string into parts at quotes and backslash
- $parts = preg_split('/([\\\\"\'])/', $statement, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
- $result = '';
-
- for ($part = current($parts); $part !== false; $part = next($parts)) {
- // inside quotes, "" is ", '' is ' and \x is x
- if ($quote_chr !== null) {
- if ($part === $quote_chr) {
- $part = next($parts);
-
- if ($part !== $quote_chr) {
- // backtrack and terminate string
- prev($parts);
- $result .= '?';
- $quote_chr = null;
- }
- } elseif ($part === '\\') {
- // skip next part
- next($parts);
- }
- } elseif ($part === "'" || $part === '"') {
- $quote_chr = $part;
- $saved_pos = key($parts);
- } else {
- $result .= $part;
- }
- }
-
- if ($quote_chr !== null) {
- // unterminated quote: copy to end of string
- $result .= implode(array_slice($parts, $saved_pos));
- }
- }
-
- return $result;
- }
-
- /**
- * Quotes the given value in a form appropriate for the type.
- * If no explicit type is given, the value's PHP type is used.
- *
- * @param string PHP value to quote
- * @param int parameter type (e.g. PDO::PARAM_STR)
- *
- * @return string quoted SQL string
- */
- public function quote($value, $type = null)
- {
- if (!isset($type)) {
- if (is_null($value)) {
- $type = PDO::PARAM_NULL;
- } elseif (is_bool($value)) {
- $type = PDO::PARAM_BOOL;
- } elseif (is_int($value)) {
- $type = PDO::PARAM_INT;
- } elseif (is_array($value)) {
- $type = self::PARAM_ARRAY;
- } else {
- $type = PDO::PARAM_STR;
- }
- }
-
- switch ($type) {
- case PDO::PARAM_NULL:
- return 'NULL';
- case PDO::PARAM_BOOL:
- return $value ? '1' : '0';
- case PDO::PARAM_INT:
- return (int) $value;
- case self::PARAM_ARRAY:
- return is_array($value) && count($value) ? join(',', array_map(array($this, 'quote'), $value)) : 'NULL';
- case self::PARAM_COLUMN:
- return preg_replace('/\\W/', '', $value);
- default:
- return parent::quote($value);
- }
- }
-
- /**
- * Executes an SQL statement and returns the number of affected rows.
- *
- * @param string SQL statement
- *
- * @return int number of affected rows
- */
- public function exec($statement)
- {
- $this->verify($statement);
-
- return parent::exec($statement);
- }
-
- /**
- * Executes an SQL statement, returning a result set as a statement object.
- *
- * @param string SQL statement
- * @param int fetch mode (optional)
- * @param mixed fetch mode parameter (see PDOStatement::setFetchMode)
- * @param mixed fetch mode parameter (see PDOStatement::setFetchMode)
- *
- * @return object PDOStatement object
- */
- public function query($statement, $mode = null, $arg1 = null, $arg2 = null)
- {
- $this->verify($statement);
-
- if (isset($mode)) {
- $stmt = parent::query($statement, $mode, $arg1, $arg2);
- } else {
- $stmt = parent::query($statement);
- }
-
- $studip_stmt = new StudipPDOStatement($this, $statement, array());
- $studip_stmt->setStatement($stmt);
-
- return $studip_stmt;
- }
-
- /**
- * Prepares a statement for execution and returns a statement object.
- *
- * @param string SQL statement
- *
- * @return object PDOStatement object
- */
- public function prepare($statement, $driver_options = array())
- {
- $this->verify($statement);
-
- return new StudipPDOStatement($this, $statement, $driver_options);
- }
-
- /**
- * This method is intended only for use by the StudipPDOStatement class.
- *
- * @param string SQL statement
- *
- * @return object PDOStatement object
- */
- public function prepareStatement($statement, $driver_options = array())
- {
- return parent::prepare($statement, $driver_options);
- }
-
- /**
- * Executes sql statement with given parameters,
- * returns number of affected rows, use only for INSERT,UPDATE etc.
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- *
- * @return int number of affected rows
- */
- public function execute($statement, $input_parameters = null)
- {
- $st = $this->prepare($statement);
- $ok = $st->execute($input_parameters);
- if ($ok === true) {
- return $st->rowCount();
- }
- }
-
- /**
- * Executes sql statement with given parameters, and fetch results
- * as sequential array, each row as associative array
- * optionally apply given callable on each row, with current row and key as parameter.
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param callable $callable callable to be applied to each of the rows
- *
- * @return array result set as array of assoc arrays
- */
- public function fetchAll($statement, $input_parameters = null, $callable = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
- if (is_callable($callable)) {
- $data = array();
- $st->setFetchMode(PDO::FETCH_ASSOC);
- foreach ($st as $key => $row) {
- $data[$key] = call_user_func($callable, $row, $key);
- }
- } else {
- $data = $st->fetchAll(PDO::FETCH_ASSOC);
- }
-
- return $data;
- }
-
- /**
- * Executes sql statement with given parameters, and fetch only
- * the values from first column as sequential array
- * optionally apply given callable on each row, with current value and key as parameter.
- *
- * @see StudipPDOStatement::fetchFirst()
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param callable $callable callable to be applied to each of the rows
- *
- * @return array result set
- */
- public function fetchFirst($statement, $input_parameters = null, $callable = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
- $data = $st->fetchFirst();
- if (is_callable($callable)) {
- foreach ($data as $key => $row) {
- $data[$key] = call_user_func($callable, $row, $key);
- }
- }
-
- return $data;
- }
-
- /**
- * Executes sql statement with given parameters, and fetch results
- * as associative array, first columns value is used as a key, the others are grouped
- * optionally apply given callable on each grouped row, with current row and key as parameter
- * if no callable is given, 'current' is used, to return the first entry of the grouped row.
- *
- * @see StudipPDOStatement::fetchGrouped()
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param callable $callable callable to be applied to each of the rows
- *
- * @return array result set
- */
- public function fetchGrouped($statement, $input_parameters = null, $callable = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
- $data = $st->fetchGrouped(PDO::FETCH_ASSOC, is_null($callable) ? 'current' : null);
- if (is_callable($callable)) {
- foreach ($data as $key => $row) {
- $data[$key] = call_user_func($callable, $row, $key);
- }
- }
-
- return $data;
- }
-
- /**
- * Executes sql statement with given parameters, and fetch results
- * as associative array, first columns value is used as a key, the other one is grouped
- * use only when selecting 2 columns
- * optionally apply given callable on each grouped row, with current row and key as parameter.
- *
- * @see StudipPDOStatement::fetchGroupedPairs()
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param callable $callable callable to be applied to each of the rows
- *
- * @return array result set
- */
- public function fetchGroupedPairs($statement, $input_parameters = null, $callable = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
- $data = $st->fetchGroupedPairs();
- if (is_callable($callable)) {
- foreach ($data as $key => $row) {
- $data[$key] = call_user_func($callable, $row, $key);
- }
- }
-
- return $data;
- }
-
- /**
- * Executes sql statement with given parameters, and fetch results
- * as associative array, first columns value is used as a key, the other one as the value
- * use only when selecting 2 columns
- * optionally apply given callable on each grouped row, with current row and key as parameter.
- *
- * @see StudipPDOStatement::fetchGroupedPairs()
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param callable $callable callable to be applied to each of the rows
- *
- * @return array result set
- */
- public function fetchPairs($statement, $input_parameters = null, $callable = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
- $data = $st->fetchPairs();
- if (is_callable($callable)) {
- foreach ($data as $key => $row) {
- $data[$key] = call_user_func($callable, $row, $key);
- }
- }
-
- return $data;
- }
-
- /**
- * Executes sql statement with given parameters, and fetch only the first row
- * as associative array.
- *
- * @see StudipPDOStatement::fetchOne()
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- *
- * @return array first row of result set
- */
- public function fetchOne($statement, $input_parameters = null)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
-
- return $st->fetchOne();
- }
-
- /**
- * Executes sql statement with given parameters, and fetch only the value of one column
- * third param denotes the column, zero indexed.
- *
- * @param string $statement SQL statement to execute
- * @param array $input_parameters parameters for statement
- * @param int $column number of column to fetch
- *
- * @return string value of chosen column
- */
- public function fetchColumn($statement, $input_parameters = null, $column = 0)
- {
- $st = $this->prepare($statement);
- $st->execute($input_parameters);
-
- return $st->fetchColumn($column);
- }
-}
-
-/**
- * This is a "fake" PDOStatement implementation that behaves mostly like
- * a real statement object, but has some additional features:.
- *
- * - Parameters passed to execute() are quoted according to their PHP type.
- * - A PHP NULL value will result in an actual SQL NULL value in the query.
- * - Array types are supported for all placeholders ("WHERE value IN (?)").
- * - Positional and named parameters can be mixed in the same query.
- */
-class StudipPDOStatement implements IteratorAggregate
-{
- protected $db;
- protected $query;
- protected $options;
- protected $columns;
- protected $params;
- protected $count;
- protected $stmt;
-
- /**
- * Initializes a new StudipPDOStatement instance.
- */
- public function __construct($db, $query, $options)
- {
- $this->db = $db;
- $this->query = $query;
- $this->options = $options;
- $this->params = array();
- }
-
- /**
- * Injects a PDOStatement.
- */
- public function setStatement(PDOStatement $statement)
- {
- $this->stmt = $statement;
- }
-
- /**
- * Arranges to have a particular variable bound to a given column in
- * the result-set from a query. Each call to fetch() or fetchAll()
- * will update all the variables that are bound to columns.
- */
- public function bindColumn($column, &$param/*, ...*/)
- {
- $args = func_get_args();
- $args[1] = &$param;
- $this->columns[] = $args;
-
- return true;
- }
-
- /**
- * Binds a PHP variable to a corresponding named or question mark place-
- * holder in the SQL statement that was used to prepare the statement.
- * Unlike bindValue(), the variable is bound as a reference and will
- * only be evaluated at the time that execute() is called.
- */
- public function bindParam($parameter, &$variable, $data_type = null)
- {
- if (is_string($parameter) && $parameter[0] !== ':') {
- $parameter = ':'.$parameter;
- }
-
- $this->params[$parameter] = array('value' => &$variable, 'type' => $data_type);
-
- return true;
- }
-
- /**
- * Binds a value to a corresponding named or question mark placeholder
- * in the SQL statement that was used to prepare the statement.
- */
- public function bindValue($parameter, $value, $data_type = null)
- {
- if (is_string($parameter) && $parameter[0] !== ':') {
- $parameter = ':'.$parameter;
- }
-
- $this->params[$parameter] = array('value' => $value, 'type' => $data_type);
-
- return true;
- }
-
- /**
- * Forwards all unknown methods to the actual statement object.
- */
- public function __call($name, array $arguments)
- {
- $callable = array($this->stmt, $name);
- if (!is_callable($callable)) {
- throw new BadMethodCallException();
- }
-
- return call_user_func_array($callable, $arguments);
- }
-
- /**
- * Forwards all Iterator methods to the actual statement object.
- */
- public function getIterator()
- {
- return $this->stmt;
- }
-
- /**
- * Executes the prepared statement and returns a PDOStatement object.
- */
- public function execute($input_parameters = null)
- {
- // bind additional parameters from execute()
- if (isset($input_parameters)) {
- foreach ($input_parameters as $key => $value) {
- $this->bindValue(is_int($key) ? $key + 1 : $key, $value, null);
- }
- }
-
- // emulate prepared statement if necessary
- foreach ($this->params as $key => $param) {
- if ($param['type'] === StudipPDO::PARAM_ARRAY ||
- $param['type'] === StudipPDO::PARAM_COLUMN ||
- $param['type'] === null && !is_string($param['value'])) {
- $emulate_prepare = true;
- break;
- }
- }
-
- // build the actual query string and prepared statement
- if ($emulate_prepare) {
- $this->count = 1;
- $query = preg_replace_callback('/\?|:\w+/', array($this, 'replaceParam'), $this->query);
- } else {
- $query = $this->query;
- }
-
- $this->stmt = $this->db->prepareStatement($query, $this->options);
-
- // bind query parameters on the actual statement
- if (!$emulate_prepare) {
- foreach ($this->params as $key => $param) {
- $this->stmt->bindValue($key, $param['value'], $param['type']);
- }
- }
-
- // set up column bindings on the actual statement
- if (isset($this->columns)) {
- foreach ($this->columns as $args) {
- call_user_func_array(array($this->stmt, 'bindColumn'), $args);
- }
- }
-
- return $this->stmt->execute();
- }
-
- /**
- * Replaces a placeholder with the corresponding parameter value.
- * Throws an exception if there is no corresponding value.
- */
- protected function replaceParam($matches)
- {
- $name = $matches[0];
-
- if ($name == '?') {
- $key = $this->count++;
- } else {
- $key = $name;
- }
-
- if (!isset($this->params[$key])) {
- throw new PDOException('missing parameter in query: '.$key);
- }
-
- return $this->db->quote($this->params[$key]['value'], $this->params[$key]['type']);
- }
-
- /**
- * Returns the result set rows as a grouped associative array. The first field
- * of each row is used as the array's keys.
- * optionally apply given callable on each grouped row to aggregate results
- * if no callable is given, 'current' is used, to return the first entry of the grouped row.
- *
- * @param int $fetch_style Either PDO::FETCH_ASSOC or PDO::FETCH_COLUMN
- * @param callable $group_func function to aggregate grouped rows
- *
- * @return array grouped result set
- */
- public function fetchGrouped($fetch_style = PDO::FETCH_ASSOC, $group_func = 'current')
- {
- if (!($fetch_style & (PDO::FETCH_ASSOC | PDO::FETCH_COLUMN))) {
- throw new PDOException('Fetch style not supported, try FETCH_ASSOC or FETCH_COLUMN');
- }
-
- $fetch_style |= PDO::FETCH_GROUP;
- $rows = $this->fetchAll($fetch_style);
-
- return is_callable($group_func) ? array_map($group_func, $rows) : $rows;
- }
-
- /**
- * Returns the result set rows as a grouped associative array. The first field
- * of each row is used as the array's keys, the other one is grouped
- * use only when selecting 2 columns
- * optionally apply given callable on each grouped row to aggregate results.
- *
- * @param callable $group_func function to aggregate grouped rows
- *
- * @return array grouped result set
- */
- public function fetchGroupedPairs($group_func = null)
- {
- return $this->fetchGrouped(PDO::FETCH_COLUMN, $group_func);
- }
-
- /**
- * Returns result rows as associative array, first colum as key,
- * second as value. Use only when selecting 2 columns.
- *
- * @return array result set
- */
- public function fetchPairs()
- {
- return $this->fetchAll(PDO::FETCH_KEY_PAIR);
- }
-
- /**
- * Returns sequential array with values from first colum.
- *
- * @return array first row result set
- */
- public function fetchFirst()
- {
- return $this->fetchAll(PDO::FETCH_COLUMN);
- }
-
- /**
- * Returns only first row of result set as associative array.
- *
- * @return array first row result set
- */
- public function fetchOne()
- {
- $data = $this->fetch(PDO::FETCH_ASSOC);
-
- return $data ?: array();
- }
-}
diff --git a/tests/_support/_generated/JsonapiTesterActions.php b/tests/_support/_generated/JsonapiTesterActions.php
index e4f4bde..9faaeec 100644
--- a/tests/_support/_generated/JsonapiTesterActions.php
+++ b/tests/_support/_generated/JsonapiTesterActions.php
@@ -2096,6 +2096,11 @@ trait JsonapiTesterActions
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
+ * @param array $credentials
+ * @param callable $function
+ *
+ * @return mixed
+ *
* @SuppressWarnings(PHPMD.Superglobals)
* @see \Helper\Jsonapi::withPHPLib()
*/
@@ -2107,7 +2112,13 @@ trait JsonapiTesterActions
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
+ * @param array $credentials
+ * @param string $method
+ * @param string $pattern
+ * @param callable $callable
+ * @param ?string $name
*
+ * @return \Slim\App
* @see \Helper\Jsonapi::createApp()
*/
public function createApp($credentials, $method, $pattern, $callable, $name = NULL) {
@@ -2118,7 +2129,9 @@ trait JsonapiTesterActions
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
+ * @param array|null $credentials
*
+ * @return JsonApiRequestBuilder
* @see \Helper\Jsonapi::createRequestBuilder()
*/
public function createRequestBuilder($credentials = NULL) {
@@ -2129,10 +2142,12 @@ trait JsonapiTesterActions
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
+ * @param \Slim\App $app
*
+ * @return JsonApiResponse
* @see \Helper\Jsonapi::sendMockRequest()
*/
- public function sendMockRequest($app, \Slim\Http\Request $request) {
+ public function sendMockRequest($app, \Slim\Psr7\Request $request) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('sendMockRequest', func_get_args()));
}
@@ -2143,7 +2158,7 @@ trait JsonapiTesterActions
*
* @see \Helper\Jsonapi::storeJsonMD()
*/
- public function storeJsonMD($filename, \Psr\Http\Message\ResponseInterface $response, $limit = NULL, $ellipsis = NULL) {
+ public function storeJsonMD(string $filename, \Psr\Http\Message\ResponseInterface $response, ?int $limit = NULL, ?string $ellipsis = NULL): string {
return $this->getScenario()->runStep(new \Codeception\Step\Action('storeJsonMD', func_get_args()));
}
}
diff --git a/tests/jsonapi/BlubberCommentsUpdateTest.php b/tests/jsonapi/BlubberCommentsUpdateTest.php
index 7ee569d..d9f4a1e 100644
--- a/tests/jsonapi/BlubberCommentsUpdateTest.php
+++ b/tests/jsonapi/BlubberCommentsUpdateTest.php
@@ -50,13 +50,9 @@ class BlubberCommentsUpdateTest extends \Codeception\Test\Unit
$comment = $this->createBlubberComment($credentialsAutor, $thread, 'Autolykos knows him.');
$this->tester->assertEquals($num + 1, \BlubberComment::countBySQL('1'));
- $this->tester->expectThrowable(\JsonApi\Errors\AuthorizationFailedException::class, function () use (
- $credentialsDozent,
- $comment
- ) {
- $content = 'Who knows Erginos?';
- $this->updateBlubberCommentJSONAPI($credentialsDozent, $comment, $content);
- });
+ $content = 'Who knows Erginos?';
+ $response = $this->updateBlubberCommentJSONAPI($credentialsDozent, $comment, $content);
+ $this->tester->assertSame(403, $response->getStatusCode());
}
public function testUpdateOtherCommentSuccess()
diff --git a/tests/jsonapi/BlubberThreadsCreateTest.php b/tests/jsonapi/BlubberThreadsCreateTest.php
index 9bcbf41..4b275d5 100644
--- a/tests/jsonapi/BlubberThreadsCreateTest.php
+++ b/tests/jsonapi/BlubberThreadsCreateTest.php
@@ -69,14 +69,14 @@ class BlubberThreadsCreateTest extends \Codeception\Test\Unit
// given
$credentials = $this->tester->getCredentialsForTestAutor();
- $this->expectException(JsonApi\Errors\BadRequestException::class);
- $this->createThread($credentials, 'course');
+ $response = $this->createThread($credentials, 'course');
+ $this->tester->assertSame(400, $response->getStatusCode());
- $this->expectException(JsonApi\Errors\BadRequestException::class);
- $this->createThread($credentials, 'institute');
+ $response = $this->createThread($credentials, 'institute');
+ $this->tester->assertSame(400, $response->getStatusCode());
- $this->expectException(JsonApi\Errors\BadRequestException::class);
- $this->createThread($credentials, 'public');
+ $response = $this->createThread($credentials, 'public');
+ $this->tester->assertSame(400, $response->getStatusCode());
}
diff --git a/tests/jsonapi/BlubberThreadsIndexTest.php b/tests/jsonapi/BlubberThreadsIndexTest.php
index 304f6b1..ea665ab 100644
--- a/tests/jsonapi/BlubberThreadsIndexTest.php
+++ b/tests/jsonapi/BlubberThreadsIndexTest.php
@@ -118,10 +118,9 @@ class BlubberThreadsIndexTest extends \Codeception\Test\Unit
// given
$credentials = $this->tester->getCredentialsForTestAutor();
- $this->tester->expectThrowable(RecordNotFoundException::class, function () use ($credentials) {
- $courseId = 'missing';
- $this->fetchCourseThreads($credentials, $courseId);
- });
+ $courseId = 'missing';
+ $response = $this->fetchCourseThreads($credentials, $courseId);
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testIndexAllThreadsOfAnInstitute()
@@ -151,10 +150,9 @@ class BlubberThreadsIndexTest extends \Codeception\Test\Unit
// given
$credentials = $this->tester->getCredentialsForTestAutor();
- $this->tester->expectThrowable(RecordNotFoundException::class, function () use ($credentials) {
- $instituteId = 'missing';
- $this->fetchInstituteThreads($credentials, $instituteId);
- });
+ $instituteId = 'missing';
+ $response = $this->fetchInstituteThreads($credentials, $instituteId);
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testIndexAllThreadsWithSinceFilter()
@@ -265,7 +263,8 @@ class BlubberThreadsIndexTest extends \Codeception\Test\Unit
);
}
- private function fetchCourseThreads(array $credentials, string $courseId, array $filters = [])
+ private function fetchCourseThreads
+ (array $credentials, string $courseId, array $filters = [])
{
$requestBuilder = $this->tester
->createRequestBuilder($credentials)
diff --git a/tests/jsonapi/FileRefsCreateTest.php b/tests/jsonapi/FileRefsCreateTest.php
index 1e3c5b5..d58e181 100644
--- a/tests/jsonapi/FileRefsCreateTest.php
+++ b/tests/jsonapi/FileRefsCreateTest.php
@@ -1,10 +1,10 @@
-<?php
-
+><?php
use JsonApi\Errors\RecordNotFoundException;
use JsonApi\Errors\UnprocessableEntityException;
-use JsonApi\Routes\Files\FileRefsCreate;
+use JsonApi\Routes\Files\NegotiateFileRefsCreate as FileRefsCreate;
use JsonApi\Schemas\ContentTermsOfUse;
use JsonApi\Schemas\FileRef;
+use Slim\Psr7\Factory\ServerRequestFactory;
require_once 'FilesTestHelper.php';
@@ -36,13 +36,7 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$name = 'filename.jpg';
$description = 'a description';
- $response = $this->sendCreateFileRefInFolder(
- $credentials,
- $folder,
- $name,
- $description,
- $license
- );
+ $response = $this->sendCreateFileRefInFolder($credentials, $folder, $name, $description, $license);
$this->assertFileRefCreated($response, $name, $description, $license);
}
@@ -56,18 +50,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$name = 'filename.jpg';
$description = 'a description';
- $this->tester->expectThrowable(
- RecordNotFoundException::class,
- function () use ($credentials, $missingFolder, $name, $description, $license) {
- $this->sendCreateFileRefInFolder(
- $credentials,
- $missingFolder,
- $name,
- $description,
- $license
- );
- }
- );
+ $response = $this->sendCreateFileRefInFolder($credentials, $missingFolder, $name, $description, $license);
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testShouldFailOnEmptyName()
@@ -80,18 +64,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$name = '';
$description = 'a description';
- $this->tester->expectThrowable(
- UnprocessableEntityException::class,
- function () use ($credentials, $folder, $name, $description, $license) {
- $this->sendCreateFileRefInFolder(
- $credentials,
- $folder,
- $name,
- $description,
- $license
- );
- }
- );
+ $response = $this->sendCreateFileRefInFolder($credentials, $folder, $name, $description, $license);
+ $this->tester->assertSame(422, $response->getStatusCode());
}
public function testShouldFailOnMissingLicense()
@@ -103,18 +77,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$name = 'a-real-filename.gif';
$description = 'a description';
- $this->tester->expectThrowable(
- UnprocessableEntityException::class,
- function () use ($credentials, $folder, $name, $description) {
- $this->sendCreateFileRefInFolder(
- $credentials,
- $folder,
- $name,
- $description,
- null
- );
- }
- );
+ $response = $this->sendCreateFileRefInFolder($credentials, $folder, $name, $description, null);
+ $this->tester->assertSame(422, $response->getStatusCode());
}
public function testShouldCreateLinkIfSameUser()
@@ -133,8 +97,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$credentials,
$folder,
$file,
- $name = "another-name.jpg",
- $description = "another description",
+ $name = 'another-name.jpg',
+ $description = 'another description',
$license
);
@@ -162,8 +126,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$credentialsAutor,
$folder,
$file,
- $name = "another-name.jpg",
- $description = "another description",
+ $name = 'another-name.jpg',
+ $description = 'another description',
$license
);
@@ -174,20 +138,47 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$this->assertFileRefCreated($response, $name, $description, $license);
}
+ public function testShouldCreateFileRefByUpload()
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $courseId = 'a07535cf2f8a72df33c12ddfa4b53dde';
+ $folder = $this->prepareTopFolder($credentials, $courseId);
+ $license = $this->getSampleLicense();
+
+ $name = 'tiny.gif';
+ $filename = __DIR__ . '/' . $name;
+ $description = 'a description';
+ $content = base64_decode('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
+ if (!file_exists($filename)) {
+ file_put_contents($filename, $content);
+ }
+ $this->tester->assertTrue(file_exists($filename));
+ $file = new \Slim\Psr7\UploadedFile($this->fileToStreamInterface($filename), $name);
+
+ $app = $this->tester->createApp($credentials, 'POST', '/folders/{id}/file-refs', FileRefsCreate::class);
+
+ $factory = new ServerRequestFactory();
+ $serverParams = [
+ 'PHP_AUTH_USER' => $credentials['username'],
+ 'PHP_AUTH_PW' => $credentials['password'],
+ ];
+ $request = $factory->createServerRequest('POST', '/folders/' . $folder->id . '/file-refs', $serverParams);
+ $request = $request->withUploadedFiles([$file])->withHeader('Content-Type', 'multipart/form-data');
+
+ $response = $this->tester->sendMockRequest($app, $request);
+ $this->tester->assertSame(201, $response->getStatusCode());
+ $this->tester->assertArrayHasKey('Location', $response->getHeaders());
+ }
+
// **** helper functions ****
private function sendCreateFileRefInFolder($user, $folder, $name, $description, $license)
{
- $app = $this->tester->createApp(
- $user,
- 'POST',
- '/folders/{id}/file-refs',
- FileRefsCreate::class
- );
+ $app = $this->tester->createApp($user, 'POST', '/folders/{id}/file-refs', FileRefsCreate::class);
$requestBuilder = $this->tester->createRequestBuilder($user);
$requestBuilder
->setJsonApiBody($this->prepareValidFileRefBody($name, $description, $license))
- ->setUri('/folders/'.($folder->id).'/file-refs')
+ ->setUri('/folders/' . $folder->id . '/file-refs')
->create();
return $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
@@ -195,24 +186,12 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
private function sendCopyFileInFolder($credentials, $folder, $file, $name, $description, $license)
{
- $app = $this->tester->createApp(
- $credentials,
- 'POST',
- '/folders/{id}/file-refs',
- FileRefsCreate::class
- );
+ $app = $this->tester->createApp($credentials, 'POST', '/folders/{id}/file-refs', FileRefsCreate::class);
$requestBuilder = $this->tester->createRequestBuilder($credentials);
$requestBuilder
- ->setJsonApiBody(
- $this->prepareValidFileRefBody(
- $name,
- $description,
- $license,
- $file
- )
- )
- ->setUri('/folders/'.($folder->id).'/file-refs')
+ ->setJsonApiBody($this->prepareValidFileRefBody($name, $description, $license, $file))
+ ->setUri('/folders/' . $folder->id . '/file-refs')
->create();
return $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
@@ -235,4 +214,11 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
$resourceLink = $resource->relationship('terms-of-use')->firstResourceLink();
$this->tester->assertSame($license->id, $resourceLink['id']);
}
+
+ private function fileToStreamInterface(string $filename)
+ {
+ $factory = new \Slim\Psr7\Factory\StreamFactory();
+
+ return $factory->createStreamFromFile($filename);
+ }
}
diff --git a/tests/jsonapi/FileRefsDeleteTest.php b/tests/jsonapi/FileRefsDeleteTest.php
index d1813a4..8b30e0d 100644
--- a/tests/jsonapi/FileRefsDeleteTest.php
+++ b/tests/jsonapi/FileRefsDeleteTest.php
@@ -41,9 +41,8 @@ class FileRefsDeleteTest extends \Codeception\Test\Unit
$credentials = $this->tester->getCredentialsForTestDozent();
$missingId = 'missing-id';
- $this->tester->expectThrowable(RecordNotFoundException::class, function () use ($credentials, $missingId) {
- $this->sendDeleteFileRef($credentials, $missingId);
- });
+ $response = $this->sendDeleteFileRef($credentials, $missingId);
+ $this->tester->assertSame(404, $response->getStatusCode());
}
// **** helper functions ****
diff --git a/tests/jsonapi/FileRefsShowTest.php b/tests/jsonapi/FileRefsShowTest.php
index 10dc035..6fcca0a 100644
--- a/tests/jsonapi/FileRefsShowTest.php
+++ b/tests/jsonapi/FileRefsShowTest.php
@@ -45,9 +45,8 @@ class FileRefsShowTest extends \Codeception\Test\Unit
{
$credentials = $this->tester->getCredentialsForTestDozent();
- $this->tester->expectThrowable(RecordNotFoundException::class, function () use ($credentials) {
- $this->sendShowFileRef($credentials, 'missing-id');
- });
+ $response = $this->sendShowFileRef($credentials, 'missing-id');
+ $this->tester->assertSame(404, $response->getStatusCode());
}
// **** helper functions ****
diff --git a/tests/jsonapi/ForumCategoriesCreateTest.php b/tests/jsonapi/ForumCategoriesCreateTest.php
index c9a12fb..4fd96d4 100644
--- a/tests/jsonapi/ForumCategoriesCreateTest.php
+++ b/tests/jsonapi/ForumCategoriesCreateTest.php
@@ -48,25 +48,20 @@ class ForumCategoriesCreateTest extends \Codeception\Test\Unit
public function testShouldNotCreateCategory()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestAutor();
- $cat = $this->createCategory($credentials);
- $course_id = 'badCourse';
- $cat_document = $this->buildValidResourceCategory();
- $app = $this->tester->createApp($credentials, 'POST', '/courses/{id}/forum-categories', ForumCategoriesCreate::class);
+ $credentials = $this->tester->getCredentialsForTestAutor();
+ $cat = $this->createCategory($credentials);
+ $course_id = 'badCourse';
+ $cat_document = $this->buildValidResourceCategory();
+ $app = $this->tester->createApp($credentials, 'POST', '/courses/{id}/forum-categories', ForumCategoriesCreate::class);
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/courses/'.$course_id.'/forum-categories')
- ->create()
- ->setJsonApiBody($cat_document);
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/courses/'.$course_id.'/forum-categories')
+ ->create()
+ ->setJsonApiBody($cat_document);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertSame($cat->entry_name, $resourceObject->attribute('title'));
- });
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumCategoriesIndexTest.php b/tests/jsonapi/ForumCategoriesIndexTest.php
index 5ef4096..01ba294 100644
--- a/tests/jsonapi/ForumCategoriesIndexTest.php
+++ b/tests/jsonapi/ForumCategoriesIndexTest.php
@@ -39,29 +39,22 @@ class ForumCategoriesIndexTest extends \Codeception\Test\Unit
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
$this->tester->assertTrue($response->isSuccessfulDocument([200]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
}
public function testShouldNotShowCategory()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $course_id = 'a07535cf2f8a72df33c12ddfa4b53dde';
- $cat = $this->createCategory($credentials);
-
- $app = $this->tester->createApp($credentials, 'get', '/course/{id}/forum-categories', ForumCategoriesIndex::class);
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $course_id = 'a07535cf2f8a72df33c12ddfa4b53dde';
+ $cat = $this->createCategory($credentials);
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/course/badID/forum-categories')
- ->fetch();
+ $app = $this->tester->createApp($credentials, 'get', '/course/{id}/forum-categories', ForumCategoriesIndex::class);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/course/badID/forum-categories')
+ ->fetch();
- $this->tester->assertTrue($response->isSuccessfulDocument([200]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumCategoriesShowTest.php b/tests/jsonapi/ForumCategoriesShowTest.php
index 710a7b1..4e8df26 100644
--- a/tests/jsonapi/ForumCategoriesShowTest.php
+++ b/tests/jsonapi/ForumCategoriesShowTest.php
@@ -47,24 +47,16 @@ class ForumCategoriesShowTest extends \Codeception\Test\Unit
public function testShouldNotShowCategories()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
+ $credentials = $this->tester->getCredentialsForTestDozent();
- $app = $this->tester->createApp($credentials, 'get', '/forum-categories/{id}', ForumCategoriesShow::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-categories/'.'badId')
- ->fetch();
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $app = $this->tester->createApp($credentials, 'get', '/forum-categories/{id}', ForumCategoriesShow::class);
- $this->tester->assertTrue($response->isSuccessfulDocument([200]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-categories/'.'badId')
+ ->fetch();
- $this->tester->assertSame($cat->entry_name, $resourceObject->attribute('title'));
- $this->tester->assertSame((int) $cat->pos, $resourceObject->attribute('position'));
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumCategoriesUpdateTest.php b/tests/jsonapi/ForumCategoriesUpdateTest.php
index cbcc766..f2015cb 100644
--- a/tests/jsonapi/ForumCategoriesUpdateTest.php
+++ b/tests/jsonapi/ForumCategoriesUpdateTest.php
@@ -47,24 +47,18 @@ class ForumCategoriesUpdateTest extends \Codeception\Test\Unit
public function testShouldNotUpdateCategory()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestAutor();
- $cat = $this->createCategory($credentials);
- $cat_document = $this->buildValidResourceCategoryUpdate();
- $app = $this->tester->createApp($credentials, 'PATCH', '/forum-categories/{id}', ForumCategoriesUpdate::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-categories/badId')
- ->update()
- ->setJsonApiBody($cat_document);
+ $credentials = $this->tester->getCredentialsForTestAutor();
+ $cat = $this->createCategory($credentials);
+ $cat_document = $this->buildValidResourceCategoryUpdate();
+ $app = $this->tester->createApp($credentials, 'PATCH', '/forum-categories/{id}', ForumCategoriesUpdate::class);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-categories/badId')
+ ->update()
+ ->setJsonApiBody($cat_document);
- $this->tester->assertTrue($response->isSuccessfulDocument([200]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotEquals($cat->entry_name, $resourceObject->attribute('title'));
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumCategoryDeleteTest.php b/tests/jsonapi/ForumCategoryDeleteTest.php
index 2805f53..8d144f2 100644
--- a/tests/jsonapi/ForumCategoryDeleteTest.php
+++ b/tests/jsonapi/ForumCategoryDeleteTest.php
@@ -44,19 +44,17 @@ class ForumCategoryDeleteTest extends \Codeception\Test\Unit
public function testShouldNotDeleteEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $cat = $this->createCategory($credentials);
- $entry = $this->createEntry($credentials, $cat->id);
- $app = $this->tester->createApp($credentials, 'delete', '/forum-categories/{id}', ForumCategoriesDelete::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-categories/badId')
- ->delete();
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertIsEmpty(ForumCat::find($cat->id));
- });
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $cat = $this->createCategory($credentials);
+ $entry = $this->createEntry($credentials, $cat->id);
+ $app = $this->tester->createApp($credentials, 'delete', '/forum-categories/{id}', ForumCategoriesDelete::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-categories/badId')
+ ->delete();
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumEntriesCreateTest.php b/tests/jsonapi/ForumEntriesCreateTest.php
index 6f374a3..04d119e 100644
--- a/tests/jsonapi/ForumEntriesCreateTest.php
+++ b/tests/jsonapi/ForumEntriesCreateTest.php
@@ -52,27 +52,21 @@ class ForumEntriesCreateTest extends \Codeception\Test\Unit
public function testShouldNotCreateEntryForCategory()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $cat = $this->createCategory($credentials);
- $content = 'some content to test';
- $title = 'entry-test-title';
- $entry_json = $this->buildValidResourceEntry($content, $title);
- $app = $this->tester->createApp($credentials, 'post', '/forum-categories/{id}/entries', ForumCategoryEntriesCreate::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-categories/'.'badId'.'/entries')
- ->create()
- ->setJsonApiBody($entry_json);
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('title'));
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- });
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $cat = $this->createCategory($credentials);
+ $content = 'some content to test';
+ $title = 'entry-test-title';
+ $entry_json = $this->buildValidResourceEntry($content, $title);
+ $app = $this->tester->createApp($credentials, 'post', '/forum-categories/{id}/entries', ForumCategoryEntriesCreate::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-categories/'.'badId'.'/entries')
+ ->create()
+ ->setJsonApiBody($entry_json);
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testShouldCreateEntryForEntry()
@@ -101,28 +95,21 @@ class ForumEntriesCreateTest extends \Codeception\Test\Unit
public function testShouldNotCreateEntryForEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $cat = $this->createCategory($credentials);
- $entry = $this->createEntry($credentials, $cat->id);
- $content = 'some new content to test';
- $title = 'entry-test-title new';
- $entry_json = $this->buildValidResourceEntry($content, $title);
- $app = $this->tester->createApp($credentials, 'post', '/forum-entries/{id}/entries', ForumEntryEntriesCreate::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-entries/'.'badID'.'/entries')
- ->create()
- ->setJsonApiBody($entry_json);
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
-
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('title'));
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- });
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $cat = $this->createCategory($credentials);
+ $entry = $this->createEntry($credentials, $cat->id);
+ $content = 'some new content to test';
+ $title = 'entry-test-title new';
+ $entry_json = $this->buildValidResourceEntry($content, $title);
+ $app = $this->tester->createApp($credentials, 'post', '/forum-entries/{id}/entries', ForumEntryEntriesCreate::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-entries/'.'badID'.'/entries')
+ ->create()
+ ->setJsonApiBody($entry_json);
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumEntriesDeleteTest.php b/tests/jsonapi/ForumEntriesDeleteTest.php
index 5af0b89..60ae3a6 100644
--- a/tests/jsonapi/ForumEntriesDeleteTest.php
+++ b/tests/jsonapi/ForumEntriesDeleteTest.php
@@ -46,20 +46,18 @@ class ForumEntriesDeleteTest extends \Codeception\Test\Unit
public function testShouldNotDeleteEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $cat = $this->createCategory($credentials);
- $entry = $this->createEntry($credentials, $cat->id);
- $app = $this->tester->createApp($credentials, 'delete', '/forum-entries/{id}', ForumEntriesDelete::class);
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $cat = $this->createCategory($credentials);
+ $entry = $this->createEntry($credentials, $cat->id);
+ $app = $this->tester->createApp($credentials, 'delete', '/forum-entries/{id}', ForumEntriesDelete::class);
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-entries/badId')
- ->delete()
- ->setJsonApiBody($entry_json);
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-entries/badId')
+ ->delete()
+ ->setJsonApiBody($entry_json);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertIsEmpty(ForumEntry::find($entry->id));
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumEntriesShowTest.php b/tests/jsonapi/ForumEntriesShowTest.php
index 45f9e6a..2443fa6 100644
--- a/tests/jsonapi/ForumEntriesShowTest.php
+++ b/tests/jsonapi/ForumEntriesShowTest.php
@@ -61,42 +61,35 @@ class ForumEntriesShowTest extends \Codeception\Test\Unit
public function testShouldNotShowEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForRoot();
- $app = $this->tester->createApp($credentials, 'get', '/forum-entries/{id}', ForumEntriesShow::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-entries/'.'badEntry')
- ->fetch();
+ $credentials = $this->tester->getCredentialsForRoot();
+ $app = $this->tester->createApp($credentials, 'get', '/forum-entries/{id}', ForumEntriesShow::class);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-entries/'.'badEntry')
+ ->fetch();
- $this->tester->assertTrue($response->isSuccessfulDocument([200]));
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testShouldNotShowEntriesForCategory()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForRoot();
- $cat = $this->createCategory($credentials);
- $this->createEntry($credentials, $cat->id);
- $this->createEntry($credentials, $cat->id);
- $this->createEntry($credentials, $cat->id);
-
- $app = $this->tester->createApp($credentials, 'get', '/forum-categories/{id}/entries', ForumCategoryEntriesIndex::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-categories/badID/entries')
- ->fetch();
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject);
- });
+ $credentials = $this->tester->getCredentialsForRoot();
+ $cat = $this->createCategory($credentials);
+ $this->createEntry($credentials, $cat->id);
+ $this->createEntry($credentials, $cat->id);
+ $this->createEntry($credentials, $cat->id);
+
+ $app = $this->tester->createApp($credentials, 'get', '/forum-categories/{id}/entries', ForumCategoryEntriesIndex::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-categories/badID/entries')
+ ->fetch();
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testShouldShowEntriesForCategory()
@@ -116,7 +109,7 @@ class ForumEntriesShowTest extends \Codeception\Test\Unit
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
$document = $response->document();
- $resourceObject = $document->primaryResource();
+ $resourceObject = $document->primaryResources();
$this->tester->assertNotNull($resourceObject);
}
@@ -137,30 +130,26 @@ class ForumEntriesShowTest extends \Codeception\Test\Unit
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
$document = $response->document();
- $resourceObject = $document->primaryResource();
+ $resourceObject = $document->primaryResources();
$this->tester->assertNotNull($resourceObject);
}
public function testShouldNotShowEntriesForEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForRoot();
- $cat = $this->createCategory($credentials);
- $targetEntry = $this->createEntry($credentials, $cat->id);
- $this->createEntry($credentials, $targetEntry->id);
- $this->createEntry($credentials, $targetEntry->id);
- $this->createEntry($credentials, $targetEntry->id);
- $app = $this->tester->createApp($credentials, 'get', '/forum-entries/{id}/entries', ForumEntryEntriesIndex::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-entries/badTopic/entries')
- ->fetch();
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject);
- });
+ $credentials = $this->tester->getCredentialsForRoot();
+ $cat = $this->createCategory($credentials);
+ $targetEntry = $this->createEntry($credentials, $cat->id);
+ $this->createEntry($credentials, $targetEntry->id);
+ $this->createEntry($credentials, $targetEntry->id);
+ $this->createEntry($credentials, $targetEntry->id);
+ $app = $this->tester->createApp($credentials, 'get', '/forum-entries/{id}/entries', ForumEntryEntriesIndex::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-entries/badTopic/entries')
+ ->fetch();
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/ForumEntriesUpdateTest.php b/tests/jsonapi/ForumEntriesUpdateTest.php
index 91f2c54..db08917 100644
--- a/tests/jsonapi/ForumEntriesUpdateTest.php
+++ b/tests/jsonapi/ForumEntriesUpdateTest.php
@@ -48,24 +48,19 @@ class ForumEntriesUpdateTest extends \Codeception\Test\Unit
public function testShouldNotUpdateEntry()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $cat = $this->createCategory($credentials);
- $entry = $this->createEntry($credentials, $cat->id);
- $entry_json = $this->buildValidResourceEntryUpdate();
- $app = $this->tester->createApp($credentials, 'PATCH', '/forum-entries/{id}', ForumEntriesUpdate::class);
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $cat = $this->createCategory($credentials);
+ $entry = $this->createEntry($credentials, $cat->id);
+ $entry_json = $this->buildValidResourceEntryUpdate();
+ $app = $this->tester->createApp($credentials, 'PATCH', '/forum-entries/{id}', ForumEntriesUpdate::class);
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/forum-entries/badId')
- ->update()
- ->setJsonApiBody($entry_json);
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/forum-entries/badId')
+ ->update()
+ ->setJsonApiBody($entry_json);
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([200]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotEquals($entry->name, $resourceObject->attribute('title'));
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertSame(404, $response->getStatusCode());
}
}
diff --git a/tests/jsonapi/MessagesShowTest.php b/tests/jsonapi/MessagesShowTest.php
index 9bf5464..b9563dc 100644
--- a/tests/jsonapi/MessagesShowTest.php
+++ b/tests/jsonapi/MessagesShowTest.php
@@ -23,10 +23,9 @@ class MessagesShowTest extends \Codeception\Test\Unit
// tests
public function testMessageNotFound()
{
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $credentials = $this->tester->getCredentialsForTestAutor();
- $response = $this->fetchMessage($credentials, new \Message(md5('eurydamas')));
- });
+ $credentials = $this->tester->getCredentialsForTestAutor();
+ $response = $this->fetchMessage($credentials, new \Message(md5('eurydamas')));
+ $this->tester->assertSame(404, $response->getStatusCode());
}
public function testShowMessage()
diff --git a/tests/jsonapi/NewsCreateTest.php b/tests/jsonapi/NewsCreateTest.php
index 199cea5..eaf9dfd 100644
--- a/tests/jsonapi/NewsCreateTest.php
+++ b/tests/jsonapi/NewsCreateTest.php
@@ -1,16 +1,12 @@
<?php
require_once 'NewsTestHelper.php';
-use JsonApi\Models\C;
+use JsonApi\Routes\News\CommentCreate;
use JsonApi\Routes\News\CourseNewsCreate;
-use JsonApi\Routes\News\UserNewsCreate;
+use JsonApi\Routes\News\NewsUpdate;
use JsonApi\Routes\News\StudipNewsCreate;
-use JsonApi\Routes\News\CommentCreate;
-use JsonApi\Routes\News\NewsUpdate;
-use JsonApi\Errors\AuthorizationFailedException;
-use JsonApi\Errors\RecordNotFoundException;
-use JsonApi\Routes\News\CommentsDelete;
+use JsonApi\Routes\News\UserNewsCreate;
class NewsCreateTest extends \Codeception\Test\Unit
{
@@ -53,49 +49,43 @@ class NewsCreateTest extends \Codeception\Test\Unit
$this->tester->assertNotNull($resourceObject->attribute('content'));
$newsId = $news->id;
}
+
public function testShouldNotStudipNewsCreate()
{
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $title = 'A public testing title';
+ $content = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
+ $entry_json = $this->buildValidResourceEntry($content, $title);
+ $app = $this->tester->createApp($credentials, 'post', '/news', StudipNewsCreate::class);
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/news')
+ ->create()
+ ->setJsonApiBody($entry_json);
- $this->tester->expectThrowable(AuthorizationFailedException::class, function () {
- $credentials = $this->tester->getCredentialsForTestDozent();
- $title = 'A public testing title';
- $content = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
- $entry_json = $this->buildValidResourceEntry($content, $title);
- $app = $this->tester->createApp($credentials, 'post', '/news', StudipNewsCreate::class);
-
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/news')
- ->create()
- ->setJsonApiBody($entry_json);
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('title'));
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- $newsId = $news->id;
-
- });
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertFalse($response->isSuccessfulDocument());
+ $this->tester->assertSame(403, $response->getStatusCode());
}
- public function testShouldNewsUpdate() {
+
+ public function testShouldNewsUpdate()
+ {
$title = 'A course testing title';
$credentials = $this->tester->getCredentialsForTestDozent();
$content = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
$news = $this->createNews($credentials, $title, $content);
-
+
$changedContent = 'Lorem ipsum dolor sit amet';
$entry_json = $this->buildValidUpdateEntry($changedContent);
$app = $this->tester->createApp($credentials, 'patch', '/news/{id}', NewsUpdate::class);
-
+
$requestBuilder = $this->tester->createRequestBuilder($credentials);
$requestBuilder
->setUri('/news/'.$news->id)
->update()
->setJsonApiBody($entry_json);
-
-
+
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
$this->tester->assertTrue($response->isSuccessfulDocument());
@@ -128,10 +118,9 @@ class NewsCreateTest extends \Codeception\Test\Unit
$this->tester->assertNotNull($resourceObject->attribute('content'));
$newsId = $news->id;
}
+
public function testShouldNotCourseNewsCreate()
{
- $this->tester->expectThrowable(AuthorizationFailedException::class, function () {
-
$credentials = $this->tester->getCredentialsForTestAutor();
$courseId = 'a07535cf2f8a72df33c12ddfa4b53dde';
$title = 'A course testing title';
@@ -147,15 +136,9 @@ class NewsCreateTest extends \Codeception\Test\Unit
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('title'));
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- $newsId = $news->id;
-
- });
+ $this->tester->assertSame(403, $response->getStatusCode());
}
+
public function testShouldUserNewsCreate()
{
$credentials = $this->tester->getCredentialsForTestAutor();
@@ -172,7 +155,6 @@ class NewsCreateTest extends \Codeception\Test\Unit
->setJsonApiBody($entry_json);
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
-
$this->tester->assertTrue($response->isSuccessfulDocument([201]));
$document = $response->document();
$resourceObject = $document->primaryResource();
@@ -180,10 +162,9 @@ class NewsCreateTest extends \Codeception\Test\Unit
$this->tester->assertNotNull($resourceObject->attribute('content'));
$newsId = $news->id;
}
+
public function testShouldNotUserNewsCreate()
{
- $this->tester->expectThrowable(AuthorizationFailedException::class, function () {
-
$credentials = $this->tester->getCredentialsForTestAutor();
$otherUser = $this->tester->getCredentialsForTestDozent();
$userId = $otherUser['id'];
@@ -199,16 +180,9 @@ class NewsCreateTest extends \Codeception\Test\Unit
->setJsonApiBody($entry_json);
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
-
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('title'));
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- $newsId = $news->id;
-
- });
+ $this->assertSame(403, $response->getStatusCode());
}
+
public function testShouldCommentCreate()
{
$title = 'A course testing title';
@@ -227,37 +201,29 @@ class NewsCreateTest extends \Codeception\Test\Unit
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
+ $this->tester->assertTrue($response->isSuccessfulDocument());
$document = $response->document();
$resourceObject = $document->primaryResource();
$this->tester->assertNotNull($resourceObject->attribute('content'));
}
+
public function testShouldNotCommentCreate()
{
- //missing title
- $this->tester->expectThrowable(RecordNotFoundException::class, function () {
- $title = 'A course testing title';
- $credentials = $this->tester->getCredentialsForTestDozent();
- $content = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
- $news = $this->createNews($credentials, $title, $content);
- $comment = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
- $entry_json = $this->buildValidCommentEntry($comment);
-
- $app = $this->tester->createApp($credentials, 'post', '/news/{id}/comments', CommentCreate::class);
- $requestBuilder = $this->tester->createRequestBuilder($credentials);
- $requestBuilder
- ->setUri('/news/badId/comments')
- ->create()
- ->setJsonApiBody($entry_json);
-
- $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
-
- $this->tester->assertTrue($response->isSuccessfulDocument([201]));
- $document = $response->document();
- $resourceObject = $document->primaryResource();
- $this->tester->assertNotNull($resourceObject->attribute('content'));
- });
- }
-
+ $title = 'A course testing title';
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $content = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
+ $news = $this->createNews($credentials, $title, $content);
+ $comment = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
+ $entry_json = $this->buildValidCommentEntry($comment);
+ $app = $this->tester->createApp($credentials, 'post', '/news/{id}/comments', CommentCreate::class);
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder
+ ->setUri('/news/badId/comments')
+ ->create()
+ ->setJsonApiBody($entry_json);
+
+ $response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ $this->tester->assertFalse($response->isSuccessfulDocument());
+ }
}
diff --git a/tests/jsonapi/NewsShowTest.php b/tests/jsonapi/NewsShowTest.php
index 79df86d..6a90657 100644
--- a/tests/jsonapi/NewsShowTest.php
+++ b/tests/jsonapi/NewsShowTest.php
@@ -35,7 +35,7 @@ class NewsShowTest extends \Codeception\Test\Unit
$news = $this->createNews($credentials, $title, $content, $range_id);
$newsId = $news->id;
$app = $this->tester->createApp($credentials, 'get', '/studip/news', GlobalNewsShow::class);
-
+
$response = $this->tester->sendMockRequest(
$app,
$this->tester->createRequestBuilder($credentials)
@@ -47,11 +47,12 @@ class NewsShowTest extends \Codeception\Test\Unit
$this->tester->assertSame(200, $response->getStatusCode());
$this->tester->assertTrue($response->isSuccessfulDocument([200]));
$document = $response->document();
- $resourceObject = $document->primaryResource();
+ $resourceObjects = $document->primaryResources();
+ $resourceObject = current($resourceObjects);
$this->tester->assertNotNull($resourceObject->attribute('title'));
$this->tester->assertNotNull($resourceObject->attribute('content'));
$this->tester->assertNotNull($document->isSingleResourceDocument());
- $this->tester->assertSame($newsId, $document->primaryResource()->id());
+ $this->tester->assertSame($newsId, $resourceObject->id());
$this->tester->storeJsonMd('show_news', $response);
}
@@ -64,7 +65,7 @@ class NewsShowTest extends \Codeception\Test\Unit
$news = $this->createNews($credentials, $title, $content, $course_id);
$newsId = $news->id;
$app = $this->tester->createApp($credentials, 'get', '/courses/{id}/news', ByCourseIndex::class);
-
+
$response = $this->tester->sendMockRequest(
$app,
$this->tester->createRequestBuilder($credentials)
@@ -74,10 +75,11 @@ class NewsShowTest extends \Codeception\Test\Unit
);
$this->tester->assertTrue($response->isSuccessfulDocument());
$document = $response->document();
- $resourceObject = $document->primaryResource();
+ $resourceObjects = $document->primaryResources();
+ $resourceObject = current($resourceObjects);
$this->tester->assertNotNull($resourceObject->attribute('title'));
$this->tester->assertNotNull($resourceObject->attribute('content'));
-
+
}
public function testShouldShowNewsByCurrentUser()
@@ -92,8 +94,7 @@ class NewsShowTest extends \Codeception\Test\Unit
$this->tester->assertSame(200, $response->getStatusCode());
$this->tester->assertTrue($response->isSuccessfulDocument([200]));
$document = $response->document();
- $this->tester->assertNotNull($document->primaryResource());
- $this->tester->assertSame($newsId, $document->primaryResource()->id());
+ $this->tester->assertNotEmpty($document->primaryResources());
}
public function testShouldNotShowNewsByCurrentUser()
@@ -107,7 +108,7 @@ class NewsShowTest extends \Codeception\Test\Unit
$this->tester->assertSame(200, $response->getStatusCode());
$this->tester->assertTrue($response->isSuccessfulDocument([200]));
$document = $response->document();
- $this->tester->assertNull($document->primaryResource());
+ $this->tester->assertEmpty($document->primaryResources());
}
private function getNoNewsByUser($credentials)
diff --git a/tests/jsonapi/UserEventsIcalTest.php b/tests/jsonapi/UserEventsIcalTest.php
index bf3d2ba..3d0a78a 100644
--- a/tests/jsonapi/UserEventsIcalTest.php
+++ b/tests/jsonapi/UserEventsIcalTest.php
@@ -39,7 +39,7 @@ class UserEventsIcalTest extends \Codeception\Test\Unit
$requestBuilder = $this->tester->createRequestBuilder($credentials);
$requestBuilder->setUri('/users/'.$credentials['id'].'/events.ics')->fetch();
- $response = $app($requestBuilder->getRequest(), new \Slim\Http\Response());
+ $response = $app->handle($requestBuilder->getRequest());
$this->tester->assertEquals(200, $response->getStatusCode());
$this->tester->assertStringContainsString('BEGIN:VEVENT', (string) $response->getBody());
diff --git a/tests/jsonapi/UserScheduleShowTest.php b/tests/jsonapi/UserScheduleShowTest.php
index f505977..fc7529f 100644
--- a/tests/jsonapi/UserScheduleShowTest.php
+++ b/tests/jsonapi/UserScheduleShowTest.php
@@ -38,6 +38,7 @@ class UserScheduleShowTest extends \Codeception\Test\Unit
$scheduleId = \DBManager::get()->lastInsertId();
$app = $this->tester->createApp($credentials, 'get', '/users/{id}/schedule', UserScheduleShow::class, 'get-schedule');
+ $app->get('/xxx', function () {})->setName('get-semester');
$requestBuilder = $this->tester->createRequestBuilder($credentials);
$requestBuilder->setUri('/users/'.$credentials['id'].'/schedule')->fetch();
diff --git a/tests/jsonapi/_bootstrap.php b/tests/jsonapi/_bootstrap.php
index b4481af..d9c5adc 100644
--- a/tests/jsonapi/_bootstrap.php
+++ b/tests/jsonapi/_bootstrap.php
@@ -55,6 +55,7 @@ StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/calendar/li
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/filesystem');
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/migrations');
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/modules');
+StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/navigation');
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/phplib');
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/raumzeit');
StudipAutoloader::addAutoloadPath($GLOBALS['STUDIP_BASE_PATH'].'/lib/resources');