Completed
Push — master ( 6d6774...64f3ed )
by Jeroen
11:23 queued 05:13
created

Router/DomainBasedLocaleRouter.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\MultiDomainBundle\Router;
4
5
use Kunstmaan\NodeBundle\Controller\SlugController;
6
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
7
use Kunstmaan\NodeBundle\Router\SlugRouter;
8
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
9
use Symfony\Component\Routing\Generator\UrlGenerator;
10
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
11
use Symfony\Component\Routing\Matcher\UrlMatcher;
12
use Symfony\Component\Routing\Route;
13
use Symfony\Component\Routing\RouteCollection;
14
15
/**
16
 * Class DomainBasedLocaleRouter
17
 */
18
class DomainBasedLocaleRouter extends SlugRouter
19
{
20
    /** @var RouteCollection */
21
    protected $routeCollectionMultiLanguage;
22
23
    /**
24
     * @var array|null
25
     */
26
    private $otherSite;
27
28
    /**
29
     * @var array
30
     */
31
    private $cachedNodeTranslations = [];
32
33
    /**
34
     * Generate an url for a supplied route
35
     *
36
     * @param string   $name          The path
37
     * @param array    $parameters    The route parameters
38
     * @param int|bool $referenceType The type of reference to be generated (one of the UrlGeneratorInterface constants)
39
     *
40
     * @return null|string
41
     */
42 3
    public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
43
    {
44 3
        if ('_slug' === $name && $this->isMultiLanguage() && $this->isMultiDomainHost()) {
45 3
            $locale = isset($parameters['_locale']) ? $parameters['_locale'] : $this->getRequestLocale();
46
47 3
            $reverseLocaleMap = $this->getReverseLocaleMap();
48 3
            if (isset($reverseLocaleMap[$locale])) {
49 3
                $parameters['_locale'] = $reverseLocaleMap[$locale];
50
            }
51
        }
52
53 3
        if (isset($parameters['otherSite'])) {
54 1
            $this->otherSite = $this->domainConfiguration->getFullHostById($parameters['otherSite']);
55
        } else {
56 3
            $this->otherSite = null;
57
        }
58
59 3
        $this->urlGenerator = new UrlGenerator(
60 3
            $this->getRouteCollection(),
61 3
            $this->getContext()
62
        );
63
64 3
        if (isset($parameters['otherSite'])) {
65 1
            unset($parameters['otherSite']);
66
        }
67
68 3
        return $this->urlGenerator->generate($name, $parameters, $referenceType);
0 ignored issues
show
It seems like $referenceType defined by parameter $referenceType on line 42 can also be of type boolean; however, Symfony\Component\Routin...rlGenerator::generate() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
69
    }
70
71
    /**
72
     * @param string $pathinfo
73
     *
74
     * @return array
75
     */
76 2
    public function match($pathinfo)
77
    {
78 2
        $urlMatcher = new UrlMatcher(
79 2
            $this->getRouteCollection(),
80 2
            $this->getContext()
81
        );
82
83 2
        $result = $urlMatcher->match($pathinfo);
84 2
        if (!empty($result)) {
85
            // Remap locale for front-end requests
86 2
            if ($this->isMultiDomainHost() &&
87 2
                $this->isMultiLanguage() &&
88 2
                !$result['preview']
89
            ) {
90 2
                $localeMap = $this->getLocaleMap();
91 2
                $locale = $result['_locale'];
92 2
                $result['_locale'] = $localeMap[$locale];
93
            }
94
95 2
            $nodeTranslation = $this->getNodeTranslation($result);
96 2
            if (\is_null($nodeTranslation)) {
97 1
                throw new ResourceNotFoundException('No page found for slug ' . $pathinfo);
98
            }
99 1
            $result['_nodeTranslation'] = $nodeTranslation;
100
        }
101
102 1
        return $result;
103
    }
104
105
    /**
106
     * @return string
107
     */
108 2
    protected function getRequestLocale()
109
    {
110 2
        $request = $this->getMasterRequest();
111 2
        $locale = $this->getDefaultLocale();
112 2
        if (!\is_null($request)) {
113 2
            $locale = $request->getLocale();
114
        }
115
116 2
        return $locale;
117
    }
118
119
    /**
120
     * @param array $matchResult
121
     *
122
     * @return \Kunstmaan\NodeBundle\Entity\NodeTranslation
123
     */
124 2
    protected function getNodeTranslation($matchResult)
125
    {
126 2
        $key = $matchResult['_controller'].$matchResult['url'].$matchResult['_locale'].$matchResult['_route'];
127 2
        if (!isset($this->cachedNodeTranslations[$key])) {
128 2
            $rootNode = $this->domainConfiguration->getRootNode();
129
130
            // Lookup node translation
131 2
            $nodeTranslationRepo = $this->getNodeTranslationRepository();
132
133
            /* @var NodeTranslation $nodeTranslation */
134 2
            $nodeTranslation = $nodeTranslationRepo->getNodeTranslationForUrl(
135 2
                $matchResult['url'],
136 2
                $matchResult['_locale'],
137 2
                false,
138 2
                null,
139
                $rootNode
140
            );
141 2
            $this->cachedNodeTranslations[$key] = $nodeTranslation;
142
        }
143
144 2
        return $this->cachedNodeTranslations[$key];
145
    }
146
147
    /**
148
     * @return bool
149
     */
150 5
    private function isMultiDomainHost()
151
    {
152 5
        return $this->domainConfiguration->isMultiDomainHost();
153
    }
154
155 6
    private function getHostLocales()
156
    {
157 6
        $host = null !== $this->otherSite ? $this->otherSite['host'] : null;
158
159 6
        return $this->domainConfiguration->getFrontendLocales($host);
160
    }
161
162
    /**
163
     * @return array
164
     */
165 2
    private function getLocaleMap()
166
    {
167 2
        return array_combine(
168 2
            $this->getFrontendLocales(),
169 2
            $this->getBackendLocales()
170
        );
171
    }
172
173
    /**
174
     * @return array
175
     */
176 3
    private function getReverseLocaleMap()
177
    {
178 3
        return array_combine(
179 3
            $this->getBackendLocales(),
180 3
            $this->getFrontendLocales()
181
        );
182
    }
183
184
    /**
185
     * Getter for routeCollection
186
     *
187
     * Override slug router
188
     *
189
     * @return \Symfony\Component\Routing\RouteCollection
190
     */
191 7
    public function getRouteCollection()
192
    {
193 7
        if (($this->otherSite && $this->isMultiLanguage($this->otherSite['host'])) || (!$this->otherSite && $this->isMultiLanguage())) {
194 6
            if (!$this->routeCollectionMultiLanguage) {
195 6
                $this->routeCollectionMultiLanguage = new RouteCollection();
196
197 6
                $this->addMultiLangPreviewRoute();
198 6
                $this->addMultiLangSlugRoute();
199
            }
200
201 6
            return $this->routeCollectionMultiLanguage;
202
        }
203
204 1
        if (!$this->routeCollection) {
205 1
            $this->routeCollection = new RouteCollection();
206
207 1
            $this->addPreviewRoute();
208 1
            $this->addSlugRoute();
209
        }
210
211 1
        return $this->routeCollection;
212
    }
213
214
    /**
215
     * Add the slug route to the route collection
216
     */
217 1
    protected function addSlugRoute()
218
    {
219 1
        $routeParameters = $this->getSlugRouteParameters();
220 1
        $this->addRoute('_slug', $routeParameters);
221 1
    }
222
223
    /**
224
     * Add the slug route to the route collection
225
     */
226 6
    protected function addMultiLangPreviewRoute()
227
    {
228 6
        $routeParameters = $this->getPreviewRouteParameters();
229 6
        $this->addMultiLangRoute('_slug_preview', $routeParameters);
230 6
    }
231
232
    /**
233
     * Add the slug route to the route collection multilanguage
234
     */
235 6
    protected function addMultiLangSlugRoute()
236
    {
237 6
        $routeParameters = $this->getSlugRouteParameters();
238 6
        $this->addMultiLangRoute('_slug', $routeParameters);
239 6
    }
240
241
    /**
242
     * @param string $name
243
     * @param array  $parameters
244
     */
245 6 View Code Duplication
    protected function addMultiLangRoute($name, array $parameters = array())
246
    {
247 6
        $this->routeCollectionMultiLanguage->add(
248 6
            $name,
249 6
            new Route(
250 6
                $parameters['path'],
251 6
                $parameters['defaults'],
252 6
                $parameters['requirements']
253
            )
254
        );
255 6
    }
256
257
    /**
258
     * Return slug route parameters
259
     *
260
     * @return array
261
     */
262 7
    protected function getSlugRouteParameters()
263
    {
264 7
        $slugPath = '/{url}';
265
        $slugDefaults = array(
266 7
            '_controller' => SlugController::class.'::slugAction',
267
            'preview' => false,
268 7
            'url' => '',
269 7
            '_locale' => $this->getDefaultLocale(),
270
        );
271
        $slugRequirements = array(
272 7
            'url' => $this->getSlugPattern(),
273
        );
274
275 7
        $locales = [];
276
277
        // If other site provided and multilingual, get the locales from the host config.
278 7
        if ($this->otherSite && $this->isMultiLanguage($this->otherSite['host'])) {
279 1
            $locales = $this->getHostLocales();
280 6
        } elseif ($this->isMultiLanguage() && !$this->otherSite) {
281 5
            $locales = $this->getFrontendLocales();
282
        }
283
284
        // Make locale availables for the slug routes.
285 7
        if (!empty($locales)) {
286 6
            $slugPath = '/{_locale}' . $slugPath;
287 6
            unset($slugDefaults['_locale']);
288 6
            $slugRequirements['_locale'] = $this->getEscapedLocales($this->getHostLocales());
289
        }
290
291
        return array(
292 7
            'path' => $slugPath,
293 7
            'defaults' => $slugDefaults,
294 7
            'requirements' => $slugRequirements,
295
        );
296
    }
297
}
298