Completed
Push — l10n_master ( 6cb695...818918 )
by Kunstmaan
50:17 queued 35:37
created

src/Kunstmaan/NodeBundle/Router/SlugRouter.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\NodeBundle\Router;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Kunstmaan\AdminBundle\Helper\DomainConfigurationInterface;
7
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
8
use Kunstmaan\NodeBundle\Repository\NodeTranslationRepository;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\RequestStack;
12
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
13
use Symfony\Component\Routing\Generator\UrlGenerator;
14
use Symfony\Component\Routing\Matcher\UrlMatcher;
15
use Symfony\Component\Routing\RequestContext;
16
use Symfony\Component\Routing\Route;
17
use Symfony\Component\Routing\RouteCollection;
18
use Symfony\Component\Routing\RouterInterface;
19
20
/**
21
 * The SlugRouter takes care of routing the paths for slugs. It should have the
22
 * lowest priority as it's a catch-all router that routes (almost) all requests
23
 * to the SlugController
24
 */
25
class SlugRouter implements RouterInterface
26
{
27
    public static $SLUG = '_slug';
28
29
    public static $SLUG_PREVIEW = '_slug_preview';
30
31
    /** @var DomainConfigurationInterface */
32
    protected $domainConfiguration;
33
34
    /** @var RequestStack */
35
    private $requestStack;
36
37
    /** @var EntityManagerInterface */
38
    private $em;
39
40
    /** @var string */
41
    protected $adminKey;
42
43
    /** @var RequestContext */
44
    protected $context;
45
46
    /** @var RouteCollection */
47
    protected $routeCollection;
48
49
    /** @var UrlGenerator */
50
    protected $urlGenerator;
51
52
    /**
53
     * @var ContainerInterface
54
     *
55
     * @deprecated in KunstmaanNodeBundle 5.1 and will be removed in KunstmaanNodeBundle 6.0.
56
     */
57
    protected $container;
58
59
    /** @var string */
60
    protected $slugPattern;
61
62
    /**
63
     * The constructor for this service
64
     *
65
     * @param ContainerInterface $container
66
     */
67 12 View Code Duplication
    public function __construct(
68
        /* DomainConfigurationInterface */ $domainConfiguration,
69
        RequestStack $requestStack = null,
70
        EntityManagerInterface $em = null,
71
        $adminKey = null
72
    ) {
73 12
        $this->slugPattern = "[a-zA-Z0-9\-_\/]*";
74
75 12
        if ($domainConfiguration instanceof ContainerInterface) {
76 12
            @trigger_error('Container injection and the usage of the container is deprecated in KunstmaanNodeBundle 5.1 and will be removed in KunstmaanNodeBundle 6.0.', E_USER_DEPRECATED);
77
78 12
            $this->container = $domainConfiguration;
79 12
            $this->domainConfiguration = $this->container->get('kunstmaan_admin.domain_configuration');
80 12
            $this->adminKey = $this->container->getParameter('kunstmaan_admin.admin_prefix');
81 12
            $this->requestStack = $this->container->get('request_stack');
82 12
            $this->em = $this->container->get('doctrine.orm.entity_manager');
83
84 12
            return;
85
        }
86
87
        $this->domainConfiguration = $domainConfiguration;
88
        $this->adminKey = $adminKey;
89
        $this->requestStack = $requestStack;
90
        $this->em = $em;
91
    }
92
93
    /**
94
     * Match given urls via the context to the routes we defined.
95
     * This functionality re-uses the default Symfony way of routing and its
96
     * components
97
     *
98
     * @param string $pathinfo
99
     *
100
     * @throws ResourceNotFoundException
101
     *
102
     * @return array
103
     */
104 2
    public function match($pathinfo)
105
    {
106 2
        $urlMatcher = new UrlMatcher(
107 2
            $this->getRouteCollection(),
108 2
            $this->getContext()
109
        );
110 2
        $result = $urlMatcher->match($pathinfo);
111
112 2
        if (!empty($result)) {
113 2
            $nodeTranslation = $this->getNodeTranslation($result);
114 2
            if (\is_null($nodeTranslation)) {
115 1
                throw new ResourceNotFoundException(
116 1
                    'No page found for slug ' . $pathinfo
117
                );
118
            }
119 1
            $result['_nodeTranslation'] = $nodeTranslation;
120
        }
121
122 1
        return $result;
123
    }
124
125
    /**
126
     * Gets the request context.
127
     *
128
     * @return RequestContext The context
129
     *
130
     * @api
131
     */
132 10
    public function getContext()
133
    {
134 10
        if (!isset($this->context)) {
135
            /** @var Request $request */
136 9
            $request = $this->getMasterRequest();
137
138 9
            $this->context = new RequestContext();
139 9
            $this->context->fromRequest($request);
140
        }
141
142 10
        return $this->context;
143
    }
144
145
    /**
146
     * Sets the request context.
147
     *
148
     * @param RequestContext $context The context
149
     *
150
     * @api
151
     */
152 1
    public function setContext(RequestContext $context)
153
    {
154 1
        $this->context = $context;
155 1
    }
156
157
    /**
158
     * Generate an url for a supplied route.
159
     *
160
     * @param string   $name          The path
161
     * @param array    $parameters    The route parameters
162
     * @param int|bool $referenceType The type of reference to be generated (one of the UrlGeneratorInterface constants)
163
     *
164
     * @return null|string
165
     */
166 2
    public function generate($name, $parameters = array(), $referenceType = UrlGenerator::ABSOLUTE_PATH)
167
    {
168 2
        $this->urlGenerator = new UrlGenerator(
169 2
            $this->getRouteCollection(),
170 2
            $this->getContext()
171
        );
172
173 2
        return $this->urlGenerator->generate($name, $parameters, $referenceType);
0 ignored issues
show
It seems like $referenceType defined by parameter $referenceType on line 166 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...
174
    }
175
176
    /**
177
     * Getter for routeCollection
178
     *
179
     * @return \Symfony\Component\Routing\RouteCollection
180
     */
181 4
    public function getRouteCollection()
182
    {
183 4
        if (\is_null($this->routeCollection)) {
184 4
            $this->routeCollection = new RouteCollection();
185
186 4
            $this->addPreviewRoute();
187 4
            $this->addSlugRoute();
188
        }
189
190 4
        return $this->routeCollection;
191
    }
192
193
    /**
194
     * @return null|\Symfony\Component\HttpFoundation\Request
195
     */
196 9
    protected function getMasterRequest()
197
    {
198 9
        if (\is_null($this->requestStack)) {
199
            return null;
200
        }
201
202 9
        return $this->requestStack->getMasterRequest();
203
    }
204
205
    /**
206
     * Add the preview route to the route collection
207
     */
208 5
    protected function addPreviewRoute()
209
    {
210 5
        $routeParameters = $this->getPreviewRouteParameters();
211 5
        $this->addRoute(self::$SLUG_PREVIEW, $routeParameters);
212 5
    }
213
214
    /**
215
     * Add the slug route to the route collection
216
     */
217 4
    protected function addSlugRoute()
218
    {
219 4
        $routeParameters = $this->getSlugRouteParameters();
220 4
        $this->addRoute(self::$SLUG, $routeParameters);
221 4
    }
222
223
    /**
224
     * Return preview route parameters
225
     *
226
     * @return array
227
     */
228 11 View Code Duplication
    protected function getPreviewRouteParameters()
229
    {
230 11
        $previewPath = sprintf('/%s/preview/{url}', $this->adminKey);
231
        $previewDefaults = array(
232 11
            '_controller' => 'KunstmaanNodeBundle:Slug:slug',
233
            'preview' => true,
234 11
            'url' => '',
235 11
            '_locale' => $this->getDefaultLocale(),
236
        );
237
        $previewRequirements = array(
238 11
            'url' => $this->getSlugPattern(),
239
        );
240
241 11
        if ($this->isMultiLanguage()) {
242 8
            $previewPath = '/{_locale}' . $previewPath;
243 8
            unset($previewDefaults['_locale']);
244 8
            $previewRequirements['_locale'] = $this->getEscapedLocales($this->getBackendLocales());
245
        }
246
247
        return array(
248 11
            'path' => $previewPath,
249 11
            'defaults' => $previewDefaults,
250 11
            'requirements' => $previewRequirements,
251
        );
252
    }
253
254
    /**
255
     * Return slug route parameters
256
     *
257
     * @return array
258
     */
259 4 View Code Duplication
    protected function getSlugRouteParameters()
260
    {
261 4
        $slugPath = '/{url}';
262
        $slugDefaults = array(
263 4
            '_controller' => 'KunstmaanNodeBundle:Slug:slug',
264
            'preview' => false,
265 4
            'url' => '',
266 4
            '_locale' => $this->getDefaultLocale(),
267
        );
268
        $slugRequirements = array(
269 4
            'url' => $this->getSlugPattern(),
270
        );
271
272 4
        if ($this->isMultiLanguage()) {
273 2
            $slugPath = '/{_locale}' . $slugPath;
274 2
            unset($slugDefaults['_locale']);
275 2
            $slugRequirements['_locale'] = $this->getEscapedLocales($this->getFrontendLocales());
276
        }
277
278
        return array(
279 4
            'path' => $slugPath,
280 4
            'defaults' => $slugDefaults,
281 4
            'requirements' => $slugRequirements,
282
        );
283
    }
284
285
    /**
286
     * @return bool
287
     */
288 11
    protected function isMultiLanguage($host = null)
289
    {
290 11
        return $this->domainConfiguration->isMultiLanguage($host);
291
    }
292
293
    /**
294
     * @return array
295
     */
296 7
    protected function getFrontendLocales()
297
    {
298 7
        return $this->domainConfiguration->getFrontendLocales();
299
    }
300
301
    /**
302
     * @return array
303
     */
304 8
    protected function getBackendLocales()
305
    {
306 8
        return $this->domainConfiguration->getBackendLocales();
307
    }
308
309
    /**
310
     * @return string
311
     */
312 11
    protected function getDefaultLocale()
313
    {
314 11
        return $this->domainConfiguration->getDefaultLocale();
315
    }
316
317
    /**
318
     * @return string
319
     */
320
    protected function getHost()
321
    {
322
        return $this->domainConfiguration->getHost();
323
    }
324
325
    /**
326
     * @return string
327
     */
328 11
    protected function getSlugPattern()
329
    {
330 11
        return $this->slugPattern;
331
    }
332
333
    /**
334
     * @param string $name
335
     * @param array  $parameters
336
     */
337 5 View Code Duplication
    protected function addRoute($name, array $parameters = array())
338
    {
339 5
        $this->routeCollection->add(
340 5
            $name,
341 5
            new Route(
342 5
                $parameters['path'],
343 5
                $parameters['defaults'],
344 5
                $parameters['requirements']
345
            )
346
        );
347 5
    }
348
349
    /**
350
     * @param array $matchResult
351
     *
352
     * @return \Kunstmaan\NodeBundle\Entity\NodeTranslation
353
     */
354 2
    protected function getNodeTranslation($matchResult)
355
    {
356
        // The route matches, now check if it actually exists (needed for proper chain router chaining!)
357 2
        $nodeTranslationRepo = $this->getNodeTranslationRepository();
358
359
        /* @var NodeTranslation $nodeTranslation */
360 2
        $nodeTranslation = $nodeTranslationRepo->getNodeTranslationForUrl(
361 2
            $matchResult['url'],
362 2
            $matchResult['_locale']
363
        );
364
365 2
        return $nodeTranslation;
366
    }
367
368
    /**
369
     * @return \Kunstmaan\NodeBundle\Repository\NodeTranslationRepository
370
     */
371 4
    protected function getNodeTranslationRepository()
372
    {
373
        /* @var NodeTranslationRepository $nodeTranslationRepo */
374 4
        $nodeTranslationRepo = $this->em->getRepository(
375 4
            'KunstmaanNodeBundle:NodeTranslation'
376
        );
377
378 4
        return $nodeTranslationRepo;
379
    }
380
381
    /**
382
     * @param array $locales
383
     *
384
     * @return string
385
     */
386 8
    protected function getEscapedLocales($locales)
387
    {
388 8
        $escapedLocales = array();
389 8
        foreach ($locales as $locale) {
390 8
            $escapedLocales[] = str_replace('-', '\-', $locale);
391
        }
392
393 8
        return implode('|', $escapedLocales);
394
    }
395
}
396