Test Failed
Pull Request — master (#48)
by Alexander
02:18
created

MiddlewareFactory::validateMiddleware()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 10
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 17
rs 9.2222
ccs 8
cts 8
cp 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\RequestModel;
6
7
use InvalidArgumentException;
8
use Psr\Container\ContainerInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Yiisoft\Middleware\Dispatcher\MiddlewareFactoryInterface;
11
12
use function get_debug_type;
13
14
final class MiddlewareFactory implements MiddlewareFactoryInterface
15
{
16
    private ContainerInterface $container;
17
    private WrapperFactory $wrapperFactory;
18
19
    public function __construct(ContainerInterface $container, WrapperFactory $wrapperFactory)
20
    {
21 4
        $this->container = $container;
22
        $this->wrapperFactory = $wrapperFactory;
23 4
    }
24 4
25
    public function create($middlewareDefinition): MiddlewareInterface
26
    {
27 4
        return $this->createMiddleware($middlewareDefinition);
28
    }
29 4
30
    /**
31
     * @param array|callable|string $middlewareDefinition
32
     *
33
     * @return MiddlewareInterface
34
     */
35
    private function createMiddleware($middlewareDefinition): MiddlewareInterface
36
    {
37 4
        $this->validateMiddleware($middlewareDefinition);
38
39 4
        if (is_string($middlewareDefinition)) {
40
            return $this->container->get($middlewareDefinition);
41 3
        }
42 1
43
        if (is_array($middlewareDefinition) && !is_object($middlewareDefinition[0])) {
44
            return $this->wrapperFactory->createActionWrapper(...$middlewareDefinition);
0 ignored issues
show
Bug introduced by
The call to Yiisoft\RequestModel\Wra...::createActionWrapper() has too few arguments starting with method. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
            return $this->wrapperFactory->/** @scrutinizer ignore-call */ createActionWrapper(...$middlewareDefinition);

This check compares calls to functions or methods with their respective definitions. If the call has less 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. Please note the @ignore annotation hint above.

Loading history...
45 2
        }
46 1
47
        return $this->wrapperFactory->createCallableWrapper($middlewareDefinition);
48
    }
49 1
50
    /**
51
     * @param array|callable|string $middlewareDefinition
52
     */
53
    private function validateMiddleware($middlewareDefinition): void
54
    {
55 4
        if (is_string($middlewareDefinition) && is_subclass_of($middlewareDefinition, MiddlewareInterface::class)) {
56
            return;
57 4
        }
58 1
59
        if ($this->isCallable($middlewareDefinition)
60
            && (!is_array($middlewareDefinition)
61 3
                || !is_object($middlewareDefinition[0]))
62 2
        ) {
63
            return;
64
        }
65 1
66 1
        throw new InvalidArgumentException(
67
            sprintf(
68 1
                'Parameter should be either PSR middleware class name or a callable, "%s" given.',
69
                get_debug_type($middlewareDefinition),
70
            )
71
        );
72
    }
73 3
74
    private function isCallable($definition): bool
75 3
    {
76 1
        if (is_callable($definition)) {
77
            return true;
78
        }
79 2
80
        return is_array($definition)
81
            && array_keys($definition) === [0, 1]
82
            && in_array(
83
                $definition[1],
84
                class_exists($definition[0]) ? get_class_methods($definition[0]) : [],
85
                true
86
            );
87
    }
88
}
89