Completed
Branch master (c0d8ef)
by Yaroslav
06:36
created

RequestContextFactory::createContext()   B

Complexity

Conditions 9
Paths 1

Size

Total Lines 65
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 9

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 65
rs 8.0555
c 0
b 0
f 0
ccs 29
cts 29
cp 1
cc 9
nc 1
nop 1
crap 9

How to fix   Long Method   

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
2
3
/*
4
 *
5
 * (c) Yaroslav Honcharuk <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Yarhon\RouteGuardBundle\Security\Http;
12
13
use Symfony\Component\HttpFoundation\RequestStack;
14
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
15
use Yarhon\RouteGuardBundle\Routing\RouteContextInterface;
16
use Yarhon\RouteGuardBundle\Routing\GeneratedUrlAwareInterface;
17
18
/**
19
 * @author Yaroslav Honcharuk <[email protected]>
20
 */
21
class RequestContextFactory
22
{
23
    /**
24
     * @var RequestStack
25
     */
26
    private $requestStack;
27
28
    /**
29
     * @var UrlGeneratorInterface
30
     */
31
    private $urlGenerator;
32
33
    /**
34
     * @param RequestStack          $requestStack
35
     * @param UrlGeneratorInterface $urlGenerator
36
     */
37 14
    public function __construct(RequestStack $requestStack, UrlGeneratorInterface $urlGenerator)
38
    {
39 14
        $this->requestStack = $requestStack;
40 14
        $this->urlGenerator = $urlGenerator;
41 14
    }
42
43
    /**
44
     * @param RouteContextInterface $routeContext
45
     *
46
     * @return RequestContext
47
     */
48 8
    public function createContext(RouteContextInterface $routeContext)
49
    {
50 8
        $urlGenerator = $this->urlGenerator;
51 8
        $urlGeneratorContext = $this->urlGenerator->getContext();
52
53
        $generateUrlClosure = function () use ($routeContext, $urlGenerator) {
54 6
            static $generated;
55
56 6
            if (null === $generated) {
57 6
                if (!($routeContext instanceof GeneratedUrlAwareInterface) || null === $routeContext->getReferenceType()) {
58 1
                    $generated = $urlGenerator->generate($routeContext->getName(), $routeContext->getParameters(), UrlGeneratorInterface::ABSOLUTE_PATH);
59
                } else {
60 5
                    $referenceType = $routeContext->getReferenceType();
61
62
                    // We need to parse path and host from the generated url, that depends on reference type.
63
                    // When using ABSOLUTE_URL or NETWORK_PATH, generated url will contain both path and host.
64
                    //
65
                    // When using ABSOLUTE_PATH or RELATIVE_PATH, generated url will contain only path.
66
                    // If route has some specific host assigned, the UrlGenerator will force reference type to
67
                    // ABSOLUTE_URL or NETWORK_PATH, that would produce url with host.
68
                    // So, with ABSOLUTE_PATH or RELATIVE_PATH, if generated url does not contains host, we can be sure
69
                    // that the host is the "current" host, and grab it from UrlGenerator context.
70
                    // Finally, with RELATIVE_PATH we can't simply determine path (absolute), so we force generation to
71
                    // ABSOLUTE_URL, and don't save the generated url.
72
73 5
                    if (UrlGeneratorInterface::RELATIVE_PATH === $referenceType) {
74 1
                        $referenceType = UrlGeneratorInterface::ABSOLUTE_URL;
75
                    }
76
77 5
                    $generated = $urlGenerator->generate($routeContext->getName(), $routeContext->getParameters(), $referenceType);
78
79 5
                    if (UrlGeneratorInterface::RELATIVE_PATH !== $routeContext->getReferenceType()) {
80 4
                        $routeContext->setGeneratedUrl($generated);
81
                    }
82
                }
83
            }
84
85 6
            return $generated;
86 8
        };
87
88
        $pathInfoClosure = function () use ($generateUrlClosure, $urlGeneratorContext) {
89 4
            $url = $generateUrlClosure();
90 4
            $pathInfo = parse_url($url, PHP_URL_PATH);
91 4
            $pathInfo = substr($pathInfo, strlen($urlGeneratorContext->getBaseUrl()));
92
93
            // See \Symfony\Component\HttpFoundation\Request::preparePathInfo
94 4
            if (false === $pathInfo || '' === $pathInfo) {
95 1
                $pathInfo = '/';
96
            }
97
98 4
            return $pathInfo;
99 8
        };
100
101
        $hostClosure = function () use ($generateUrlClosure, $urlGeneratorContext) {
102 2
            $url = $generateUrlClosure();
103 2
            $host = parse_url($url, PHP_URL_HOST) ?: $urlGeneratorContext->getHost();
104
105 2
            return $host;
106 8
        };
107
108 8
        $request = $this->requestStack->getCurrentRequest();
109
110 8
        $requestContext = new RequestContext($pathInfoClosure, $hostClosure, $routeContext->getMethod(), $request->getClientIp());
111
112 8
        return $requestContext;
113
    }
114
}
115