Completed
Push — master ( 12c6b6...f78727 )
by Iacovos
02:10
created

CallableResolver::resolveStrict()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
crap 2
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
    const MODE_LAZYLOAD = 0b0010;
16
17
    /**
18
     * @var ContainerInterface
19
     */
20
    private $container;
21
22
    /**
23
     * @var null|string
24
     */
25
    private $method_separator;
26
27
    /**
28
     * @var int
29
     */
30
    private $modes;
31
32
    /**
33
     * DefaultCallableStrategy constructor.
34
     *
35
     * @param \Interop\Container\ContainerInterface $container
36
     * @param string                                $method_separator
37
     */
38 10
    public function __construct(ContainerInterface $container = null, $method_separator = null)
39
    {
40 10
        $this->container = $container;
41 10
        $this->method_separator = ($method_separator === null) ? self::DEFAULT_METHOD_SEPARATOR : $method_separator;
42 10
        $this->modes = 0;
43 10
    }
44
45
    /**
46
     * @param string $class
47
     * @return string
48
     */
49 9
    protected function fillClass($class)
50
    {
51
        // Use backtrace to find the calling Class
52 9
        if (empty($class) || $class === 'parent' || $class === 'self') {
53 3
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
54 3
            $class = ($class === 'parent') ? get_parent_class($trace[3]['class']) : $trace[3]['class'];
55 3
        }
56
57 9
        if ($this->container !== null && $this->container->has($class)) {
58 2
            $class = $this->container->get($class);
59 2
        }
60
61 9
        return $class;
62
    }
63
64
    /**
65
     * @param int $mode
66
     */
67 5
    public function setMode($mode)
68
    {
69 5
        $this->modes = $mode;
70 5
    }
71
72
    /**
73
     * @param int $mode
74
     * @return boolean
75
     */
76 10
    public function isMode($mode)
77
    {
78 10
        return ($this->modes & $mode);
79
    }
80
81
    /**
82
     * @param string $in
83
     * @return array|\Closure
84
     * @throws \Exception
85
     */
86 10
    public function resolve($in)
87
    {
88 10
        if ($this->isMode(self::MODE_STRICT) && $this->isMode(self::MODE_LAZYLOAD)) {
89
            return function() use ($in) {
90 1
                return $this->resolveStrict($in);
91 1
            };
92 9
        } elseif ($this->isMode(self::MODE_STRICT)) {
93 3
            return $this->resolveStrict($in);
94 6
        } elseif ($this->isMode(self::MODE_LAZYLOAD)) {
95 1
            return function() use ($in) {
96 1
                return $this->resolveCallable($in);
97 1
            };
98
        } else {
99 5
            return $this->resolveCallable($in);
100
        }
101
    }
102
103
    /**
104
     * @param string $in
105
     *
106
     * @return array
107
     *
108
     * @throws \Exception
109
     */
110 10
    protected function resolveCallable($in)
111
    {
112 10
        $pos = strrpos($in, $this->method_separator);
113 10
        if ($pos === false) {
114 1
            throw new \Exception(sprintf('Method separator not found in %s', $in));
115
        }
116
117 9
        $class = substr($in, 0, $pos);
118 9
        $class = $this->fillClass($class);
119 9
        $method = substr($in, $pos + strlen($this->method_separator));
120
121 9
        return [$class, $method];
122
    }
123
124
    /**
125
     * @param $in
126
     *
127
     * @return array
128
     *
129
     * @throws \Exception
130
     */
131 4
    protected function resolveStrict($in)
132
    {
133 4
        $callable = $this->resolveCallable($in);
134 4
        if (is_callable($callable)) {
135 3
            return $callable;
136
        }
137
138 1
        throw new \Exception(sprintf('Could not resolve %s to a callable', $in));
139
    }
140
}
141