Completed
Pull Request — master (#4)
by Iacovos
15:59
created

CallableResolver::fillClass()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 14
ccs 0
cts 0
cp 0
rs 8.2222
cc 7
eloc 7
nc 6
nop 1
crap 56
1
<?php
2
3
namespace Softius\ResourcesResolver;
4
5
use Interop\Container\ContainerInterface;
6
7
/**
8
 * Class CallableResolver.
9
 */
10
class CallableResolver implements ResolvableInterface
11
{
12
    const DEFAULT_METHOD_SEPARATOR = '::';
13
14
    const MODE_STRICT = 0b0001;
15 8
    const MODE_LAZYLOAD = 0b0010;
16
17 8
    /**
18 8
     * @var ContainerInterface
19
     */
20
    private $container;
21
22
    /**
23
     * @var null|string
24
     */
25 5
    private $method_separator;
26
27 5
    /**
28
     * @var int
29
     */
30
    private $modes;
31
32
    /**
33
     * DefaultCallableStrategy constructor.
34
     *
35 3
     * @param \Interop\Container\ContainerInterface $container
36
     * @param string                                $method_separator
37 3
     */
38
    public function __construct(ContainerInterface $container = null, $method_separator = null)
39
    {
40
        $this->container = $container;
41
        $this->method_separator = ($method_separator === null) ? self::DEFAULT_METHOD_SEPARATOR : $method_separator;
42
        $this->modes = 0;
43
    }
44
45
    /**
46
     * @param string $class
47
     * @return string
48
     */
49
    protected function fillClass($class)
50
    {
51
        // Use backtrace to find the calling Class
52
        if (empty($class) || $class === 'parent' || $class === 'self') {
53
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
54
            $class = ($class === 'parent') ? get_parent_class($trace[3]['class']) : $trace[3]['class'];
55
        }
56
57
        if ($this->container !== null && $this->container->has($class)) {
58
            $class = $this->container->get($class);
59
        }
60
61
        return $class;
62
    }
63
64
    /**
65
     * @param int $mode
66
     */
67
    public function setMode($mode)
0 ignored issues
show
Unused Code introduced by
The parameter $mode is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
    {
69
        $this->modes = $modes;
0 ignored issues
show
Bug introduced by
The variable $modes does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
70
    }
71
72
    /**
73
     * @param int $mode
74
     * @return boolean
75
     */
76
    public function isMode($mode)
77
    {
78
        return ($this->modes & $mode);
79
    }
80
81
    /**
82
     * @param string $in
83
     * @return array|\Closure
84
     * @throws \Exception
85
     */
86
    public function resolve($in)
87
    {
88
        if ($this->isMode(self::MODE_STRICT) && $this->isMode(self::MODE_LAZYLOAD)) {
89
            return function() use ($in) {
90
                return $this->resolveStrict($in);
91
            };
92
        } elseif ($this->isMode(self::MODE_STRICT)) {
93
            return $this->resolveStrict($in);
94
        } elseif ($this->isMode(self::MODE_LAZYLOAD)) {
95
            return function() use ($in) {
96
                return $this->resolveCallable($in);
97
            };
98
        } else {
99
            return $this->resolveCallable($in);
100
        }
101
    }
102
103
    /**
104
     * @param string $in
105
     *
106
     * @return array
107
     *
108
     * @throws \Exception
109
     */
110
    protected function resolveCallable($in)
111
    {
112
        $pos = strrpos($in, $this->method_separator);
113
        if ($pos === false) {
114
            throw new \Exception(sprintf('Method separator not found in %s', $in));
115
        }
116
117
        $class = substr($in, 0, $pos);
118
        $class = $this->fillClass($class);
119
        $method = substr($in, $pos + strlen($this->method_separator));
120
121
        return [$class, $method];
122
    }
123
124
    /**
125
     * @param $in
126
     *
127
     * @return array
128
     *
129
     * @throws \Exception
130
     */
131
    protected function resolveStrict($in)
132
    {
133
        $callable = $this->resolveCallable($in);
134
        if (is_callable($callable)) {
135
            return $callable;
136
        }
137
138
        throw new \Exception(sprintf('Could not resolve %s to a callable', $in));
139
    }
140
}
141