Completed
Push — 6.7 ( b0deca...188029 )
by André
13:43
created

DefaultRouter::generate()   C

Complexity

Conditions 17
Paths 40

Size

Total Lines 54
Code Lines 33

Duplication

Lines 13
Ratio 24.07 %

Importance

Changes 0
Metric Value
cc 17
eloc 33
nc 40
nop 3
dl 13
loc 54
rs 6.6619
c 0
b 0
f 0

How to fix   Long Method    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
2
3
/**
4
 * File containing the DefaultRouter class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Bundle\EzPublishCoreBundle\Routing;
10
11
use eZ\Publish\Core\MVC\ConfigResolverInterface;
12
use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest;
13
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
14
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
15
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface;
16
use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer;
17
use Symfony\Bundle\FrameworkBundle\Routing\Router;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\Routing\Exception\RouteNotFoundException;
20
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
21
22
/**
23
 * Extension of Symfony default router implementing RequestMatcherInterface.
24
 */
25
class DefaultRouter extends Router implements RequestMatcherInterface, SiteAccessAware
26
{
27
    /**
28
     * @var SiteAccess
29
     */
30
    protected $siteAccess;
31
32
    protected $nonSiteAccessAwareRoutes = array();
33
34
    /**
35
     * @var \eZ\Publish\Core\MVC\ConfigResolverInterface
36
     */
37
    protected $configResolver;
38
39
    /**
40
     * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface
41
     */
42
    protected $siteAccessRouter;
43
44
    public function setConfigResolver(ConfigResolverInterface $configResolver)
45
    {
46
        $this->configResolver = $configResolver;
47
    }
48
49
    public function setSiteAccess(SiteAccess $siteAccess = null)
50
    {
51
        $this->siteAccess = $siteAccess;
52
    }
53
54
    /**
55
     * Injects route names that are not supposed to be SiteAccess aware.
56
     * i.e. Routes pointing to asset generation (like assetic).
57
     *
58
     * @param array $routes
59
     */
60
    public function setNonSiteAccessAwareRoutes(array $routes)
61
    {
62
        $this->nonSiteAccessAwareRoutes = $routes;
63
    }
64
65
    /**
66
     * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface $siteAccessRouter
67
     */
68
    public function setSiteAccessRouter(SiteAccessRouterInterface $siteAccessRouter)
69
    {
70
        $this->siteAccessRouter = $siteAccessRouter;
71
    }
72
73
    public function matchRequest(Request $request)
74
    {
75
        return $this->match($request->attributes->get('semanticPathinfo', $request->getPathInfo()));
76
    }
77
78
    public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
79
    {
80
        $siteAccess = $this->siteAccess;
81
        $originalContext = $context = $this->getContext();
82
        $isSiteAccessAware = $this->isSiteAccessAwareRoute($name);
83
84
        // Retrieving the appropriate SiteAccess to generate the link for.
85 View Code Duplication
        if (isset($parameters['siteaccess']) && $isSiteAccessAware) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
            $siteAccess = $this->siteAccessRouter->matchByName($parameters['siteaccess']);
87
            if ($siteAccess instanceof SiteAccess && $siteAccess->matcher instanceof SiteAccess\VersatileMatcher) {
88
                // Switch request context for link generation.
89
                $context = $this->getContextBySimplifiedRequest($siteAccess->matcher->getRequest());
90
                $this->setContext($context);
91
            } elseif ($this->logger) {
92
                $siteAccess = $this->siteAccess;
93
                $this->logger->notice("Could not generate a link using provided 'siteaccess' parameter: {$parameters['siteaccess']}. Generating using current context.");
94
            }
95
96
            unset($parameters['siteaccess']);
97
        }
98
99
        try {
100
            $url = parent::generate($name, $parameters, $referenceType);
101
        } catch (RouteNotFoundException $e) {
102
            // Switch back to original context, for next links generation.
103
            $this->setContext($originalContext);
104
            throw $e;
105
        }
106
107
        // Now putting back SiteAccess URI if needed.
108
        if ($isSiteAccessAware && $siteAccess && $siteAccess->matcher instanceof URILexer) {
109
            if ($referenceType === self::ABSOLUTE_URL || $referenceType === self::NETWORK_PATH) {
110
                $scheme = $context->getScheme();
111
                $port = '';
112
                if ($scheme === 'http' && $this->context->getHttpPort() != 80) {
113
                    $port = ':' . $this->context->getHttpPort();
114
                } elseif ($scheme === 'https' && $this->context->getHttpsPort() != 443) {
115
                    $port = ':' . $this->context->getHttpsPort();
116
                }
117
118
                $base = $context->getHost() . $port . $context->getBaseUrl();
119
            } else {
120
                $base = $context->getBaseUrl();
121
            }
122
123
            $linkUri = $base ? substr($url, strpos($url, $base) + strlen($base)) : $url;
124
            $url = str_replace($linkUri, $siteAccess->matcher->analyseLink($linkUri), $url);
125
        }
126
127
        // Switch back to original context, for next links generation.
128
        $this->setContext($originalContext);
129
130
        return $url;
131
    }
132
133
    /**
134
     * Checks if $routeName is a siteAccess aware route, and thus needs to have siteAccess URI prepended.
135
     * Will be used for link generation, only in the case of URI SiteAccess matching.
136
     *
137
     * @param $routeName
138
     *
139
     * @return bool
140
     */
141
    protected function isSiteAccessAwareRoute($routeName)
142
    {
143
        foreach ($this->nonSiteAccessAwareRoutes as $ignoredPrefix) {
144
            if (strpos($routeName, $ignoredPrefix) === 0) {
145
                return false;
146
            }
147
        }
148
149
        return true;
150
    }
151
152
    /**
153
     * Merges context from $simplifiedRequest into a clone of the current context.
154
     *
155
     * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $simplifiedRequest
156
     *
157
     * @return \Symfony\Component\Routing\RequestContext
158
     */
159 View Code Duplication
    public function getContextBySimplifiedRequest(SimplifiedRequest $simplifiedRequest)
160
    {
161
        $context = clone $this->context;
162
        if ($simplifiedRequest->scheme) {
163
            $context->setScheme($simplifiedRequest->scheme);
164
        }
165
166
        if ($simplifiedRequest->port) {
167
            $context->setHttpPort($simplifiedRequest->port);
168
        }
169
170
        if ($simplifiedRequest->host) {
171
            $context->setHost($simplifiedRequest->host);
172
        }
173
174
        if ($simplifiedRequest->pathinfo) {
175
            $context->setPathInfo($simplifiedRequest->pathinfo);
176
        }
177
178
        return $context;
179
    }
180
}
181