Passed
Push — master ( ef34b2...e07722 )
by Alexander
02:33
created

TransformerResolver::resolveTransformable()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 3
nop 1
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Flugg\Responder\Transformers;
4
5
use Flugg\Responder\Contracts\Transformable;
6
use Flugg\Responder\Contracts\Transformers\TransformerResolver as TransformerResolverContract;
7
use Flugg\Responder\Exceptions\InvalidTransformerException;
8
use Illuminate\Contracts\Container\Container;
9
use Illuminate\Contracts\Support\Arrayable;
10
use Traversable;
11
12
/**
13
 * This class is responsible for resolving transformers.
14
 *
15
 * @package flugger/laravel-responder
16
 * @author  Alexander Tømmerås <[email protected]>
17
 * @license The MIT License
18
 */
19
class TransformerResolver implements TransformerResolverContract
20
{
21
    /**
22
     * A container used to resolve transformers.
23
     *
24
     * @var \Illuminate\Contracts\Container\Container
25
     */
26
    protected $container;
27
28
    /**
29
     * Transformable to transformer mappings.
30
     *
31
     * @var array
32
     */
33
    protected $bindings = [];
34
35
    /**
36
     * Construct the resolver class.
37
     *
38
     * @param \Illuminate\Contracts\Container\Container $container
39
     */
40 8
    public function __construct(Container $container)
41
    {
42 8
        $this->container = $container;
43 8
    }
44
45
    /**
46
     * Register a transformable to transformer binding.
47
     *
48
     * @param  string|array         $transformable
49
     * @param  string|callback|null $transformer
50
     * @return void
51
     */
52 1
    public function bind($transformable, $transformer = null)
53
    {
54 1
        $this->bindings = array_merge($this->bindings, is_array($transformable) ? $transformable : [
55 1
            $transformable => $transformer,
56
        ]);
57 1
    }
58
59
    /**
60
     * Resolve a transformer.
61
     *
62
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable $transformer
63
     * @return \Flugg\Responder\Transformers\Transformer|callable
64
     * @throws \Flugg\Responder\Exceptions\InvalidTransformerException
65
     */
66 8
    public function resolve($transformer)
67
    {
68 8
        if (is_string($transformer)) {
69 1
            return $this->container->make($transformer);
70
        }
71
72 7
        if (! is_callable($transformer) && ! $transformer instanceof Transformer) {
73 1
            throw new InvalidTransformerException;
74
        }
75
76 6
        return $transformer;
77
    }
78
79
    /**
80
     * Resolve a transformer from the given data.
81
     *
82
     * @param  mixed $data
83
     * @return \Flugg\Responder\Transformers\Transformer|callable
84
     */
85 4
    public function resolveFromData($data)
86
    {
87 4
        $transformable = $this->resolveTransformable($data);
88 4
        $transformer = $this->resolveTransformer($transformable);
89
90 4
        return $this->resolve($transformer);
0 ignored issues
show
Bug introduced by
It seems like $transformer defined by $this->resolveTransformer($transformable) on line 88 can also be of type object<Flugg\Responder\Contracts\Transformable>; however, Flugg\Responder\Transfor...rmerResolver::resolve() does only seem to accept callable, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
91
    }
92
93
    /**
94
     * Resolve a transformable from the given data.
95
     *
96
     * @param  mixed $data
97
     * @return mixed
98
     */
99 4
    protected function resolveTransformable($data)
100
    {
101 4
        if (is_array($data) || $data instanceof Traversable) {
102 1
            foreach ($data as $item) {
103 1
                return $item;
104
            }
105
        }
106
107 3
        return $data;
108
    }
109
110
    /**
111
     * Resolve a transformer from the transformable element.
112
     *
113
     * @param  mixed $transformable
114
     * @return \Flugg\Responder\Contracts\Transformable|callable
115
     */
116 4
    protected function resolveTransformer($transformable)
117
    {
118 4
        if (is_object($transformable) && key_exists(get_class($transformable), $this->bindings)) {
119 1
            return $this->bindings[get_class($transformable)];
120
        }
121
122 3
        if ($transformable instanceof Transformable) {
123 2
            return $transformable->transformer();
124
        }
125
126 1
        return $this->resolveFallbackTransformer();
127
    }
128
129
    /**
130
     * Resolve a fallback closure transformer just returning the data directly.
131
     *
132
     * @return callable
133
     */
134
    protected function resolveFallbackTransformer()
135
    {
136 1
        return function ($data) {
137 1
            return $data instanceof Arrayable ? $data->toArray() : $data;
138 1
        };
139
    }
140
}