Completed
Branch master (726023)
by
unknown
02:44
created

SchemaProvider::getRelationshipSelfLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 4
crap 1
1
<?php namespace Neomerx\JsonApi\Schema;
2
3
/**
4
 * Copyright 2015 [email protected] (www.neomerx.com)
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 \InvalidArgumentException;
20
use \Neomerx\JsonApi\I18n\Translator as T;
21
use \Neomerx\JsonApi\Contracts\Schema\LinkInterface;
22
use \Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
23
use \Neomerx\JsonApi\Contracts\Document\DocumentInterface;
24
use \Neomerx\JsonApi\Contracts\Schema\SchemaFactoryInterface;
25
use \Neomerx\JsonApi\Contracts\Schema\SchemaProviderInterface;
26
use \Neomerx\JsonApi\Contracts\Schema\RelationshipObjectInterface;
27
28
/**
29
 * @package Neomerx\JsonApi
30
 */
31
abstract class SchemaProvider implements SchemaProviderInterface
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 end with '/'
58
     */
59
    protected $selfSubUrl;
60
61
    /**
62
     * @var bool
63
     */
64
    protected $isShowAttributesInIncluded = true;
1 ignored issue
show
Comprehensibility Naming introduced by
The variable name $isShowAttributesInIncluded exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
65
66
    /**
67
     * @var SchemaFactoryInterface
68
     */
69
    private $factory;
70
71
    /**
72
     * @var ContainerInterface
73
     */
74
    private $container;
75
76
    /**
77
     * @param SchemaFactoryInterface $factory
78
     * @param ContainerInterface     $container
79
     */
80 62
    public function __construct(SchemaFactoryInterface $factory, ContainerInterface $container)
81
    {
82 62
        $isOk = (is_string($this->resourceType) === true && empty($this->resourceType) === false);
83 62
        if ($isOk === false) {
84 1
            throw new InvalidArgumentException(T::t('Resource type is not set for Schema \'%s\'.', [static::class]));
85
        }
86
87 61
        if ($this->selfSubUrl === null) {
88 57
            $this->selfSubUrl = '/' . $this->resourceType . '/';
89 57
        } else {
90
            $isOk =
91 5
                is_string($this->selfSubUrl) === true &&
92 5
                empty($this->selfSubUrl) === false &&
93 5
                $this->selfSubUrl[0] === '/' &&
94 5
                $this->selfSubUrl[strlen($this->selfSubUrl) - 1] == '/';
95
96 5
            if ($isOk === false) {
97 1
                $message = T::t('\'Self\' sub-url set incorrectly for Schema \'%s\'.', [static::class]);
98 1
                throw new InvalidArgumentException($message);
99
            }
100
        }
101
102 60
        $this->factory   = $factory;
103 60
        $this->container = $container;
104 60
    }
105
106
    /**
107
     * @inheritdoc
108
     */
109 57
    public function getResourceType()
110
    {
111 57
        return $this->resourceType;
112
    }
113
114
    /**
115
     * @inheritdoc
116
     */
117 49
    public function getSelfSubUrl($resource = null)
118
    {
119 49
        return $resource === null ? $this->selfSubUrl : $this->selfSubUrl . $this->getId($resource);
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125 47
    public function getSelfSubLink($resource)
126
    {
127 47
        return $this->createLink($this->getSelfSubUrl($resource));
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133 4
    public function getRelationshipSelfLink($resource, $name, $meta = null, $treatAsHref = false)
134
    {
135 4
        $link = $this->createLink($this->getRelationshipSelfUrl($resource, $name), $meta, $treatAsHref);
136
137 4
        return $link;
138
    }
139
140
    /**
141
     * @inheritdoc
142
     */
143 4
    public function getRelationshipRelatedLink($resource, $name, $meta = null, $treatAsHref = false)
144
    {
145 4
        $link = $this->createLink($this->getRelationshipRelatedUrl($resource, $name), $meta, $treatAsHref);
146
147 4
        return $link;
148
    }
149
150
    /**
151
     * @inheritdoc
152
     */
153 53
    public function getPrimaryMeta($resource)
154
    {
155 53
        return null;
156
    }
157
158
    /**
159
     * @inheritdoc
160
     */
161 29
    public function getLinkageMeta($resource)
162
    {
163 29
        return null;
164
    }
165
166
    /**
167
     * @inheritdoc
168
     */
169 19
    public function getInclusionMeta($resource)
170
    {
171 19
        return null;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177 30
    public function getRelationshipsPrimaryMeta($resource)
178
    {
179 30
        return null;
180
    }
181
182
    /**
183
     * @inheritdoc
184
     */
185 16
    public function getRelationshipsInclusionMeta($resource)
186
    {
187 16
        return null;
188
    }
189
190
    /**
191
     * @inheritdoc
192
     */
193 19
    public function isShowAttributesInIncluded()
194
    {
195 19
        return $this->isShowAttributesInIncluded;
196
    }
197
198
    /**
199
     * Get resource links.
200
     *
201
     * @param object $resource
202
     * @param bool   $isPrimary
203
     * @param array  $includeRelationships A list of relationships that will be included as full resources.
204
     *
205
     * @return array
206
     */
207 8
    public function getRelationships($resource, $isPrimary, array $includeRelationships)
208
    {
209 8
        $resource && $isPrimary && $includeRelationships ?: null;
1 ignored issue
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...
210
211 8
        return [];
212
    }
213
214
    /**
215
     * @inheritdoc
216
     */
217 51
    public function createResourceObject($resource, $isOriginallyArrayed, $attributeKeysFilter = null)
218
    {
219 51
        return $this->factory->createResourceObject($this, $resource, $isOriginallyArrayed, $attributeKeysFilter);
220
    }
221
222
    /**
223
     * @inheritdoc
224
     */
225 51
    public function getRelationshipObjectIterator($resource, $isPrimary, array $includeRelationships)
226
    {
227 51
        foreach ($this->getRelationships($resource, $isPrimary, $includeRelationships) as $name => $desc) {
228 40
            yield $this->createRelationshipObject($resource, $name, $desc);
229 51
        }
230 50
    }
231
232
    /**
233
     * @inheritdoc
234
     */
235 26
    public function getIncludePaths()
236
    {
237 26
        return [];
238
    }
239
240
    /**
241
     * @inheritdoc
242
     */
243 47
    public function getResourceLinks($resource)
244
    {
245
        $links = [
246 47
            LinkInterface::SELF => $this->getSelfSubLink($resource),
247 47
        ];
248
249 47
        return $links;
250
    }
251
252
    /**
253
     * @inheritdoc
254
     */
255 16
    public function getIncludedResourceLinks($resource)
256
    {
257 16
        return [];
258
    }
259
260
    /**
261
     * @param object $resource
262
     * @param string $name
263
     *
264
     * @return string
265
     */
266 4
    protected function getRelationshipSelfUrl($resource, $name)
267
    {
268 4
        $url = $this->getSelfSubUrl($resource) . '/' . DocumentInterface::KEYWORD_RELATIONSHIPS . '/' . $name;
269
270 4
        return $url;
271
    }
272
273
    /**
274
     * @param object $resource
275
     * @param string $name
276
     *
277
     * @return string
278
     */
279 4
    protected function getRelationshipRelatedUrl($resource, $name)
280
    {
281 4
        $url = $this->getSelfSubUrl($resource) . '/' . $name;
282
283 4
        return $url;
284
    }
285
286
    /**
287
     * @param string     $subHref
288
     * @param null|mixed $meta
289
     * @param bool       $treatAsHref
290
     *
291
     * @return LinkInterface
292
     */
293 49
    protected function createLink($subHref, $meta = null, $treatAsHref = false)
294
    {
295 49
        return $this->factory->createLink($subHref, $meta, $treatAsHref);
296
    }
297
298
    /**
299
     * @param object $resource
300
     * @param string $relationshipName
301
     * @param array  $description
302
     * @param bool   $isShowSelf
303
     * @param bool   $isShowRelated
304
     *
305
     * @return array <string,LinkInterface>
306
     */
307 40
    protected function readLinks($resource, $relationshipName, array $description, $isShowSelf, $isShowRelated)
308
    {
309 40
        $links = $this->getValue($description, self::LINKS, []);
310 40 View Code Duplication
        if ($isShowSelf === true && isset($links[LinkInterface::SELF]) === false) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
311 1
            $links[LinkInterface::SELF] = $this->getRelationshipSelfLink($resource, $relationshipName);
312 1
        }
313 40 View Code Duplication
        if ($isShowRelated === true && isset($links[LinkInterface::RELATED]) === false) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
314 3
            $links[LinkInterface::RELATED] = $this->getRelationshipRelatedLink($resource, $relationshipName);
315 3
        }
316
317 40
        return $links;
318
    }
319
320
    /**
321
     * @param object $resource
322
     * @param string $name
323
     * @param array  $desc
324
     *
325
     * @return RelationshipObjectInterface
326
     */
327 40
    protected function createRelationshipObject($resource, $name, array $desc)
328
    {
329 40
        $data          = $this->getValue($desc, self::DATA);
330 40
        $meta          = $this->getValue($desc, self::META, null);
331 40
        $isShowSelf    = ($this->getValue($desc, self::SHOW_SELF, false) === true);
332 40
        $isShowRelated = ($this->getValue($desc, self::SHOW_RELATED, false) === true);
333 40
        $isShowData    = ($this->getValue($desc, self::SHOW_DATA, true) === true);
334 40
        $links         = $this->readLinks($resource, $name, $desc, $isShowSelf, $isShowRelated);
335
336 40
        return $this->factory->createRelationshipObject($name, $data, $links, $meta, $isShowData, false);
337
    }
338
339
    /**
340
     * @param array  $array
341
     * @param string $key
342
     * @param mixed  $default
343
     *
344
     * @return mixed
345
     */
346 40
    private function getValue(array $array, $key, $default = null)
347
    {
348 40
        return (isset($array[$key]) === true ? $array[$key] : $default);
349
    }
350
}
351