GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — 3.x (#2341)
by
unknown
01:50
created

CallableResolver::constructCallable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 3
eloc 10
nc 3
nop 1
1
<?php
2
/**
3
 * Slim Framework (https://slimframework.com)
4
 *
5
 * @link      https://github.com/slimphp/Slim
6
 * @copyright Copyright (c) 2011-2017 Josh Lockhart
7
 * @license   https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
8
 */
9
namespace Slim;
10
11
use RuntimeException;
12
use Psr\Container\ContainerInterface;
13
use Slim\Interfaces\CallableResolverInterface;
14
15
/**
16
 * This class resolves a string of the format 'class:method' into a closure
17
 * that can be dispatched.
18
 */
19
final class CallableResolver implements CallableResolverInterface
20
{
21
    const CALLABLE_PATTERN = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!';
22
23
    /**
24
     * @var ContainerInterface
25
     */
26
    private $container;
27
28
    /**
29
     * @param ContainerInterface $container
30
     */
31
    public function __construct(ContainerInterface $container)
32
    {
33
        $this->container = $container;
34
    }
35
36
    /**
37
     * Resolve toResolve into a closure so that the router can dispatch.
38
     *
39
     * If toResolve is of the format 'class:method', then try to extract 'class'
40
     * from the container otherwise instantiate it and then dispatch 'method'.
41
     *
42
     * @param mixed $toResolve
43
     *
44
     * @return callable
45
     *
46
     * @throws RuntimeException if the callable does not exist
47
     * @throws RuntimeException if the callable is not resolvable
48
     */
49
    public function resolve($toResolve)
50
    {
51
        if (is_callable($toResolve)) {
52
            return $toResolve;
53
        }
54
55
        if (!is_string($toResolve)) {
56
            $this->assertCallable($toResolve);
57
        }
58
59
        // check for slim callable as "class:method"
60
        if (preg_match(self::CALLABLE_PATTERN, $toResolve, $matches)) {
61
            $resolved = $this->resolveCallable($matches[1], $matches[2]);
62
            $this->assertCallable($resolved);
63
64
            return $resolved;
65
        }
66
67
        $resolved = $this->resolveCallable($toResolve);
68
        $this->assertCallable($resolved);
69
70
        return $resolved;
71
    }
72
73
    /**
74
     * Check if string is something in the DIC
75
     * that's callable or is a class name which has an __invoke() method.
76
     *
77
     * @param string $class
78
     * @param string $method
79
     * @return callable
80
     */
81
    protected function resolveCallable($class, $method = '__invoke')
82
    {
83
        if ($this->container->has($class)) {
84
            return [$this->container->get($class), $method];
85
        }
86
87
        return [$this->constructCallable($class), $method];
88
    }
89
90
    /**
91
     * Check if string is a class that exists
92
     * and if so resolve the constructor arguments from the DiC
93
     *
94
     * @param string $class
95
     * @return object
96
     *
97
     * @throws \RuntimeException if the callable does not exist
98
     */
99
    protected function constructCallable($class)
100
    {
101
        if (!class_exists($class)) {
102
            throw new RuntimeException(sprintf('Callable %s does not exist', $class));
103
        }
104
105
        $reflection = new \ReflectionClass($class);
106
107
        $constructor = $reflection->getConstructor();
108
        $args = [];
109
        if ($constructor !== null) {
110
            $args = $this->resolveMethodArguments($constructor);
111
        }
112
113
        $callable = $reflection->newInstanceArgs($args);
114
        return $callable;
115
    }
116
117
    /**
118
     * Attempt to resolve method arguments from the DiC or pass in the container itself
119
     *
120
     * @param \ReflectionMethod $method
121
     * @return array
122
     *
123
     * @throws \RuntimeException if an argument is not type hinted or a dependency cannot be resolved
124
     */
125
    protected function resolveMethodArguments(\ReflectionMethod $method)
126
    {
127
        $args = [];
128
129
        $parameters = $method->getParameters();
130
        if (count($parameters) === 1 && $parameters[0]->getClass() === null) {
131
            // If there is a single un-type hinted argument then inject the container.
132
            // This is for backwards compatibility.
133
            $args[] = $this->container;
134
        } else {
135
            foreach ($method->getParameters() as $parameter) {
136
                $class = $parameter->getClass();
137
                if (!is_object($class)) {
138
                    throw new RuntimeException(sprintf('Argument %d for %s::%s must be type hinted',
139
                        $parameter->getPosition(), $method->getDeclaringClass()->getName(), $method->getName()));
0 ignored issues
show
introduced by
Consider using $method->class. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
140
                }
141
                if ($class->getName() == ContainerInterface::class) {
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
142
                    $args[] = $this->container;
143
                    continue;
144
                }
145
                if (!$this->container->has($class->getName())) {
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
146
                    throw new RuntimeException(sprintf('%s is not resolvable', $class->getName()));
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
147
                }
148
149
                $args[] = $this->container->get($class->getName());
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
150
            }
151
        }
152
153
        return $args;
154
    }
155
156
    /**
157
     * @param Callable $callable
158
     *
159
     * @throws \RuntimeException if the callable is not resolvable
160
     */
161
    protected function assertCallable($callable)
162
    {
163
        if (!is_callable($callable)) {
164
            throw new RuntimeException(sprintf(
165
                '%s is not resolvable',
166
                is_array($callable) || is_object($callable) ? json_encode($callable) : $callable
167
            ));
168
        }
169
    }
170
}
171