1 | <?php |
||||
2 | /** |
||||
3 | * SEOmatic plugin for Craft CMS |
||||
4 | * |
||||
5 | * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful, |
||||
6 | * and flexible |
||||
7 | * |
||||
8 | * @link https://nystudio107.com |
||||
9 | * @copyright Copyright (c) 2017 nystudio107 |
||||
10 | */ |
||||
11 | |||||
12 | namespace nystudio107\seomatic\models; |
||||
13 | |||||
14 | use Craft; |
||||
15 | use nystudio107\codeeditor\validators\TwigTemplateValidator; |
||||
16 | use nystudio107\seomatic\base\NonceItem; |
||||
17 | use nystudio107\seomatic\helpers\PluginTemplate as PluginTemplateHelper; |
||||
18 | use yii\web\View; |
||||
19 | use function is_string; |
||||
20 | |||||
21 | /** |
||||
22 | * @author nystudio107 |
||||
23 | * @package Seomatic |
||||
24 | * @since 3.0.0 |
||||
25 | */ |
||||
26 | class MetaScript extends NonceItem |
||||
27 | { |
||||
28 | // Constants |
||||
29 | // ========================================================================= |
||||
30 | |||||
31 | public const ITEM_TYPE = 'MetaScript'; |
||||
32 | |||||
33 | // Static Methods |
||||
34 | // ========================================================================= |
||||
35 | /** |
||||
36 | * @var string |
||||
37 | */ |
||||
38 | public $name; |
||||
39 | |||||
40 | // Public Properties |
||||
41 | // ========================================================================= |
||||
42 | |||||
43 | /** |
||||
44 | * @var string |
||||
45 | */ |
||||
46 | public $description; |
||||
47 | |||||
48 | /** |
||||
49 | * @var string |
||||
50 | */ |
||||
51 | public $templatePath; |
||||
52 | |||||
53 | /** |
||||
54 | * @var string |
||||
55 | */ |
||||
56 | public $templateString; |
||||
57 | |||||
58 | /** |
||||
59 | * @var int |
||||
60 | */ |
||||
61 | public $position = View::POS_HEAD; |
||||
62 | |||||
63 | /** |
||||
64 | * @var string |
||||
65 | */ |
||||
66 | public $bodyTemplatePath; |
||||
67 | |||||
68 | /** |
||||
69 | * @var string |
||||
70 | */ |
||||
71 | public $bodyTemplateString; |
||||
72 | |||||
73 | /** |
||||
74 | * @var int |
||||
75 | */ |
||||
76 | public $bodyPosition = View::POS_BEGIN; |
||||
77 | |||||
78 | /** |
||||
79 | * @var array |
||||
80 | */ |
||||
81 | public $vars; |
||||
82 | |||||
83 | /** |
||||
84 | * @var array |
||||
85 | */ |
||||
86 | public $dataLayer = []; |
||||
87 | |||||
88 | /** |
||||
89 | * @var bool Whether this tag is deprecated or not |
||||
90 | */ |
||||
91 | public $deprecated = false; |
||||
92 | |||||
93 | /** |
||||
94 | * @var string The deprecation notice to display |
||||
95 | */ |
||||
96 | public $deprecationNotice = ''; |
||||
97 | |||||
98 | /** |
||||
99 | * @var bool Whether this tag is discontinued, and should not be displayed or rendered |
||||
100 | */ |
||||
101 | public $discontinued = false; |
||||
102 | |||||
103 | /** |
||||
104 | * @param array $config |
||||
105 | * |
||||
106 | * @return MetaScript |
||||
107 | */ |
||||
108 | public static function create(array $config = []): MetaScript |
||||
109 | { |
||||
110 | $model = new MetaScript($config); |
||||
111 | // Load $templateString from the source template if it's not set |
||||
112 | if (empty($model->templateString) && !empty($model->templatePath)) { |
||||
113 | $model->templateString = $model->loadTemplate($model->templatePath); |
||||
114 | } |
||||
115 | |||||
116 | // Load $templateString from the source template if it's not set |
||||
117 | if (empty($model->bodyTemplateString) && !empty($model->bodyTemplatePath)) { |
||||
118 | $model->bodyTemplateString = $model->loadTemplate($model->bodyTemplatePath); |
||||
119 | } |
||||
120 | |||||
121 | return $model; |
||||
122 | } |
||||
123 | |||||
124 | // Public Methods |
||||
125 | // ========================================================================= |
||||
126 | |||||
127 | /** |
||||
128 | * @inheritdoc |
||||
129 | */ |
||||
130 | public function init(): void |
||||
131 | { |
||||
132 | parent::init(); |
||||
133 | |||||
134 | $this->key = $this->key ?: lcfirst($this->name); |
||||
135 | } |
||||
136 | |||||
137 | /** |
||||
138 | * Load the existing template into a string |
||||
139 | * |
||||
140 | * @param string $templatePath |
||||
141 | * |
||||
142 | * @return string |
||||
143 | */ |
||||
144 | public function loadTemplate(string $templatePath): string |
||||
145 | { |
||||
146 | $result = ''; |
||||
147 | // Try it from our plugin directory first |
||||
148 | $path = Craft::getAlias('@nystudio107/seomatic/templates/') |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
149 | . $templatePath; |
||||
150 | if (file_exists($path)) { |
||||
151 | $result = @file_get_contents($path); |
||||
152 | } else { |
||||
153 | // Next try it from the Craft template directory |
||||
154 | $path = Craft::getAlias('@templates/') |
||||
0 ignored issues
–
show
Are you sure
Craft::getAlias('@templates/') of type false|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
155 | . $templatePath; |
||||
156 | if (file_exists($path)) { |
||||
157 | $result = @file_get_contents($path); |
||||
158 | } |
||||
159 | } |
||||
160 | |||||
161 | return $result; |
||||
0 ignored issues
–
show
|
|||||
162 | } |
||||
163 | |||||
164 | /** |
||||
165 | * @inheritdoc |
||||
166 | */ |
||||
167 | public function rules(): array |
||||
168 | { |
||||
169 | $rules = parent::rules(); |
||||
170 | $rules = array_merge($rules, [ |
||||
171 | [ |
||||
172 | [ |
||||
173 | 'name', |
||||
174 | 'description', |
||||
175 | 'templatePath', |
||||
176 | 'templateString', |
||||
177 | 'bodyTemplatePath', |
||||
178 | 'bodyTemplateString', |
||||
179 | ], |
||||
180 | 'string', |
||||
181 | ], |
||||
182 | [ |
||||
183 | [ |
||||
184 | 'position', |
||||
185 | ], |
||||
186 | 'integer', |
||||
187 | ], |
||||
188 | [ |
||||
189 | [ |
||||
190 | 'name', |
||||
191 | 'description', |
||||
192 | 'position', |
||||
193 | ], |
||||
194 | 'required', |
||||
195 | ], |
||||
196 | [ |
||||
197 | [ |
||||
198 | 'templateString', |
||||
199 | 'bodyTemplateString', |
||||
200 | ], |
||||
201 | TwigTemplateValidator::class, |
||||
202 | ], |
||||
203 | [['vars'], 'safe'], |
||||
204 | [['dataLayer'], 'safe'], |
||||
205 | ]); |
||||
206 | |||||
207 | return $rules; |
||||
208 | } |
||||
209 | |||||
210 | /** |
||||
211 | * @inheritdoc |
||||
212 | */ |
||||
213 | public function fields(): array |
||||
214 | { |
||||
215 | $fields = parent::fields(); |
||||
216 | switch ($this->scenario) { |
||||
217 | case 'render': |
||||
218 | $fields = array_diff_key( |
||||
219 | $fields, |
||||
220 | array_flip([ |
||||
221 | 'name', |
||||
222 | 'description', |
||||
223 | 'templatePath', |
||||
224 | 'templateString', |
||||
225 | 'position', |
||||
226 | 'bodyTemplatePath', |
||||
227 | 'bodyTemplateString', |
||||
228 | 'bodyPosition', |
||||
229 | 'vars', |
||||
230 | 'dataLayer', |
||||
231 | ]) |
||||
232 | ); |
||||
233 | break; |
||||
234 | } |
||||
235 | |||||
236 | return $fields; |
||||
237 | } |
||||
238 | |||||
239 | /** |
||||
240 | * @inheritdoc |
||||
241 | */ |
||||
242 | public function prepForRender(&$data): bool |
||||
243 | { |
||||
244 | $shouldRender = parent::prepForRender($data); |
||||
245 | if ($this->discontinued) { |
||||
246 | return false; |
||||
247 | } |
||||
248 | |||||
249 | return $shouldRender; |
||||
250 | } |
||||
251 | |||||
252 | /** |
||||
253 | * Render the script body HTML |
||||
254 | * |
||||
255 | * @param array $params |
||||
256 | * |
||||
257 | * @return string |
||||
258 | */ |
||||
259 | public function renderBodyHtml(array $params = []): string |
||||
260 | { |
||||
261 | $html = ''; |
||||
262 | if (!empty($this->bodyTemplatePath) && $this->prepForRender($params)) { |
||||
263 | $variables = $this->normalizeScriptVars(); |
||||
264 | if (!empty($this->bodyTemplateString)) { |
||||
265 | $html = PluginTemplateHelper::renderStringTemplate($this->bodyTemplateString, $variables); |
||||
266 | } |
||||
267 | } |
||||
268 | |||||
269 | return $html; |
||||
270 | } |
||||
271 | |||||
272 | /** |
||||
273 | * @inheritdoc |
||||
274 | */ |
||||
275 | public function render(array $params = []): string |
||||
276 | { |
||||
277 | $html = ''; |
||||
278 | if (!empty($this->templatePath) && $this->prepForRender($params)) { |
||||
279 | $variables = $this->normalizeScriptVars(); |
||||
280 | $html = PluginTemplateHelper::renderStringTemplate($this->templateString, $variables); |
||||
281 | } |
||||
282 | |||||
283 | if (empty($html) && !empty($this->templatePath)) { |
||||
284 | $html = '/* ' . $this->name . Craft::t('seomatic', ' script did not render') . ' */' . PHP_EOL; |
||||
285 | } |
||||
286 | |||||
287 | return $html; |
||||
288 | } |
||||
289 | |||||
290 | /** |
||||
291 | * @inheritdoc |
||||
292 | */ |
||||
293 | public function renderAttributes(array $params = []): array |
||||
294 | { |
||||
295 | $attributes = []; |
||||
296 | |||||
297 | if ($this->prepForRender($options)) { |
||||
298 | $variables = $this->normalizeScriptVars(); |
||||
299 | if (!empty($this->templateString)) { |
||||
300 | $attributes['script'] |
||||
301 | = PluginTemplateHelper::renderStringTemplate($this->templateString, $variables); |
||||
302 | } |
||||
303 | if (!empty($this->bodyTemplateString)) { |
||||
304 | $attributes['bodyScript'] |
||||
305 | = PluginTemplateHelper::renderStringTemplate($this->bodyTemplateString, $variables); |
||||
306 | } |
||||
307 | } |
||||
308 | |||||
309 | return $attributes; |
||||
310 | } |
||||
311 | |||||
312 | /** |
||||
313 | * Normalize the script variables by parsing them as environment variables, and trimming whitespace |
||||
314 | * |
||||
315 | * @return array |
||||
316 | */ |
||||
317 | private function normalizeScriptVars(): array |
||||
318 | { |
||||
319 | $variables = array_merge($this->vars, [ |
||||
320 | 'dataLayer' => $this->dataLayer, |
||||
321 | ]); |
||||
322 | foreach ($variables as $key => $value) { |
||||
323 | if (!empty($value['value']) && is_string($value['value'])) { |
||||
324 | $variables[$key]['value'] = Craft::parseEnv($value['value']); |
||||
0 ignored issues
–
show
The function
Craft::parseEnv() has been deprecated: in 3.7.29. [[App::parseEnv()]] should be used instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
325 | $variables[$key]['value'] = trim($variables[$key]['value']); |
||||
326 | } |
||||
327 | } |
||||
328 | |||||
329 | return $variables; |
||||
330 | } |
||||
331 | } |
||||
332 |