Completed
Push — master ( 51af85...b489fc )
by Pavel
06:35
created

SeoRequestListener   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 9
dl 0
loc 88
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B onMasterRequest() 0 34 6
A normalizeSeoOptions() 0 17 4
1
<?php
2
3
namespace Bankiru\Seo\Listener;
4
5
use Bankiru\Seo\Exception\MatchingException;
6
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
7
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
8
use Symfony\Component\Routing\Route;
9
use Symfony\Component\Routing\RouterInterface;
10
11
final class SeoRequestListener
12
{
13
    /** @var RouterInterface */
14
    private $router;
15
    /**
16
     * @var MasterSeoRequest
17
     */
18
    private $seoRequest;
19
20
    /**
21
     * SeoRequestListener constructor.
22
     *
23
     * @param RouterInterface  $router
24
     * @param MasterSeoRequest $seoRequest
25
     */
26
    public function __construct(RouterInterface $router, MasterSeoRequest $seoRequest)
27
    {
28
        $this->router     = $router;
29
        $this->seoRequest = $seoRequest;
30
    }
31
32
    /**
33
     * @param GetResponseEvent $event
34
     *
35
     * @throws \UnexpectedValueException
36
     * @throws NotFoundHttpException
37
     * @throws \LogicException
38
     */
39
    public function onMasterRequest(GetResponseEvent $event)
40
    {
41
        if (!$event->isMasterRequest()) {
42
            return;
43
        }
44
45
        $request = $event->getRequest();
46
47
        $name  = $request->attributes->get('route');
48
        $route = $this->router->getRouteCollection()->get($name);
49
        if (!$route) {
50
            return;
51
        }
52
53
        $seoOptions = $this->normalizeSeoOptions($route, $name);
54
55
        if (true !== $seoOptions['enabled']) {
56
            return;
57
        }
58
59
        $this->seoRequest->setDestination(RequestDestinationFactory::createFromRequest($request));
60
61
        if (false === $seoOptions['match']) {
62
            return;
63
        }
64
65
        try {
66
            $page = $this->seoRequest->getPage();
67
        } catch (MatchingException $exception) {
68
            throw new NotFoundHttpException(null, $exception);
69
        }
70
71
        $request->attributes->set('_seo_page', $page);
72
    }
73
74
    /**
75
     * @param Route  $route
76
     * @param string $name
77
     *
78
     * @return array
79
     * @throws \UnexpectedValueException
80
     */
81
    private function normalizeSeoOptions(Route $route, $name)
82
    {
83
        $seoOptions = $route->getOption('seo');
84
        if (null === $seoOptions) {
85
            return ['enabled' => false];
86
        }
87
        if (is_bool($seoOptions)) {
88
            return ['enabled' => $seoOptions, 'match' => true];
89
        }
90
        if (!is_array($seoOptions)) {
91
            throw new \UnexpectedValueException(
92
                sprintf('Seo options should be either boolean or array for route "%s"', $name)
93
            );
94
        }
95
96
        return array_replace_recursive(['enabled' => true, 'match' => true], $seoOptions);
97
    }
98
}
99