Completed
Push — master ( 6db9a9...7e342e )
by
unknown
18:05
created

AssetCollector::getStyleSheets()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
namespace TYPO3\CMS\Core\Page;
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
use TYPO3\CMS\Core\SingletonInterface;
19
use TYPO3\CMS\Core\Utility\ArrayUtility;
20
21
/**
22
 * The Asset Collector is responsible for keeping track of
23
 * - everything within <script> tags: javascript files and inline javascript code
24
 * - inline CSS and CSS files
25
 *
26
 * The goal of the asset collector is to:
27
 * - utilize a single "runtime-based" store for adding assets of certain kinds that are added to the output
28
 * - allow to deal with assets from non-cacheable plugins and cacheable content in the Frontend
29
 * - reduce the "power" and flexibility (I'd say it's a burden) of the "god class" PageRenderer.
30
 * - reduce the burden of storing everything in PageRenderer
31
 *
32
 * As a side-effect this allows to:
33
 * - Add a single CSS snippet or CSS file per content block, but assure that the CSS is only added once to the output.
34
 *
35
 * Note on the implementation:
36
 * - We use a Singleton to make use of the AssetCollector throughout Frontend process (similar to PageRenderer).
37
 * - Although this is not optimal, I don't see any other way to do so in the current code.
38
 *
39
 * https://developer.wordpress.org/reference/functions/wp_enqueue_style/
40
 */
41
class AssetCollector implements SingletonInterface
42
{
43
    /**
44
     * @var array
45
     */
46
    protected $javaScripts = [];
47
48
    /**
49
     * @var array
50
     */
51
    protected $inlineJavaScripts = [];
52
53
    /**
54
     * @var array
55
     */
56
    protected $styleSheets = [];
57
58
    /**
59
     * @var array
60
     */
61
    protected $inlineStyleSheets = [];
62
63
    /**
64
     * @var array
65
     */
66
    protected $media = [];
67
68
    public function addJavaScript(string $identifier, string $source, array $attributes, array $options = []): self
69
    {
70
        $existingAttributes = $this->javaScripts[$identifier]['attributes'] ?? [];
71
        ArrayUtility::mergeRecursiveWithOverrule($existingAttributes, $attributes);
72
        $existingOptions = $this->javaScripts[$identifier]['options'] ?? [];
73
        ArrayUtility::mergeRecursiveWithOverrule($existingOptions, $options);
74
        $this->javaScripts[$identifier] = [
75
            'source' => $source,
76
            'attributes' => $existingAttributes,
77
            'options' => $existingOptions
78
        ];
79
        return $this;
80
    }
81
82
    public function addInlineJavaScript(string $identifier, string $source, array $attributes, array $options = []): self
83
    {
84
        $existingAttributes = $this->inlineJavaScripts[$identifier]['attributes'] ?? [];
85
        ArrayUtility::mergeRecursiveWithOverrule($existingAttributes, $attributes);
86
        $existingOptions = $this->inlineJavaScripts[$identifier]['options'] ?? [];
87
        ArrayUtility::mergeRecursiveWithOverrule($existingOptions, $options);
88
        $this->inlineJavaScripts[$identifier] = [
89
            'source' => $source,
90
            'attributes' => $existingAttributes,
91
            'options' => $existingOptions
92
        ];
93
        return $this;
94
    }
95
96
    public function addStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self
97
    {
98
        $existingAttributes = $this->styleSheets[$identifier]['attributes'] ?? [];
99
        ArrayUtility::mergeRecursiveWithOverrule($existingAttributes, $attributes);
100
        $existingOptions = $this->styleSheets[$identifier]['options'] ?? [];
101
        ArrayUtility::mergeRecursiveWithOverrule($existingOptions, $options);
102
        $this->styleSheets[$identifier] = [
103
            'source' => $source,
104
            'attributes' => $existingAttributes,
105
            'options' => $existingOptions
106
        ];
107
        return $this;
108
    }
109
110
    public function addInlineStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self
111
    {
112
        $existingAttributes = $this->inlineStyleSheets[$identifier]['attributes'] ?? [];
113
        ArrayUtility::mergeRecursiveWithOverrule($existingAttributes, $attributes);
114
        $existingOptions = $this->inlineStyleSheets[$identifier]['options'] ?? [];
115
        ArrayUtility::mergeRecursiveWithOverrule($existingOptions, $options);
116
        $this->inlineStyleSheets[$identifier] = [
117
            'source' => $source,
118
            'attributes' => $existingAttributes,
119
            'options' => $existingOptions
120
        ];
121
        return $this;
122
    }
123
124
    public function addMedia(string $fileName, array $additionalInformation): self
125
    {
126
        $existingAdditionalInformation = $this->media[$fileName] ?? [];
127
        ArrayUtility::mergeRecursiveWithOverrule($existingAdditionalInformation, $additionalInformation);
128
        $this->media[$fileName] = $existingAdditionalInformation;
129
        return $this;
130
    }
131
132
    public function removeJavaScript(string $identifier): self
133
    {
134
        unset($this->javaScripts[$identifier]);
135
        return $this;
136
    }
137
138
    public function removeInlineJavaScript(string $identifier): self
139
    {
140
        unset($this->inlineJavaScripts[$identifier]);
141
        return $this;
142
    }
143
144
    public function removeStyleSheet(string $identifier): self
145
    {
146
        unset($this->styleSheets[$identifier]);
147
        return $this;
148
    }
149
150
    public function removeInlineStyleSheet(string $identifier): self
151
    {
152
        unset($this->inlineStyleSheets[$identifier]);
153
        return $this;
154
    }
155
156
    public function removeMedia(string $identifier): self
157
    {
158
        unset($this->media[$identifier]);
159
        return $this;
160
    }
161
162
    public function getMedia(): array
163
    {
164
        return $this->media;
165
    }
166
167
    public function getJavaScripts(): array
168
    {
169
        return $this->javaScripts;
170
    }
171
172
    public function getInlineJavaScripts(): array
173
    {
174
        return $this->inlineJavaScripts;
175
    }
176
177
    public function getStyleSheets(): array
178
    {
179
        return $this->styleSheets;
180
    }
181
182
    public function getInlineStyleSheets(): array
183
    {
184
        return $this->inlineStyleSheets;
185
    }
186
}
187