Passed
Push — master ( 762564...748440 )
by Rustam
02:08
created

MiddlewareFactory   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 29
c 2
b 0
f 0
dl 0
loc 72
ccs 30
cts 30
cp 1
rs 10
wmc 17

5 Methods

Rating   Name   Duplication   Size   Complexity  
A isCallable() 0 12 5
A create() 0 3 1
A __construct() 0 4 1
A createMiddleware() 0 13 4
A validateMiddleware() 0 17 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 4
    public function __construct(ContainerInterface $container, WrapperFactory $wrapperFactory)
20
    {
21 4
        $this->container = $container;
22 4
        $this->wrapperFactory = $wrapperFactory;
23
    }
24
25 4
    public function create($middlewareDefinition): MiddlewareInterface
26
    {
27 4
        return $this->createMiddleware($middlewareDefinition);
28
    }
29
30
    /**
31
     * @param array|callable|string $middlewareDefinition
32
     *
33
     * @return MiddlewareInterface
34
     */
35 4
    private function createMiddleware($middlewareDefinition): MiddlewareInterface
36
    {
37 4
        $this->validateMiddleware($middlewareDefinition);
38
39 3
        if (is_string($middlewareDefinition)) {
40 1
            return $this->container->get($middlewareDefinition);
41
        }
42
43 2
        if (is_array($middlewareDefinition) && !is_object($middlewareDefinition[0])) {
44 1
            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
        }
46
47 1
        return $this->wrapperFactory->createCallableWrapper($middlewareDefinition);
48
    }
49
50
    /**
51
     * @param array|callable|string $middlewareDefinition
52
     */
53 4
    private function validateMiddleware($middlewareDefinition): void
54
    {
55 4
        if (is_string($middlewareDefinition) && is_subclass_of($middlewareDefinition, MiddlewareInterface::class)) {
56 1
            return;
57
        }
58
59 3
        if ($this->isCallable($middlewareDefinition)
60 2
            && (!is_array($middlewareDefinition)
61 3
                || !is_object($middlewareDefinition[0]))
62
        ) {
63 2
            return;
64
        }
65
66 1
        throw new InvalidArgumentException(
67 1
            sprintf(
68
                'Parameter should be either PSR middleware class name or a callable, "%s" given.',
69 1
                get_debug_type($middlewareDefinition),
70
            )
71
        );
72
    }
73
74 3
    private function isCallable($definition): bool
75
    {
76 3
        if (is_callable($definition)) {
77 1
            return true;
78
        }
79
80 2
        return is_array($definition)
81 2
            && array_keys($definition) === [0, 1]
82 1
            && in_array(
83 1
                $definition[1],
84 1
                class_exists($definition[0]) ? get_class_methods($definition[0]) : [],
85
                true
86
            );
87
    }
88
}
89