Completed
Push — 2.0 ( 998466...51c520 )
by Paweł
26s queued 14s
created

RouteEnhancer   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 6
dl 0
loc 160
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
B enhance() 0 27 8
B setArticleMeta() 0 24 8
A setTemplateName() 0 11 5
A setRouteMeta() 0 11 2
A getContentFromDefaults() 0 8 2
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Core Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\CoreBundle\Enhancer;
16
17
use SWP\Component\TemplatesSystem\Gimme\Context\Context;
18
use SWP\Component\TemplatesSystem\Gimme\Meta\Meta;
19
use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
20
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
21
use Symfony\Component\HttpFoundation\Request;
22
use SWP\Component\TemplatesSystem\Gimme\Loader\LoaderInterface;
23
use SWP\Bundle\CoreBundle\Resolver\TemplateNameResolverInterface;
24
use SWP\Bundle\ContentBundle\Model\ArticleInterface;
25
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
26
use SWP\Bundle\ContentBundle\Model\RouteInterface;
27
use SWP\Bundle\CoreBundle\Controller\ContentController;
28
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
29
30
class RouteEnhancer implements RouteEnhancerInterface
31
{
32
    const ARTICLE_META = '_article_meta';
33
34
    const ROUTE_META = '_route_meta';
35
36
    /**
37
     * @var TemplateNameResolverInterface
38
     */
39
    protected $templateNameResolver;
40
41
    /**
42
     * @var LoaderInterface
43
     */
44
    protected $metaLoader;
45
46
    /**
47
     * @var Context
48
     */
49
    protected $context;
50
51
    /**
52
     * @var array
53
     */
54
    private $enhancedRoutesDefaults = [];
55
56
    /**
57
     * @param TemplateNameResolverInterface $templateNameResolver
58
     * @param LoaderInterface               $metaLoader
59
     * @param Context                       $context
60
     */
61
    public function __construct(TemplateNameResolverInterface $templateNameResolver, LoaderInterface $metaLoader, Context $context)
62
    {
63
        $this->templateNameResolver = $templateNameResolver;
64
        $this->metaLoader = $metaLoader;
65
        $this->context = $context;
66
    }
67
68
    /**
69
     * Adjust route defaults and request attributes to our needs.
70
     *
71
     * @param array   $defaults
72
     * @param Request $request
73
     *
74
     * @return array
75
     */
76
    public function enhance(array $defaults, Request $request)
77
    {
78
        $defaultsKey = md5(json_encode($defaults));
79
        if (!isset($this->enhancedRoutesDefaults[$defaultsKey])) {
80
            $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
81
82
            if (!isset($defaults['_controller']) || (isset($defaults['_controller']) && sprintf('%s::urlRedirectAction', RedirectController::class) !== $defaults['_controller'])) {
83
                $defaults['_controller'] = ContentController::class.'::renderPageAction';
84
            }
85
86
            $defaults = $this->setArticleMeta($this->getContentFromDefaults($defaults), $defaults);
87
            $defaults = $this->setTemplateName($this->getContentFromDefaults($defaults), $defaults);
88
            $defaults = $this->setRouteMeta($defaults);
89
90
            if (null !== ($article = $this->getContentFromDefaults($defaults)) && !isset($defaults['slug']) && RouteInterface::TYPE_CONTENT === $route->getType()) {
91
                $defaults['slug'] = $article->getSlug();
92
            }
93
            $this->enhancedRoutesDefaults[$defaultsKey] = $defaults;
94
        } else {
95
            $defaults = $this->enhancedRoutesDefaults[$defaultsKey];
96
        }
97
98
        $request->attributes->set('routeMeta', $defaults[self::ROUTE_META]);
99
        $request->attributes->set('articleMeta', $defaults[self::ARTICLE_META]);
100
101
        return $defaults;
102
    }
103
104
    /**
105
     * Get article based on available parameters, set route type.
106
     *
107
     * @param mixed $content
108
     * @param array $defaults
109
     *
110
     * @throws NotFoundHttpException
111
     *
112
     * @return array
113
     */
114
    public function setArticleMeta($content, array $defaults)
115
    {
116
        $articleMeta = false;
117
        if (isset($defaults['slug'])) {
118
            $articleMeta = $this->metaLoader->load('article', ['slug' => $defaults['slug']], LoaderInterface::SINGLE);
119
            $defaults['type'] = RouteInterface::TYPE_COLLECTION;
120
            if (false === $articleMeta || ($articleMeta->getValues()->getRoute()->getId() !== $defaults[RouteObjectInterface::ROUTE_OBJECT]->getId())) {
121
                throw new NotFoundHttpException(sprintf('Article for slug: %s was not found.', $defaults['slug']));
122
            }
123
        } elseif ($content instanceof ArticleInterface) {
124
            $articleMeta = $this->metaLoader->load('article', ['article' => $content], LoaderInterface::SINGLE);
125
            $defaults['type'] = RouteInterface::TYPE_CONTENT;
126
            if (false === $articleMeta) {
127
                throw new NotFoundHttpException(sprintf('Content with id: %s was not found.', $content->getId()));
128
            }
129
        }
130
        if ($articleMeta && $articleMeta->getValues() instanceof ArticleInterface) {
131
            $defaults[RouteObjectInterface::CONTENT_OBJECT] = $articleMeta->getValues();
132
        }
133
134
        $defaults[self::ARTICLE_META] = $articleMeta;
135
136
        return $defaults;
137
    }
138
139
    /**
140
     * Resolve template name based on available data.
141
     *
142
     * @param mixed $content
143
     * @param array $defaults
144
     *
145
     * @return array
146
     */
147
    public function setTemplateName($content, array $defaults)
148
    {
149
        $route = isset($defaults[RouteObjectInterface::ROUTE_OBJECT]) ? $defaults[RouteObjectInterface::ROUTE_OBJECT] : null;
150
        if ($content && isset($defaults['slug'])) {
151
            $defaults[RouteObjectInterface::TEMPLATE_NAME] = $this->templateNameResolver->resolve($content);
152
        } elseif (null !== $route) {
153
            $defaults[RouteObjectInterface::TEMPLATE_NAME] = $this->templateNameResolver->resolve($route);
154
        }
155
156
        return $defaults;
157
    }
158
159
    /**
160
     * @param array $defaults
161
     *
162
     * @return array
163
     */
164
    public function setRouteMeta(array $defaults)
165
    {
166
        $routeMeta = $this->metaLoader->load('route', ['route_object' => $defaults[RouteObjectInterface::ROUTE_OBJECT]]);
167
        $defaults[self::ROUTE_META] = $routeMeta;
168
169
        if ($routeMeta instanceof Meta) {
170
            $this->context->setCurrentPage($routeMeta);
171
        }
172
173
        return $defaults;
174
    }
175
176
    /**
177
     * @param array $defaults
178
     *
179
     * @return ArticleInterface|bool
180
     */
181
    private function getContentFromDefaults($defaults)
182
    {
183
        if (isset($defaults[RouteObjectInterface::CONTENT_OBJECT])) {
184
            return $defaults[RouteObjectInterface::CONTENT_OBJECT];
185
        }
186
187
        return;
188
    }
189
}
190