aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/JsonApi/Routes/RelationshipsController.php
blob: 47b546c782b26040d03ad98edd1c8f0678d99302 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php

namespace JsonApi\Routes;

use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\UnsupportedRequestError;
use JsonApi\JsonApiController;
use Neomerx\JsonApi\Contracts\Schema\DocumentInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

abstract class RelationshipsController extends JsonApiController
{
    use ValidationTrait;

    protected $allowedPagingParameters = ['offset', 'limit'];

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function __invoke(Request $request, Response $response, $args)
    {
        if (!$this->authorize($request, $related = $this->findRelated($args))) {
            throw new AuthorizationFailedException();
        }

        $map = [
            'GET' => 'fetchRelationship',
            'PATCH' => 'replaceRelationship',
            'POST' => 'addToRelationship',
            'DELETE' => 'removeFromRelationship',
        ];

        if (!isset($map[$request->getMethod()])) {
            throw new UnsupportedRequestError();
        }

        return call_user_func([$this, $map[$request->getMethod()]], $request, $related);
    }

    abstract protected function findRelated(array $args);

    abstract protected function authorize(Request $request, $resource);

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function validateResourceDocument($json, $data)
    {
    }

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function fetchRelationship(Request $request, $related)
    {
        throw new UnsupportedRequestError();
    }

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function addToRelationship(Request $request, $related)
    {
        throw new UnsupportedRequestError();
    }

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function removeFromRelationship(Request $request, $related)
    {
        throw new UnsupportedRequestError();
    }

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function replaceRelationship(Request $request, $related)
    {
        throw new UnsupportedRequestError();
    }

    abstract protected function getRelationshipSelfLink($resource, $schema, $userData);

    abstract protected function getRelationshipRelatedLink($resource, $schema, $userData);

    protected function getRelationshipLinks($resource, $userData = null)
    {
        $schema = $this->getSchema($resource);

        return array_reduce(
            [
                [DocumentInterface::KEYWORD_SELF, 'getRelationshipSelfLink'],
                [DocumentInterface::KEYWORD_RELATED, 'getRelationshipRelatedLink'],
            ],
            function ($links, $entry) use ($resource, $schema, $userData) {
                list($keyword, $method) = $entry;
                if ($link = $this->$method($resource, $schema, $userData)) {
                    $links[$keyword] = $link;
                }

                return $links;
            },
            []
        );
    }
}