MakesResources::resource()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 2
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace Flugg\Responder\Transformers\Concerns;
4
5
use Countable;
6
use Flugg\Responder\Contracts\Resources\ResourceFactory;
7
use Illuminate\Contracts\Container\Container;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Support\Str;
10
use League\Fractal\Resource\ResourceInterface;
11
use LogicException;
12
13
/**
14
 * A trait to be used by a transformer to make related resources.
15
 *
16
 * @package flugger/laravel-responder
17
 * @author  Alexander Tømmerås <[email protected]>
18
 * @license The MIT License
19
 */
20
trait MakesResources
21
{
22
    /**
23
     * A list of cached related resources.
24
     *
25
     * @var \League\Fractal\ResourceInterface[]
26
     */
27
    protected $resources = [];
28
29
    /**
30
     * Make a resource.
31
     *
32
     * @param  mixed                                                          $data
33
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable|null $transformer
34
     * @param  string|null                                                    $resourceKey
35
     * @return \League\Fractal\Resource\ResourceInterface
36
     */
37 22
    protected function resource($data = null, $transformer = null, string $resourceKey = null): ResourceInterface
38
    {
39 22
        if ($data instanceof ResourceInterface) {
40 2
            return $data;
41
        }
42
43 22
        $resourceFactory = $this->resolveContainer()->make(ResourceFactory::class);
44
45 22
        return $resourceFactory->make($data, $transformer, $resourceKey);
46
    }
47
48
    /**
49
     * Include a related resource.
50
     *
51
     * @param  string $identifier
52
     * @param  mixed  $data
53
     * @param  array  $parameters
54
     * @return \League\Fractal\Resource\ResourceInterface
55
     * @throws \LogicException
56
     */
57 23
    protected function includeResource(string $identifier, $data, array $parameters): ResourceInterface
58
    {
59 23
        $transformer = $this->mappedTransformerClass($identifier);
60
61 23
        if(config('responder.use_camel_case_relations')) {
62 22
            $identifier = Str::camel($identifier);
63
        }
64
65 23
        if (method_exists($this, $method = 'include' . ucfirst($identifier))) {
66 4
            $resource = $this->resource($this->$method($data, collect($parameters)), $transformer, $identifier);
67 20
        } elseif ($data instanceof Model) {
68 19
            $resource = $this->includeResourceFromModel($data, $identifier, $transformer);
69
        } else {
70 1
            throw new LogicException('Relation [' . $identifier . '] not found in [' . get_class($this) . '].');
71
        }
72
73 22
        return $resource;
74
    }
75
76
    /**
77
     * Include a related resource from a model and cache the resource type for following calls.
78
     *
79
     * @param  \Illuminate\Database\Eloquent\Model                            $model
80
     * @param  string                                                         $identifier
81
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable|null $transformer
82
     * @return \League\Fractal\Resource\ResourceInterface
83
     */
84 19
    protected function includeResourceFromModel(Model $model, string $identifier, $transformer = null): ResourceInterface
85
    {
86 19
        $data = $this->resolveRelation($model, $identifier);
87
88 19
        if (! $this->shouldCacheResource($data)) {
89 7
            return $this->resource($data, $transformer, $identifier);
90 19
        } elseif (key_exists($identifier, $this->resources)) {
91 2
            return $this->resources[$identifier]->setData($data);
92
        }
93
94 19
        return $this->resources[$identifier] = $this->resource($data, $transformer, $identifier);
95
    }
96
97
    /**
98
     * Indicates if the resource should be cached.
99
     *
100
     * @param  mixed $data
101
     * @return bool
102
     */
103 19
    protected function shouldCacheResource($data): bool
104
    {
105 19
        return is_array($data) || $data instanceof Countable ? count($data) > 0 : is_null($data);
106
    }
107
108
    /**
109
     * Resolve a container using the resolver callback.
110
     *
111
     * @return \Illuminate\Contracts\Container\Container
112
     */
113
    protected abstract function resolveContainer(): Container;
114
115
    /**
116
     * Resolve relation data from a model.
117
     *
118
     * @param  \Illuminate\Database\Eloquent\Model $model
119
     * @param  string                              $identifier
120
     * @return mixed
121
     */
122
    protected abstract function resolveRelation(Model $model, string $identifier);
123
124
    /**
125
     * Get a related transformer class mapped to a relation identifier.
126
     *
127
     * @param  string $identifier
128
     * @return string
129
     */
130
    protected abstract function mappedTransformerClass(string $identifier);
131
}