Completed
Push — master ( dd842b...72a857 )
by Alexander
03:27
created

ResourceFactory::resolveResourceKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 2
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Flugg\Responder\Resources;
4
5
use Flugg\Responder\Contracts\Resources\ResourceFactory as ResourceFactoryContract;
6
use Flugg\Responder\Contracts\Resources\ResourceKeyResolver as ResourceKeyResolverContract;
7
use Flugg\Responder\Contracts\Transformers\TransformerResolver;
8
use Illuminate\Support\Arr;
9
use League\Fractal\Resource\Collection as CollectionResource;
10
use League\Fractal\Resource\Item as ItemResource;
11
use League\Fractal\Resource\NullResource;
12
use League\Fractal\Resource\Primitive;
13
use League\Fractal\Resource\ResourceInterface;
14
use Traversable;
15
16
/**
17
 * This class is responsible for making Fractal resources from a variety of data types.
18
 *
19
 * @package flugger/laravel-responder
20
 * @author  Alexander Tømmerås <[email protected]>
21
 * @license The MIT License
22
 */
23
class ResourceFactory implements ResourceFactoryContract
24
{
25
    /**
26
     * A service class, used to normalize data.
27
     *
28
     * @var \Flugg\Responder\Resources\DataNormalizer
29
     */
30
    protected $normalizer;
31
32
    /**
33
     * A resolver class, used to resolve resource keys.
34
     *
35
     * @var \Flugg\Responder\Contracts\Transformers\TransformerResolver
36
     */
37
    protected $transformerResolver;
38
39
    /**
40
     * A resolver class, used to resolve resource keys.
41
     *
42
     * @var \Flugg\Responder\Contracts\Resources\ResourceKeyResolver
43
     */
44
    protected $resourceKeyResolver;
45
46
    /**
47
     * Construct the factory class.
48
     *
49
     * @param \Flugg\Responder\Resources\DataNormalizer                   $normalizer
50
     * @param \Flugg\Responder\Contracts\Transformers\TransformerResolver $transformerResolver
51
     * @param \Flugg\Responder\Contracts\Resources\ResourceKeyResolver    $resourceKeyResolver
52
     */
53 54
    public function __construct(DataNormalizer $normalizer, TransformerResolver $transformerResolver, ResourceKeyResolverContract $resourceKeyResolver)
54
    {
55 54
        $this->normalizer = $normalizer;
56 54
        $this->transformerResolver = $transformerResolver;
57 54
        $this->resourceKeyResolver = $resourceKeyResolver;
58 54
    }
59
60
    /**
61
     * Make resource from the given data.
62
     *
63
     * @param  mixed                                                          $data
64
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable|null $transformer
65
     * @param  string|null                                                    $resourceKey
66
     * @return \League\Fractal\Resource\ResourceInterface
67
     */
68 54
    public function make($data = null, $transformer = null, string $resourceKey = null): ResourceInterface
69
    {
70 54
        if ($data instanceof ResourceInterface) {
71 1
            return $this->makeFromResource($data, $transformer, $resourceKey);
72 53
        } elseif (is_null($data = $this->normalizer->normalize($data))) {
73 12
            return $this->instatiateResource($data, null, $resourceKey);
74
        }
75
76 41
        $transformer = $this->resolveTransformer($data, $transformer);
77 41
        $resourceKey = $this->resolveResourceKey($data, $resourceKey);
78
79 41
        return $this->instatiateResource($data, $transformer, $resourceKey);
80
    }
81
82
    /**
83
     * Make resource from the given resource.
84
     *
85
     * @param  \League\Fractal\Resource\ResourceInterface                     $resource
86
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable|null $transformer
87
     * @param  string|null                                                    $resourceKey
88
     * @return \League\Fractal\Resource\ResourceInterface
89
     */
90 1
    public function makeFromResource(ResourceInterface $resource, $transformer = null, string $resourceKey = null): ResourceInterface
91
    {
92 1
        $transformer = $this->resolveTransformer($resource->getData(), $transformer ?: $resource->getTransformer());
93 1
        $resourceKey = $this->resolveResourceKey($resource->getData(), $resourceKey ?: $resource->getResourceKey());
94
95 1
        return $resource->setTransformer($transformer)->setResourceKey($resourceKey);
96
    }
97
98
    /**
99
     * Instatiate a new resource instance.
100
     *
101
     * @param  mixed                                                   $data
102
     * @param  \Flugg\Responder\Transformers\Transformer|callable|null $transformer
103
     * @param  string|null                                             $resourceKey
104
     * @return \League\Fractal\Resource\ResourceInterface
105
     */
106 53
    protected function instatiateResource($data, $transformer = null, string $resourceKey = null): ResourceInterface
107
    {
108 53
        if (is_null($data)) {
109 12
            return new NullResource(null, null, $resourceKey);
110 41
        } elseif ($this->shouldCreateCollection($data)) {
111 15
            return new CollectionResource($data, $transformer, $resourceKey);
112 33
        } elseif (is_scalar($data)) {
113
            return new Primitive($data, $transformer, $resourceKey);
114
        }
115
116 33
        return new ItemResource($data, $transformer, $resourceKey);
117
    }
118
119
    /**
120
     * Indicates if the data belongs to a collection resource.
121
     *
122
     * @param  mixed $data
123
     * @return bool
124
     */
125 41
    protected function shouldCreateCollection($data): bool
126
    {
127 41
        if (is_array($data)) {
128 9
            return ! Arr::isAssoc($data) && ! is_scalar(Arr::first($data));
129
        }
130
131 32
        return $data instanceof Traversable;
132
    }
133
134
    /**
135
     * Resolve a transformer.
136
     *
137
     * @param  mixed                                                          $data
138
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable|null $transformer
139
     * @return \Flugg\Responder\Transformers\Transformer|callable
140
     */
141 42
    protected function resolveTransformer($data, $transformer)
142
    {
143 42
        if (isset($transformer)) {
144 14
            return $this->transformerResolver->resolve($transformer);
145
        }
146
147 31
        return $this->transformerResolver->resolveFromData($data);
148
    }
149
150
    /**
151
     * Resolve a resource key.
152
     *
153
     * @param  mixed       $data
154
     * @param  string|null $resourceKey
155
     * @return null|string
156
     */
157 42
    protected function resolveResourceKey($data, string $resourceKey = null)
158
    {
159 42
        return isset($resourceKey) ? $resourceKey : $this->resourceKeyResolver->resolve($data);
160
    }
161
}