Passed
Pull Request — 2.4 (#2495)
by Antoine
03:22
created

ResourceMetadata::withAttributes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Metadata\Resource;
15
16
use ApiPlatform\Core\Api\OperationType;
17
18
/**
19
 * Resource metadata.
20
 *
21
 * @author Kévin Dunglas <[email protected]>
22
 */
23
final class ResourceMetadata
24
{
25
    private $shortName;
26
    private $description;
27
    private $iri;
28
    private $itemOperations;
29
    private $collectionOperations;
30
    private $subresourceOperations;
31
    private $graphql;
32
    private $attributes;
33
34
    public function __construct(string $shortName = null, string $description = null, string $iri = null, array $itemOperations = null, array $collectionOperations = null, array $attributes = null, array $subresourceOperations = null, array $graphql = null)
35
    {
36
        $this->shortName = $shortName;
37
        $this->description = $description;
38
        $this->iri = $iri;
39
        $this->itemOperations = $itemOperations;
40
        $this->collectionOperations = $collectionOperations;
41
        $this->subresourceOperations = $subresourceOperations;
42
        $this->graphql = $graphql;
43
        $this->attributes = $attributes;
44
    }
45
46
    /**
47
     * Gets the short name.
48
     *
49
     * @return string|null
50
     */
51
    public function getShortName()
52
    {
53
        return $this->shortName;
54
    }
55
56
    /**
57
     * Returns a new instance with the given short name.
58
     */
59
    public function withShortName(string $shortName): self
60
    {
61
        $metadata = clone $this;
62
        $metadata->shortName = $shortName;
63
64
        return $metadata;
65
    }
66
67
    /**
68
     * Gets the description.
69
     *
70
     * @return string|null
71
     */
72
    public function getDescription()
73
    {
74
        return $this->description;
75
    }
76
77
    /**
78
     * Returns a new instance with the given description.
79
     */
80
    public function withDescription(string $description): self
81
    {
82
        $metadata = clone $this;
83
        $metadata->description = $description;
84
85
        return $metadata;
86
    }
87
88
    /**
89
     * Gets the associated IRI.
90
     *
91
     * @return string|null
92
     */
93
    public function getIri()
94
    {
95
        return $this->iri;
96
    }
97
98
    /**
99
     * Returns a new instance with the given IRI.
100
     */
101
    public function withIri(string $iri): self
102
    {
103
        $metadata = clone $this;
104
        $metadata->iri = $iri;
105
106
        return $metadata;
107
    }
108
109
    /**
110
     * Gets item operations.
111
     *
112
     * @return array|null
113
     */
114
    public function getItemOperations()
115
    {
116
        return $this->itemOperations;
117
    }
118
119
    /**
120
     * Returns a new instance with the given item operations.
121
     */
122
    public function withItemOperations(array $itemOperations): self
123
    {
124
        $metadata = clone $this;
125
        $metadata->itemOperations = $itemOperations;
126
127
        return $metadata;
128
    }
129
130
    /**
131
     * Gets collection operations.
132
     *
133
     * @return array|null
134
     */
135
    public function getCollectionOperations()
136
    {
137
        return $this->collectionOperations;
138
    }
139
140
    /**
141
     * Returns a new instance with the given collection operations.
142
     */
143
    public function withCollectionOperations(array $collectionOperations): self
144
    {
145
        $metadata = clone $this;
146
        $metadata->collectionOperations = $collectionOperations;
147
148
        return $metadata;
149
    }
150
151
    /**
152
     * Gets subresource operations.
153
     *
154
     * @return array|null
155
     */
156
    public function getSubresourceOperations()
157
    {
158
        return $this->subresourceOperations;
159
    }
160
161
    /**
162
     * Returns a new instance with the given subresource operations.
163
     */
164
    public function withSubresourceOperations(array $subresourceOperations): self
165
    {
166
        $metadata = clone $this;
167
        $metadata->subresourceOperations = $subresourceOperations;
168
169
        return $metadata;
170
    }
171
172
    /**
173
     * Gets a collection operation attribute, optionally fallback to a resource attribute.
174
     */
175
    public function getCollectionOperationAttribute(string $operationName = null, string $key, $defaultValue = null, bool $resourceFallback = false)
176
    {
177
        return $this->findOperationAttribute($this->collectionOperations, $operationName, $key, $defaultValue, $resourceFallback);
178
    }
179
180
    /**
181
     * Gets an item operation attribute, optionally fallback to a resource attribute.
182
     */
183
    public function getItemOperationAttribute(string $operationName = null, string $key, $defaultValue = null, bool $resourceFallback = false)
184
    {
185
        return $this->findOperationAttribute($this->itemOperations, $operationName, $key, $defaultValue, $resourceFallback);
186
    }
187
188
    /**
189
     * Gets a subresource operation attribute, optionally fallback to a resource attribute.
190
     */
191
    public function getSubresourceOperationAttribute(string $operationName = null, string $key, $defaultValue = null, bool $resourceFallback = false)
192
    {
193
        return $this->findOperationAttribute($this->subresourceOperations, $operationName, $key, $defaultValue, $resourceFallback);
194
    }
195
196
    /**
197
     * Gets an operation attribute, optionally fallback to a resource attribute.
198
     */
199
    private function findOperationAttribute(array $operations = null, string $operationName = null, string $key, $defaultValue = null, bool $resourceFallback = false)
200
    {
201
        if (null !== $operationName && isset($operations[$operationName][$key])) {
202
            return $operations[$operationName][$key];
203
        }
204
205
        if ($resourceFallback && isset($this->attributes[$key])) {
206
            return $this->attributes[$key];
207
        }
208
209
        return $defaultValue;
210
    }
211
212
    public function getGraphqlAttribute(string $operationName, string $key, $defaultValue = null, bool $resourceFallback = false)
213
    {
214
        if (isset($this->graphql[$operationName][$key])) {
215
            return $this->graphql[$operationName][$key];
216
        }
217
218
        if ($resourceFallback && isset($this->attributes[$key])) {
219
            return $this->attributes[$key];
220
        }
221
222
        return $defaultValue;
223
    }
224
225
    /**
226
     * Gets the first available operation attribute according to the following order: collection, item, subresource, optionally fallback to a default value.
227
     */
228
    public function getOperationAttribute(array $attributes, string $key, $defaultValue = null, bool $resourceFallback = false)
229
    {
230
        if (isset($attributes['collection_operation_name'])) {
231
            return $this->getCollectionOperationAttribute($attributes['collection_operation_name'], $key, $defaultValue, $resourceFallback);
232
        }
233
234
        if (isset($attributes['item_operation_name'])) {
235
            return $this->getItemOperationAttribute($attributes['item_operation_name'], $key, $defaultValue, $resourceFallback);
236
        }
237
238
        if (isset($attributes['subresource_operation_name'])) {
239
            return $this->getSubresourceOperationAttribute($attributes['subresource_operation_name'], $key, $defaultValue, $resourceFallback);
240
        }
241
242
        if ($resourceFallback && isset($this->attributes[$key])) {
243
            return $this->attributes[$key];
244
        }
245
246
        return $defaultValue;
247
    }
248
249
    /**
250
     * Gets an attribute for a given operation type and operation name.
251
     */
252
    public function getTypedOperationAttribute(string $operationType, string $operationName, string $key, $defaultValue = null, bool $resourceFallback = false)
253
    {
254
        switch ($operationType) {
255
            case OperationType::COLLECTION:
256
                return $this->getCollectionOperationAttribute($operationName, $key, $defaultValue, $resourceFallback);
257
            case OperationType::ITEM:
258
                return $this->getItemOperationAttribute($operationName, $key, $defaultValue, $resourceFallback);
259
            default:
260
                return $this->getSubresourceOperationAttribute($operationName, $key, $defaultValue, $resourceFallback);
261
        }
262
    }
263
264
    /**
265
     * Gets the normalized I/O attributes.
266
     */
267
    public function getTypedOperationIOMetadata(string $operationType, string $operationName, string $ioType): ?array
268
    {
269
        $ioAttribute = $this->getTypedOperationAttribute($operationType, $operationName, $ioType, null, true);
270
271
        if (false === $ioAttribute) {
272
            return ['class' => null];
273
        }
274
275
        if (null === $ioAttribute) {
276
            return null;
277
        }
278
279
        if (\is_string($ioAttribute)) {
280
            $ioAttribute = ['class' => $ioAttribute];
281
        }
282
283
        if (!isset($ioAttribute['name'])) {
284
            if (false === $pos = strrpos($ioAttribute['class'], '\\')) {
285
                return $ioAttribute;
286
            }
287
288
            $ioAttribute['name'] = substr($ioAttribute['class'], $pos + 1);
289
        }
290
291
        return $ioAttribute;
292
    }
293
294
    /**
295
     * Get the operation I/O class if any.
296
     */
297
    public function getTypedOperationIOClass(string $operationType, string $operationName, string $ioType, $fallback = null)
298
    {
299
        $ioMetadata = $this->getTypedOperationIOMetadata($operationType, $operationName, $ioType);
300
301
        return null === $ioMetadata ? $fallback : $ioMetadata['class'];
302
    }
303
304
    /**
305
     * Get the resource I/O class if any.
306
     */
307
    public function getTypedResourceIOClass(string $ioType, $fallback = null)
308
    {
309
        $ioMetadata = $this->getAttribute($ioType);
310
311
        if (\is_string($ioMetadata)) {
312
            return $ioMetadata;
313
        }
314
315
        if (\is_array($ioMetadata)) {
316
            return $ioMetadata['class'];
317
        }
318
319
        if (false === $ioMetadata) {
320
            return false;
321
        }
322
323
        return $fallback;
324
    }
325
326
    /**
327
     * Gets attributes.
328
     *
329
     * @return array|null
330
     */
331
    public function getAttributes()
332
    {
333
        return $this->attributes;
334
    }
335
336
    /**
337
     * Gets an attribute.
338
     */
339
    public function getAttribute(string $key, $defaultValue = null)
340
    {
341
        if (isset($this->attributes[$key])) {
342
            return $this->attributes[$key];
343
        }
344
345
        return $defaultValue;
346
    }
347
348
    /**
349
     * Returns a new instance with the given attribute.
350
     */
351
    public function withAttributes(array $attributes): self
352
    {
353
        $metadata = clone $this;
354
        $metadata->attributes = $attributes;
355
356
        return $metadata;
357
    }
358
359
    /**
360
     * Gets options of for the GraphQL query.
361
     *
362
     * @return array|null
363
     */
364
    public function getGraphql()
365
    {
366
        return $this->graphql;
367
    }
368
369
    /**
370
     * Returns a new instance with the given GraphQL options.
371
     */
372
    public function withGraphql(array $graphql): self
373
    {
374
        $metadata = clone $this;
375
        $metadata->graphql = $graphql;
376
377
        return $metadata;
378
    }
379
}
380