Completed
Branch master (3cbe70)
by
unknown
03:13
created

SchemaProvider::getRelationships()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4286
cc 3
eloc 4
nc 4
nop 2
crap 3
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;
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 58
    public function __construct(SchemaFactoryInterface $factory, ContainerInterface $container)
81
    {
82 58
        $isOk = (is_string($this->resourceType) === true && empty($this->resourceType) === false);
83 58
        if ($isOk === false) {
84 1
            throw new InvalidArgumentException(T::t('Resource type is not set for Schema \'%s\'.', [static::class]));
85
        }
86
87 57
        if ($this->selfSubUrl === null) {
88 18
            $this->selfSubUrl = '/' . $this->resourceType . '/';
89 18
        } else {
90
            $isOk =
91 57
                is_string($this->selfSubUrl) === true &&
92 57
                empty($this->selfSubUrl) === false &&
93 57
                $this->selfSubUrl[0] === '/' &&
94 57
                $this->selfSubUrl[strlen($this->selfSubUrl) - 1] == '/';
95
96 57
            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 56
        $this->factory   = $factory;
103 56
        $this->container = $container;
104 56
    }
105
106
    /**
107
     * @inheritdoc
108
     */
109 53
    public function getResourceType()
110
    {
111 53
        return $this->resourceType;
112
    }
113
114
    /**
115
     * @inheritdoc
116
     */
117 1
    public function getSelfSubUrl()
118
    {
119 1
        return $this->selfSubUrl;
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125 45
    public function getSelfSubLink($resource)
126
    {
127 45
        return new Link($this->selfSubUrl . $this->getId($resource));
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133 49
    public function getPrimaryMeta($resource)
134
    {
135 49
        return null;
136
    }
137
138
    /**
139
     * @inheritdoc
140
     */
141 24
    public function getLinkageMeta($resource)
142
    {
143 24
        return null;
144
    }
145
146
    /**
147
     * @inheritdoc
148
     */
149 14
    public function getInclusionMeta($resource)
150
    {
151 14
        return null;
152
    }
153
154
    /**
155
     * @inheritdoc
156
     */
157 28
    public function getRelationshipsPrimaryMeta($resource)
158
    {
159 28
        return null;
160
    }
161
162
    /**
163
     * @inheritdoc
164
     */
165 12
    public function getRelationshipsInclusionMeta($resource)
166
    {
167 12
        return null;
168
    }
169
170
    /**
171
     * @inheritdoc
172
     */
173 14
    public function isShowAttributesInIncluded()
174
    {
175 14
        return $this->isShowAttributesInIncluded;
176
    }
177
178
    /**
179
     * Get resource links.
180
     *
181
     * @param object $resource
182
     * @param array  $includeRelationships A list of relationships that will be included as full resources.
183
     *
184
     * @return array
185
     */
186 6
    public function getRelationships($resource, array $includeRelationships = [])
187
    {
188 6
        $resource ?: null;
189 6
        $includeRelationships ?: null;
190
191 6
        return [];
192
    }
193
194
    /**
195
     * @inheritdoc
196
     */
197 47
    public function createResourceObject($resource, $isOriginallyArrayed, $attributeKeysFilter = null)
198
    {
199 47
        return $this->factory->createResourceObject($this, $resource, $isOriginallyArrayed, $attributeKeysFilter);
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205 47
    public function getRelationshipObjectIterator($resource, array $includeRelationships)
206
    {
207 47
        foreach ($this->getRelationships($resource, $includeRelationships) as $name => $desc) {
208 36
            yield $this->createRelationshipObject($name, $desc);
209 47
        }
210 47
    }
211
212
    /**
213
     * @inheritdoc
214
     */
215 26
    public function getIncludePaths()
216
    {
217 26
        return [];
218
    }
219
220
    /**
221
     * @inheritdoc
222
     */
223 43
    public function getResourceLinks($resource)
224
    {
225
        $links = [
226 43
            LinkInterface::SELF => $this->getSelfSubLink($resource),
227 43
        ];
228
229 43
        return $links;
230
    }
231
232
    /**
233
     * @inheritdoc
234
     */
235 12
    public function getIncludedResourceLinks($resource)
236
    {
237 12
        return [];
238
    }
239
240
    /**
241
     * @param string $relationshipName
242
     * @param array  $description
243
     * @param bool   $isShowSelf
244
     * @param bool   $isShowRelated
245
     *
246
     * @return array <string,LinkInterface>
247
     */
248 36
    protected function readLinks($relationshipName, array $description, $isShowSelf, $isShowRelated)
249
    {
250 36
        $links = $this->getValue($description, self::LINKS, []);
251 36 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...
252 1
            $links[LinkInterface::SELF] = $this->factory->createLink(
253 1
                DocumentInterface::KEYWORD_RELATIONSHIPS. '/'.$relationshipName
254 1
            );
255 1
        }
256 36 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...
257 3
            $links[LinkInterface::RELATED] = $this->factory->createLink($relationshipName);
258 3
        }
259
260 36
        return $links;
261
    }
262
263
    /**
264
     * @param string $name
265
     * @param array  $desc
266
     *
267
     * @return RelationshipObjectInterface
268
     */
269 36
    protected function createRelationshipObject($name, array $desc)
270
    {
271 36
        $data          = $this->getValue($desc, self::DATA);
272 36
        $meta          = $this->getValue($desc, self::META, null);
273 36
        $isShowSelf    = ($this->getValue($desc, self::SHOW_SELF, false) === true);
274 36
        $isShowRelated = ($this->getValue($desc, self::SHOW_RELATED, false) === true);
275 36
        $isShowData    = ($this->getValue($desc, self::SHOW_DATA, true) === true);
276 36
        $links         = $this->readLinks($name, $desc, $isShowSelf, $isShowRelated);
277
278 36
        return $this->factory->createRelationshipObject($name, $data, $links, $meta, $isShowData, false);
279
    }
280
281
    /**
282
     * @param array  $array
283
     * @param string $key
284
     * @param mixed  $default
285
     *
286
     * @return mixed
287
     */
288 36
    private function getValue(array $array, $key, $default = null)
289
    {
290 36
        return (isset($array[$key]) === true ? $array[$key] : $default);
291
    }
292
}
293