MainTransformation   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 78
rs 10
c 0
b 0
f 0
wmc 12

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A resolveTransformation() 0 6 2
B __invoke() 0 21 7
A transformIterable() 0 9 2
1
<?php
2
3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ICanBoogie\Transformation;
13
14
/**
15
 * A transformation that uses a provider to find the best transformation for a given data.
16
 *
17
 * This transformation is very useful when dealing with nested data, or when you don't want to deal with type
18
 * checking.
19
 */
20
class MainTransformation implements Transformation
21
{
22
    /**
23
     * @var TransformationProvider|callable
24
     */
25
    private $transformationProvider;
26
27
    /**
28
     * @var Transformation[]
29
     */
30
    private $cache = [];
31
32
    /**
33
     * @param TransformationProvider|callable $transformationProvider
34
     */
35
    public function __construct(callable $transformationProvider)
36
    {
37
        $this->transformationProvider = $transformationProvider;
38
    }
39
40
    /**
41
     * @param mixed $data
42
     * @param Transformation|callable|null $transformation If provided, the specified transformation is used
43
     * instead of this one as parameter for the transformation associated with the data.
44
     *
45
     * @return mixed
46
     */
47
    public function __invoke($data, callable $transformation = null)
48
    {
49
        if ($data === null || is_scalar($data)) {
50
            return $data;
51
        }
52
53
        $transformation = $transformation ?: $this;
54
55
        if (is_object($data)) {
56
            try {
57
                return $this->resolveTransformation($data)($data, $transformation);
58
            } catch (TransformationNotFound $e) {
59
                if (!$data instanceof \Traversable) {
60
                    throw $e;
61
                }
62
63
                // The Traversable does not have a transformation, let's iterate over it.
64
            }
65
        }
66
67
        return $this->transformIterable($data, $transformation);
68
    }
69
70
    /**
71
     * @param mixed $data
72
     *
73
     * @return callable
74
     */
75
    private function resolveTransformation($data): callable
76
    {
77
        $class = get_class($data);
78
        $transformation = &$this->cache[$class];
79
80
        return $transformation ?: $transformation = ($this->transformationProvider)($data);
0 ignored issues
show
introduced by
$transformation is of type ICanBoogie\Transformation\Transformation, thus it always evaluated to true.
Loading history...
81
    }
82
83
    /**
84
     * @param \Traversable|array $data
85
     * @param callable $transformation
86
     *
87
     * @return array
88
     */
89
    private function transformIterable($data, callable $transformation): array
90
    {
91
        $array = [];
92
93
        foreach ($data as $item) {
94
            $array[] = $this($item, $transformation);
95
        }
96
97
        return $array;
98
    }
99
}
100