Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
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 string|null
41
     */
42 3
    public function generate($name, $parameters = [], $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);
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
     */
244 6 View Code Duplication
    protected function addMultiLangRoute($name, array $parameters = [])
0 ignored issues
show
This method seems to be duplicated in 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...
245
    {
246 6
        $this->routeCollectionMultiLanguage->add(
247 6
            $name,
248 6
            new Route(
249 6
                $parameters['path'],
250 6
                $parameters['defaults'],
251 6
                $parameters['requirements']
252
            )
253
        );
254 6
    }
255
256
    /**
257
     * Return slug route parameters
258
     *
259
     * @return array
260
     */
261 7
    protected function getSlugRouteParameters()
262
    {
263 7
        $slugPath = '/{url}';
264
        $slugDefaults = [
265 7
            '_controller' => SlugController::class . '::slugAction',
266
            'preview' => false,
267 7
            'url' => '',
268 7
            '_locale' => $this->getDefaultLocale(),
269
        ];
270
        $slugRequirements = [
271 7
            'url' => $this->getSlugPattern(),
272
        ];
273
274 7
        $locales = [];
275
276
        // If other site provided and multilingual, get the locales from the host config.
277 7
        if ($this->otherSite && $this->isMultiLanguage($this->otherSite['host'])) {
278 1
            $locales = $this->getHostLocales();
279 6
        } elseif ($this->isMultiLanguage() && !$this->otherSite) {
280 5
            $locales = $this->getFrontendLocales();
281
        }
282
283
        // Make locale availables for the slug routes.
284 7
        if (!empty($locales)) {
285 6
            $slugPath = '/{_locale}' . $slugPath;
286 6
            unset($slugDefaults['_locale']);
287 6
            $slugRequirements['_locale'] = $this->getEscapedLocales($this->getHostLocales());
288
        }
289
290
        return [
291 7
            'path' => $slugPath,
292 7
            'defaults' => $slugDefaults,
293 7
            'requirements' => $slugRequirements,
294
        ];
295
    }
296
}
297