Completed
Push — master ( 22a756...a8d83f )
by John
02:03
created

OperationMatcher::process()   C

Complexity

Conditions 11
Paths 29

Size

Total Lines 46
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 46
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 24
nc 29
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types = 1);
2
/*
3
 * This file is part of the KleijnWeb\PhpApi\Descriptions package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
namespace KleijnWeb\PhpApi\Middleware;
9
10
use Interop\Http\ServerMiddleware\DelegateInterface;
11
use KleijnWeb\PhpApi\Descriptions\Description\Description;
12
use KleijnWeb\PhpApi\Descriptions\Description\Parameter;
13
use KleijnWeb\PhpApi\Descriptions\Description\Repository;
14
use KleijnWeb\PhpApi\Descriptions\Description\Schema\ScalarSchema;
15
use KleijnWeb\PhpApi\Middleware\Util\Meta;
16
use KleijnWeb\PhpApi\Middleware\Util\ParameterTypePatternResolver;
17
use KleijnWeb\PhpApi\Middleware\Util\PhpApiMiddleware;
18
use Middlewares\Utils\Factory;
19
use Psr\Http\Message\ResponseInterface;
20
use Psr\Http\Message\ServerRequestInterface;
21
22
class OperationMatcher extends PhpApiMiddleware
23
{
24
    /**
25
     * @var Repository
26
     */
27
    private $repository;
28
29
    /**
30
     * @var ParameterTypePatternResolver
31
     */
32
    private $typePatternResolver;
33
34
    /**
35
     * @param Repository                   $repository
36
     * @param ParameterTypePatternResolver $typePatternResolver
37
     */
38
    public function __construct(Repository $repository, ParameterTypePatternResolver $typePatternResolver = null)
39
    {
40
        $this->repository          = $repository;
41
        $this->typePatternResolver = $typePatternResolver ?: new ParameterTypePatternResolver();
42
    }
43
44
    /**
45
     * Process a server request and return a response.
46
     *
47
     * @param ServerRequestInterface $request
48
     * @param DelegateInterface      $delegate
49
     *
50
     * @return ResponseInterface
51
     */
52
    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
53
    {
54
        $uriPath = $request->getUri()->getPath();
55
56
        /** @var Description $description */
57
        foreach ($this->repository as $description) {
58
59
            $basePath = $description->getBasePath() ? "{$description->getBasePath()}/" : "";
60
61
            foreach ($description->getPaths() as $path) {
62
                $pathPattern = "$basePath{$path->getPath()}";
63
64
                $parameterNames = [];
65
                foreach ($path->getOperations() as $operation) {
66
                    foreach ($operation->getParameters() as $parameter) {
67
                        if ($parameter->getIn() === Parameter::IN_PATH
68
                            && ($schema = $parameter->getSchema()) instanceof ScalarSchema
69
                        ) {
70
                            $parameterName    = $parameter->getName();
71
                            $parameterNames[] = $parameterName;
72
                            $typePattern      = $this->typePatternResolver->resolve($schema);
73
                            $parameterPattern = "(?P<$parameterName>$typePattern)(?=(/|$))";
74
                            $pathPattern      = str_replace('{'.$parameterName.'}', $parameterPattern, $pathPattern);
75
                        }
76
                    }
77
78
                    if (preg_match("#^$pathPattern$#", $uriPath, $matches) > 0) {
79
                        if (strtolower($request->getMethod()) !== $operation->getMethod()) {
80
                            return Factory::createResponse(405);
81
                        }
82
83
                        $request = Meta::requestWith($request, $description, $operation, $path);
84
85
                        foreach ($parameterNames as $parameterName) {
86
                            $request = $request->withAttribute($parameterName, $matches[$parameterName]);
87
                        }
88
89
                        return $delegate->process($request);
90
                    }
91
                }
92
93
            }
94
        }
95
96
        return Factory::createResponse(404);
97
    }
98
}