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

MakesResources::shouldCacheResource()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

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