SeoExtension::getFunctions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Norsys\SeoBundle\Twig\Extension;
5
6
use Norsys\SeoBundle\Exception\TagBuilderNullValueException;
7
use Norsys\SeoBundle\Services\TagBuilder\Tag;
8
use Norsys\SeoBundle\Services\TagBuilder\TagBuilderInterface;
9
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
10
11
/**
12
 * Helper class for meta/title/link rendering in Twig
13
 */
14
class SeoExtension extends \Twig_Extension
15
{
16
    /**
17
     * @var string
18
     */
19
    const NODE_NAME_META = 'metas';
20
21
    /**
22
     * @var string
23
     */
24
    const NODE_NAME_LINK = 'links';
25
26
    /**
27
     * @var array
28
     */
29
    private static $tags;
30
31
    /**
32
     * @var Translator
33
     */
34
    private $translator;
35
36
    /**
37
     * @var array
38
     */
39
    private $defaults;
40
41
    /**
42
     * @var array
43
     */
44
    private $configTitle;
45
46
    /**
47
     * @var array
48
     */
49
    private $data;
50
51
    /**
52
     * @var TagBuilderInterface
53
     */
54
    private $tagBuilder;
55
56
    /**
57
     *
58
     * @param array               $seoConfigMetas
59
     * @param array               $seoConfigTitle
60
     * @param array               $seoConfigLinks
61
     * @param TagBuilderInterface $tagBuilder
62
     */
63
    public function __construct(
64
        array $seoConfigMetas,
65
        array $seoConfigTitle,
66
        array $seoConfigLinks,
67
        TagBuilderInterface $tagBuilder
68
    ) {
69
        $this->defaults = $seoConfigMetas['defaults'];
70
71
        $this->configTitle = $seoConfigTitle;
72
73
        $this->initTags();
74
75
        unset($seoConfigMetas['defaults']);
76
77
        $this->data = [
78
            self::NODE_NAME_LINK => $seoConfigLinks,
79
            self::NODE_NAME_META => $seoConfigMetas,
80
        ];
81
82
        $this->tagBuilder = $tagBuilder;
83
    }
84
85
    /**
86
     * Init tags.
87
     */
88
    private function initTags()
89
    {
90
        if (is_array(static::$tags) === false) {
0 ignored issues
show
introduced by
The condition is_array(static::tags) === false is always false.
Loading history...
Bug introduced by
Since $tags is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $tags to at least protected.
Loading history...
91
            static::$tags = [
92
                self::NODE_NAME_META => new Tag('meta', true),
93
                self::NODE_NAME_LINK => new Tag('link', true)
94
            ];
95
        }
96
    }
97
98
    /**
99
     * @param Translator $translator
100
     */
101
    public function setTranslator(Translator $translator)
102
    {
103
        $this->translator = $translator;
104
    }
105
106
    /**
107
     * @return array
108
     */
109
    public function getFunctions() : array
110
    {
111
        return [
112
            // We pass "is_safe" option to have raw content output
113
            // @see https://twig.sensiolabs.org/doc/2.x/advanced.html#automatic-escaping
114
            new \Twig_SimpleFunction('seo_render_metas', [ $this, 'renderMetaTags' ], [ 'is_safe' => [ 'html'] ]),
115
            new \Twig_SimpleFunction('seo_render_links', [ $this, 'renderLinkTags' ], [ 'is_safe' => [ 'html'] ]),
116
            new \Twig_SimpleFunction('seo_render_title', [ $this, 'renderTitleTag' ], [ 'is_safe' => [ 'html'] ]),
117
        ];
118
    }
119
120
    /**
121
     * @param string $routeName
122
     * @return string
123
     */
124
    public function renderMetaTags(string $routeName = null) : string
125
    {
126
        return $this->renderTags(self::NODE_NAME_META, $routeName);
127
    }
128
129
    /**
130
     * @param string $routeName
131
     * @return string
132
     */
133
    public function renderLinkTags(string $routeName = null) : string
134
    {
135
        return $this->renderTags(self::NODE_NAME_LINK, $routeName);
136
    }
137
138
    /**
139
     * @param string $routeName
140
     * @return string
141
     */
142
    public function renderTitleTag(string $routeName = null) : string
143
    {
144
        $rawTitle = $this->configTitle['pages'][$routeName] ?? $this->configTitle['default'];
145
146
        return $this->tagBuilder->build(new Tag('title', false), [], $rawTitle);
147
    }
148
149
    /**
150
     * @param string $type
151
     * @param string $routeName
152
     * @return array
153
     */
154
    private function getData(string $type, string $routeName = null) : array
155
    {
156
        $defaults = ($type === self::NODE_NAME_META) ? $this->defaults : [];
157
        $routeData = $this->data[$type]['pages'][$routeName] ?? $defaults;
158
159
        return $routeData;
160
    }
161
162
    /**
163
     * @param string $type
164
     * @param string $routeName
165
     * @return string
166
     */
167
    private function renderTags(string $type, string $routeName = null) : string
168
    {
169
        $tags = [];
170
        $data = $this->getData($type, $routeName);
171
        foreach ($data as $attributes) {
172
            try {
173
                $tags[] = $this->tagBuilder->build(static::$tags[$type], $attributes);
0 ignored issues
show
Bug introduced by
Since $tags is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $tags to at least protected.
Loading history...
174
            } catch (TagBuilderNullValueException $e) {
175
                // If value if null we don't create a new tag
176
            }
177
        }
178
179
        return implode("\n", $tags);
180
    }
181
}
182