Completed
Pull Request — master (#210)
by Ryan
07:26
created

Evaluator   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 20
c 3
b 1
f 0
lcom 0
cbo 1
dl 0
loc 120
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C evaluate() 0 30 7
A isTraversable() 0 4 1
C data() 0 43 11
1
<?php namespace Anomaly\Streams\Platform\Support;
2
3
use ArrayAccess;
4
use Illuminate\Contracts\Container\Container;
5
6
/**
7
 * Class Evaluator
8
 *
9
 * @link    http://anomaly.is/streams-platform
10
 * @author  AnomalyLabs, Inc. <[email protected]>
11
 * @author  Ryan Thompson <[email protected]>
12
 * @package Anomaly\Streams\Platform\Support
13
 */
14
class Evaluator
15
{
16
17
    /**
18
     * The IoC container.
19
     *
20
     * @var \Illuminate\Contracts\Container\Container
21
     */
22
    protected $container;
23
24
    /**
25
     * Create a new Evaluator instance.
26
     *
27
     * @param Container $container
28
     */
29
    public function __construct(Container $container)
30
    {
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * Evaluate a target entity with arguments.
36
     *
37
     * @param        $target
38
     * @param  array $arguments
39
     * @return mixed
40
     */
41
    public function evaluate($target, array $arguments = [])
42
    {
43
        /**
44
         * If the target is an instance of Closure then
45
         * call through the IoC it with the arguments.
46
         */
47
        if ($target instanceof \Closure) {
48
            return $this->container->call($target, $arguments);
49
        }
50
51
        /**
52
         * If the target is an array then evaluate
53
         * each of it's values.
54
         */
55
        if (is_array($target)) {
56
            foreach ($target as &$value) {
57
                $value = $this->evaluate($value, $arguments);
58
            }
59
        }
60
61
        /**
62
         * if the target is a string and is in a traversable
63
         * format then traverse the target using the arguments.
64
         */
65
        if (is_string($target) && !isset($arguments[$target]) && $this->isTraversable($target)) {
66
            $target = $this->data($arguments, $target, $target);
0 ignored issues
show
Unused Code introduced by
The call to Evaluator::data() has too many arguments starting with $target.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
67
        }
68
69
        return $target;
70
    }
71
72
    /**
73
     * Check if a string is in a traversable format.
74
     *
75
     * @param  $target
76
     * @return bool
77
     */
78
    protected function isTraversable($target)
79
    {
80
        return (!preg_match('/[^a-z._]/', $target));
81
    }
82
83
    /**
84
     * Return the data from the key.
85
     *
86
     * @param $arguments
87
     * @param $target
88
     * @return mixed
89
     */
90
    protected function data($arguments, $target)
91
    {
92
        if (is_null($arguments)) {
93
            return $target;
94
        }
95
96
        $arguments = is_array($arguments) ? $arguments : explode('.', $arguments);
97
98
        foreach ($arguments as $segment) {
99
            if (is_array($target)) {
100
                if (!array_key_exists($segment, $target)) {
101
                    return value($target);
102
                }
103
104
                $target = $target[$segment];
105
            } elseif ($target instanceof ArrayAccess) {
106
                if (!isset($target[$segment])) {
107
                    return value($target);
108
                }
109
110
                $target = $target[$segment];
111
            } elseif (is_object($target)) {
112
113
                /**
114
                 * Check if the method exists first
115
                 * otherwise we might end up trying to
116
                 * access relational methods.
117
                 *
118
                 * Otherwise this is identical from
119
                 * data_get helper.
120
                 */
121
                if (method_exists($target, $segment) || !isset($target->{$segment})) {
122
                    return value($target);
123
                }
124
125
                $target = $target->{$segment};
126
            } else {
127
                return value($target);
128
            }
129
        }
130
131
        return $target;
132
    }
133
}
134