Completed
Branch master (ffe81d)
by Neomerx
04:33
created

BaseSchema::getRelationshipSelfLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 4
dl 0
loc 10
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php namespace Neomerx\JsonApi\Schema;
2
3
/**
4
 * Copyright 2015-2018 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Neomerx\JsonApi\Contracts\Document\DocumentInterface;
20
use Neomerx\JsonApi\Contracts\Document\LinkInterface;
21
use Neomerx\JsonApi\Contracts\Schema\RelationshipObjectInterface;
22
use Neomerx\JsonApi\Contracts\Schema\ResourceObjectInterface;
23
use Neomerx\JsonApi\Contracts\Schema\SchemaFactoryInterface;
24
use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
25
26
/**
27
 * @package Neomerx\JsonApi
28
 *
29
 * @SuppressWarnings(PHPMD.LongVariable)
30
 */
31
abstract class BaseSchema implements SchemaInterface
32
{
33
    /** Links information */
34
    const LINKS = DocumentInterface::KEYWORD_LINKS;
35
36
    /** Linked data key. */
37
    const DATA = DocumentInterface::KEYWORD_DATA;
38
39
    /** Relationship meta */
40
    const META = DocumentInterface::KEYWORD_META;
41
42
    /** If 'self' URL should be shown. */
43
    const SHOW_SELF = 'showSelf';
44
45
    /** If 'related' URL should be shown. */
46
    const SHOW_RELATED = 'related';
47
48
    /** If data should be shown in relationships. */
49
    const SHOW_DATA = 'showData';
50
51
    /**
52
     * @var string
53
     */
54
    protected $resourceType;
55
56
    /**
57
     * @var string Must start with '/' e.g. '/sub-url'
58
     */
59
    protected $selfSubUrl;
60
61
    /**
62
     * @var bool
63
     */
64
    protected $isShowAttributesInIncluded = true;
65
66
    /**
67
     * @var SchemaFactoryInterface
68
     */
69
    private $factory;
70
71
    /**
72
     * @param SchemaFactoryInterface $factory
73
     *
74
     * @SuppressWarnings(PHPMD.StaticAccess)
75
     * @SuppressWarnings(PHPMD.ElseExpression)
76
     */
77 72
    public function __construct(SchemaFactoryInterface $factory)
78
    {
79 72
        assert(
80 72
            is_string($this->getResourceType()) === true && empty($this->getResourceType()) === false,
81 72
            'Resource type is not set for Schema \'' . static::class . '\'.'
82
        );
83
84 72
        if ($this->selfSubUrl === null) {
85 69
            $this->selfSubUrl = '/' . $this->getResourceType();
86
        } else {
87 4
            assert(
88 4
                is_string($this->selfSubUrl) === true && empty($this->selfSubUrl) === false &&
89 4
                $this->selfSubUrl[0] === '/' && $this->selfSubUrl[strlen($this->selfSubUrl) - 1] != '/',
90 4
                '\'Self\' sub-url set incorrectly for Schema \'' . static::class . '\'.'
91
            );
92
        }
93
94 72
        $this->factory = $factory;
95 72
    }
96
97
    /**
98
     * @inheritdoc
99
     */
100 72
    public function getResourceType(): string
101
    {
102 72
        return $this->resourceType;
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108 57
    public function getSelfSubUrl($resource = null): string
109
    {
110 57
        return $resource === null ? $this->selfSubUrl : $this->selfSubUrl . '/' . $this->getId($resource);
111
    }
112
113
    /**
114
     * @inheritdoc
115
     */
116 54
    public function getSelfSubLink($resource): LinkInterface
117
    {
118 54
        return $this->createLink($this->getSelfSubUrl($resource));
119
    }
120
121
    /**
122
     * @inheritdoc
123
     *
124
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
125
     */
126 4
    public function getRelationshipSelfLink(
127
        $resource,
128
        string $name,
129
        $meta = null,
130
        bool $treatAsHref = false
131
    ): LinkInterface {
132 4
        $link = $this->createLink($this->getRelationshipSelfUrl($resource, $name), $meta, $treatAsHref);
133
134 4
        return $link;
135
    }
136
137
    /**
138
     * @inheritdoc
139
     *
140
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
141
     */
142 5
    public function getRelationshipRelatedLink(
143
        $resource,
144
        string $name,
145
        $meta = null,
146
        bool $treatAsHref = false
147
    ): LinkInterface {
148 5
        $link = $this->createLink($this->getRelationshipRelatedUrl($resource, $name), $meta, $treatAsHref);
149
150 5
        return $link;
151
    }
152
153
    /**
154
     * @inheritdoc
155
     */
156 62
    public function getPrimaryMeta($resource)
157
    {
158 62
        return null;
159
    }
160
161
    /**
162
     * @inheritdoc
163
     */
164 29
    public function getLinkageMeta($resource)
165
    {
166 29
        return null;
167
    }
168
169
    /**
170
     * @inheritdoc
171
     */
172 19
    public function getInclusionMeta($resource)
173
    {
174 19
        return null;
175
    }
176
177
    /**
178
     * @inheritdoc
179
     */
180 33
    public function getRelationshipsPrimaryMeta($resource)
181
    {
182 33
        return null;
183
    }
184
185
    /**
186
     * @inheritdoc
187
     */
188 16
    public function getRelationshipsInclusionMeta($resource)
189
    {
190 16
        return null;
191
    }
192
193
    /**
194
     * @inheritdoc
195
     */
196 19
    public function isShowAttributesInIncluded(): bool
197
    {
198 19
        return $this->isShowAttributesInIncluded;
199
    }
200
201
    /**
202
     * Get resource links.
203
     *
204
     * @param object     $resource
205
     * @param bool       $isPrimary
206
     * @param array      $includeRelationships A list of relationships that will be included as full resources.
207
     *
208
     * @return array
209
     */
210 8
    public function getRelationships($resource, bool $isPrimary, array $includeRelationships): ?array
211
    {
212 8
        assert($resource || $isPrimary || $includeRelationships || true);
0 ignored issues
show
Bug Best Practice introduced by
The expression $includeRelationships of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
213
214 8
        return [];
215
    }
216
217
    /**
218
     * @inheritdoc
219
     */
220 59
    public function createResourceObject(
221
        $resource,
222
        bool $isOriginallyArrayed,
223
        array $fieldKeysFilter = null
224
    ): ResourceObjectInterface {
225 59
        return $this->factory->createResourceObject($this, $resource, $isOriginallyArrayed, $fieldKeysFilter);
226
    }
227
228
    /**
229
     * @inheritdoc
230
     */
231 59
    public function getRelationshipObjectIterator($resource, bool $isPrimary, array $includeRelationships): iterable
232
    {
233 59
        $relationships = $this->getRelationships($resource, $isPrimary, $includeRelationships);
234 59
        foreach ($relationships as $name => $desc) {
235 44
            yield $this->createRelationshipObject($resource, $name, $desc);
236
        }
237 58
    }
238
239
    /**
240
     * @inheritdoc
241
     */
242 34
    public function getIncludePaths(): array
243
    {
244 34
        return [];
245
    }
246
247
    /**
248
     * @inheritdoc
249
     */
250 54
    public function getResourceLinks($resource): array
251
    {
252
        $links = [
253 54
            LinkInterface::SELF => $this->getSelfSubLink($resource),
254
        ];
255
256 54
        return $links;
257
    }
258
259
    /**
260
     * @inheritdoc
261
     */
262 16
    public function getIncludedResourceLinks($resource): array
263
    {
264 16
        return [];
265
    }
266
267
    /**
268
     * @param object $resource
269
     * @param string $name
270
     *
271
     * @return string
272
     */
273 4
    protected function getRelationshipSelfUrl($resource, $name)
274
    {
275 4
        $url = $this->getSelfSubUrl($resource) . '/' . DocumentInterface::KEYWORD_RELATIONSHIPS . '/' . $name;
276
277 4
        return $url;
278
    }
279
280
    /**
281
     * @param object $resource
282
     * @param string $name
283
     *
284
     * @return string
285
     */
286 5
    protected function getRelationshipRelatedUrl($resource, $name)
287
    {
288 5
        $url = $this->getSelfSubUrl($resource) . '/' . $name;
289
290 5
        return $url;
291
    }
292
293
    /**
294
     * @param string     $subHref
295
     * @param null|mixed $meta
296
     * @param bool       $treatAsHref
297
     *
298
     * @return LinkInterface
299
     *
300
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
301
     */
302 56
    protected function createLink($subHref, $meta = null, $treatAsHref = false)
303
    {
304 56
        return $this->factory->createLink($subHref, $meta, $treatAsHref);
305
    }
306
307
    /**
308
     * @param object $resource
309
     * @param string $relationshipName
310
     * @param array  $description
311
     * @param bool   $isShowSelf
312
     * @param bool   $isShowRelated
313
     *
314
     * @return array <string,LinkInterface>
315
     */
316 44
    protected function readLinks($resource, $relationshipName, array $description, $isShowSelf, $isShowRelated)
317
    {
318 44
        $links = $description[self::LINKS] ?? [];
319 44
        if ($isShowSelf === true && isset($links[LinkInterface::SELF]) === false) {
320 1
            $links[LinkInterface::SELF] = $this->getRelationshipSelfLink($resource, $relationshipName);
321
        }
322 44
        if ($isShowRelated === true && isset($links[LinkInterface::RELATED]) === false) {
323 4
            $links[LinkInterface::RELATED] = $this->getRelationshipRelatedLink($resource, $relationshipName);
324
        }
325
326 44
        return $links;
327
    }
328
329
    /**
330
     * @param object $resource
331
     * @param string $name
332
     * @param array  $desc
333
     *
334
     * @return RelationshipObjectInterface
335
     */
336 44
    protected function createRelationshipObject($resource, $name, array $desc)
337
    {
338 44
        $data          = $desc[self::DATA] ?? null;
339 44
        $meta          = $desc[self::META] ?? null;
340 44
        $isShowSelf    = (($desc[self::SHOW_SELF] ?? false) === true);
341 44
        $isShowRelated = (($desc[self::SHOW_RELATED] ?? false) === true);
342 44
        $isShowData    = (($desc[self::SHOW_DATA] ?? array_key_exists(self::DATA, $desc)) === true);
343 44
        $links         = $this->readLinks($resource, $name, $desc, $isShowSelf, $isShowRelated);
344
345 44
        return $this->factory->createRelationshipObject($name, $data, $links, $meta, $isShowData, false);
346
    }
347
}
348