Completed
Push — master ( bb050e...36e41a )
by Paweł
11:10
created

RouteEnhancer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
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\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
20
use Symfony\Component\HttpFoundation\Request;
21
use SWP\Component\TemplatesSystem\Gimme\Loader\LoaderInterface;
22
use SWP\Bundle\CoreBundle\Resolver\TemplateNameResolverInterface;
23
use SWP\Bundle\ContentBundle\Model\ArticleInterface;
24
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
25
use SWP\Bundle\ContentBundle\Model\RouteInterface;
26
use SWP\Bundle\CoreBundle\Controller\ContentController;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
29
class RouteEnhancer implements RouteEnhancerInterface
30
{
31
    const ARTICLE_META = '_article_meta';
32
33
    const ROUTE_META = '_route_meta';
34
35
    /**
36
     * @var TemplateNameResolverInterface
37
     */
38
    protected $templateNameResolver;
39
40
    /**
41
     * @var LoaderInterface
42
     */
43
    protected $metaLoader;
44
45
    /**
46
     * @var Context
47
     */
48
    protected $context;
49
50
    /**
51
     * @var array
52
     */
53
    private $enhancedRoutesDefaults = [];
54 109
55
    /**
56
     * @param TemplateNameResolverInterface $templateNameResolver
57
     * @param LoaderInterface               $metaLoader
58
     * @param Context                       $context
59 109
     */
60 109
    public function __construct(TemplateNameResolverInterface $templateNameResolver, LoaderInterface $metaLoader, Context $context)
61 109
    {
62 109
        $this->templateNameResolver = $templateNameResolver;
63
        $this->metaLoader = $metaLoader;
64
        $this->context = $context;
65
    }
66
67
    /**
68
     * Adjust route defaults and request attributes to our needs.
69
     *
70
     * @param array   $defaults
71
     * @param Request $request
72 14
     *
73
     * @return array
74 14
     */
75 14
    public function enhance(array $defaults, Request $request)
76 12
    {
77 10
        $defaultsKey = md5(json_encode($defaults));
78
        if (!isset($this->enhancedRoutesDefaults[$defaultsKey])) {
79 10
            $defaults['_controller'] = ContentController::class.'::renderPageAction';
80
            $defaults = $this->setArticleMeta($this->getContentFromDefaults($defaults), $defaults);
81
            $defaults = $this->setTemplateName($this->getContentFromDefaults($defaults), $defaults);
82
            $defaults = $this->setRouteMeta($defaults);
83
            $this->enhancedRoutesDefaults[$defaultsKey] = $defaults;
84
        } else {
85
            $defaults = $this->enhancedRoutesDefaults[$defaultsKey];
86
        }
87
88
        $request->attributes->set('routeMeta', $defaults[self::ROUTE_META]);
89
        $request->attributes->set('articleMeta', $defaults[self::ARTICLE_META]);
90
91
        return $defaults;
92
    }
93 14
94
    /**
95 14
     * Get article based on available parameters, set route type.
96 14
     *
97 7
     * @param mixed $content
98 7
     * @param array $defaults
99 7
     *
100 7
     * @throws NotFoundHttpException
101
     *
102
     * @return array
103
     */
104
    public function setArticleMeta($content, array $defaults)
105
    {
106
        $articleMeta = null;
107
        if (isset($defaults['slug'])) {
108
            $articleMeta = $this->metaLoader->load('article', ['slug' => $defaults['slug']], LoaderInterface::SINGLE);
109 12
            $defaults['type'] = RouteInterface::TYPE_COLLECTION;
110 5
            if (null === $articleMeta || ($articleMeta->getValues()->getRoute()->getId() !== $defaults[RouteObjectInterface::ROUTE_OBJECT]->getId())) {
111
                throw new NotFoundHttpException('Article was not found.');
112
            }
113 12
        } elseif ($content instanceof ArticleInterface) {
114 12
            $articleMeta = $this->metaLoader->load('article', ['article' => $content], LoaderInterface::SINGLE);
115
            $defaults['type'] = RouteInterface::TYPE_CONTENT;
116 12
            if (null === $articleMeta) {
117
                throw new NotFoundHttpException('Page was not found.');
118
            }
119
        }
120
        if ($articleMeta && $articleMeta->getValues() instanceof ArticleInterface) {
121
            $defaults[RouteObjectInterface::CONTENT_OBJECT] = $articleMeta->getValues();
122
        }
123
124
        $defaults[self::ARTICLE_META] = $articleMeta;
125
126
        return $defaults;
127 12
    }
128
129 12
    /**
130 12
     * Resolve template name based on available data.
131 5
     *
132 7
     * @param mixed $content
133 7
     * @param array $defaults
134
     *
135
     * @return array
136 10
     */
137
    public function setTemplateName($content, array $defaults)
138
    {
139
        $route = isset($defaults[RouteObjectInterface::ROUTE_OBJECT]) ? $defaults[RouteObjectInterface::ROUTE_OBJECT] : null;
140
        if ($content) {
141
            $defaults[RouteObjectInterface::TEMPLATE_NAME] = $this->templateNameResolver->resolve($content);
142
        } elseif (null !== $route) {
143
            $defaults[RouteObjectInterface::TEMPLATE_NAME] = $this->templateNameResolver->resolve($route);
144
        }
145 10
146
        return $defaults;
147 10
    }
148 10
149 10
    /**
150
     * @param array $defaults
151 10
     *
152 10
     * @return array
153
     */
154
    public function setRouteMeta(array $defaults)
155 10
    {
156
        $routeMeta = $this->metaLoader->load('route', ['route_object' => $defaults[RouteObjectInterface::ROUTE_OBJECT]]);
157
        $defaults[self::ROUTE_META] = $routeMeta;
158
159
        if ($routeMeta instanceof Meta) {
160
            $this->context->setCurrentPage($routeMeta);
161
        }
162
163 14
        return $defaults;
164
    }
165 14
166 5
    /**
167
     * @param array $defaults
168
     *
169 14
     * @return ArticleInterface|bool
170
     */
171
    private function getContentFromDefaults($defaults)
172
    {
173
        if (isset($defaults[RouteObjectInterface::CONTENT_OBJECT])) {
174
            return $defaults[RouteObjectInterface::CONTENT_OBJECT];
175
        }
176
177
        return;
178
    }
179
}
180