Passed
Push — master ( e122d6...753728 )
by Alexander
02:47
created

TransformerResolver::resolveTransformableItem()   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 Traversable;
10
11
/**
12
 * This class is responsible for resolving transformers.
13
 *
14
 * @package flugger/laravel-responder
15
 * @author  Alexander Tømmerås <[email protected]>
16
 * @license The MIT License
17
 */
18
class TransformerResolver implements TransformerResolverContract
19
{
20
    /**
21
     * Transformable to transformer mappings.
22
     *
23
     * @var array
24
     */
25
    protected $bindings = [];
26
27
    /**
28
     * A container used to resolve transformers.
29
     *
30
     * @var \Illuminate\Contracts\Container\Container
31
     */
32
    protected $container;
33
34
    /**
35
     * A fallback transformer to return when no transformer can be resolved.
36
     *
37
     * @var \Flugg\Responder\Transformers\Transformer|string|callable
38
     */
39
    protected $fallback;
40
41
    /**
42
     * Construct the resolver class.
43
     *
44
     * @param \Illuminate\Contracts\Container\Container                 $container
45
     * @param \Flugg\Responder\Transformers\Transformer|string|callable $fallback
46
     */
47 57
    public function __construct(Container $container, $fallback)
48
    {
49 57
        $this->container = $container;
50 57
        $this->fallback = $fallback;
51 57
    }
52
53
    /**
54
     * Register a transformable to transformer binding.
55
     *
56
     * @param  string|array         $transformable
57
     * @param  string|callback|null $transformer
58
     * @return void
59
     */
60 2
    public function bind($transformable, $transformer = null)
61
    {
62 2
        $this->bindings = array_merge($this->bindings, is_array($transformable) ? $transformable : [
63 2
            $transformable => $transformer,
64
        ]);
65 2
    }
66
67
    /**
68
     * Resolve a transformer.
69
     *
70
     * @param  \Flugg\Responder\Transformers\Transformer|string|callable $transformer
71
     * @return \Flugg\Responder\Transformers\Transformer|callable
72
     * @throws \Flugg\Responder\Exceptions\InvalidTransformerException
73
     */
74 46
    public function resolve($transformer)
75
    {
76 46
        if (is_string($transformer)) {
77 36
            return $this->container->make($transformer);
78
        }
79
80 33
        if (! is_callable($transformer) && ! $transformer instanceof Transformer) {
81 1
            throw new InvalidTransformerException;
82
        }
83
84 32
        return $transformer;
85
    }
86
87
    /**
88
     * Resolve a transformer from the given data.
89
     *
90
     * @param  mixed $data
91
     * @return \Flugg\Responder\Transformers\Transformer|callable
92
     */
93 30
    public function resolveFromData($data)
94
    {
95 30
        $transformer = $this->resolveTransformer($this->resolveTransformableItem($data));
96
97 30
        return $this->resolve($transformer);
0 ignored issues
show
Bug introduced by
It seems like $transformer defined by $this->resolveTransforme...ansformableItem($data)) on line 95 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...
98
    }
99
100
    /**
101
     * Resolve a transformer from the transformable element.
102
     *
103
     * @param  mixed $transformable
104
     * @return \Flugg\Responder\Contracts\Transformable|callable
105
     */
106 30 View Code Duplication
    protected function resolveTransformer($transformable)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
    {
108 30
        if (is_object($transformable) && key_exists(get_class($transformable), $this->bindings)) {
109 2
            return $this->bindings[get_class($transformable)];
110
        }
111
112 28
        if ($transformable instanceof Transformable) {
113 5
            return $transformable->transformer();
114
        }
115
116 23
        return $this->resolve($this->fallback);
117
    }
118
119
    /**
120
     * Resolve a transformable item from the given data.
121
     *
122
     * @param  mixed $data
123
     * @return mixed
124
     */
125 30
    protected function resolveTransformableItem($data)
126
    {
127 30
        if (is_array($data) || $data instanceof Traversable) {
128 15
            foreach ($data as $item) {
129 15
                return $item;
130
            }
131
        }
132
133 15
        return $data;
134
    }
135
}