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\behaviors\EnvAttributeParserBehavior; |
||||||
15 | use craft\helpers\Json as JsonHelper; |
||||||
16 | use craft\validators\ArrayValidator; |
||||||
17 | use craft\validators\DateTimeValidator; |
||||||
18 | use DateTime; |
||||||
19 | use nystudio107\seomatic\base\FluentModel; |
||||||
20 | use nystudio107\seomatic\base\MetaContainer; |
||||||
21 | use nystudio107\seomatic\helpers\ArrayHelper; |
||||||
22 | use nystudio107\seomatic\helpers\MetaValue as MetaValueHelper; |
||||||
23 | use nystudio107\seomatic\Seomatic; |
||||||
24 | use nystudio107\seomatic\variables\SeomaticVariable; |
||||||
25 | use function is_array; |
||||||
26 | use function is_string; |
||||||
27 | |||||||
28 | /** |
||||||
29 | * @author nystudio107 |
||||||
30 | * @package Seomatic |
||||||
31 | * @since 3.0.0 |
||||||
32 | */ |
||||||
33 | class MetaBundle extends FluentModel |
||||||
34 | { |
||||||
35 | // Properties |
||||||
36 | // ========================================================================= |
||||||
37 | |||||||
38 | /** |
||||||
39 | * @var string |
||||||
40 | */ |
||||||
41 | public $bundleVersion; |
||||||
42 | |||||||
43 | /** |
||||||
44 | * @var string |
||||||
45 | */ |
||||||
46 | public $sourceBundleType; |
||||||
47 | |||||||
48 | /** |
||||||
49 | * @var int |
||||||
50 | */ |
||||||
51 | public $sourceId; |
||||||
52 | |||||||
53 | /** |
||||||
54 | * @var string |
||||||
55 | */ |
||||||
56 | public $sourceName; |
||||||
57 | |||||||
58 | /** |
||||||
59 | * @var string |
||||||
60 | */ |
||||||
61 | public $sourceHandle; |
||||||
62 | |||||||
63 | /** |
||||||
64 | * @var string |
||||||
65 | */ |
||||||
66 | public $sourceType; |
||||||
67 | |||||||
68 | /** |
||||||
69 | * @var int|null |
||||||
70 | */ |
||||||
71 | public $typeId; |
||||||
72 | |||||||
73 | /** |
||||||
74 | * @var string |
||||||
75 | */ |
||||||
76 | public $sourceTemplate; |
||||||
77 | |||||||
78 | /** |
||||||
79 | * @var int |
||||||
80 | */ |
||||||
81 | public $sourceSiteId; |
||||||
82 | |||||||
83 | /** |
||||||
84 | * @var array |
||||||
85 | */ |
||||||
86 | public $sourceAltSiteSettings = []; |
||||||
87 | |||||||
88 | /** |
||||||
89 | * @var DateTime |
||||||
90 | */ |
||||||
91 | public $sourceDateUpdated; |
||||||
92 | |||||||
93 | /** |
||||||
94 | * @var MetaGlobalVars|array|null |
||||||
95 | */ |
||||||
96 | public $metaGlobalVars; |
||||||
97 | |||||||
98 | /** |
||||||
99 | * @var MetaSiteVars|array|null |
||||||
100 | */ |
||||||
101 | public $metaSiteVars; |
||||||
102 | |||||||
103 | /** |
||||||
104 | * @var MetaSitemapVars|array|null |
||||||
105 | */ |
||||||
106 | public $metaSitemapVars; |
||||||
107 | |||||||
108 | /** |
||||||
109 | * @var MetaContainer[]|array|null |
||||||
110 | */ |
||||||
111 | public $metaContainers; |
||||||
112 | |||||||
113 | /** |
||||||
114 | * @var array |
||||||
115 | */ |
||||||
116 | public $redirectsContainer; |
||||||
117 | |||||||
118 | /** |
||||||
119 | * @var FrontendTemplateContainer|array|null |
||||||
120 | */ |
||||||
121 | public $frontendTemplatesContainer; |
||||||
122 | |||||||
123 | /** |
||||||
124 | * @var MetaBundleSettings|array|null |
||||||
125 | */ |
||||||
126 | public $metaBundleSettings; |
||||||
127 | |||||||
128 | // Methods |
||||||
129 | // ========================================================================= |
||||||
130 | |||||||
131 | /** |
||||||
132 | * Create a new meta bundle |
||||||
133 | * |
||||||
134 | * @param array $config |
||||||
135 | * @param bool $parse Whether the resulting metabundle should be parsed |
||||||
136 | * |
||||||
137 | * @return null|MetaBundle |
||||||
138 | */ |
||||||
139 | public static function create(array $config = [], bool $parse = true) |
||||||
140 | { |
||||||
141 | self::cleanProperties(__CLASS__, $config); |
||||||
142 | $model = new MetaBundle($config); |
||||||
143 | $model->normalizeMetaBundleData($parse); |
||||||
144 | |||||||
145 | return $model; |
||||||
146 | } |
||||||
147 | |||||||
148 | /** |
||||||
149 | * Normalizes the meta bundles’s data for use. |
||||||
150 | * |
||||||
151 | * This is called after meta bundle data is loaded, to allow it to be |
||||||
152 | * parsed, models instantiated, etc. |
||||||
153 | * |
||||||
154 | * @param bool $parse Whether the resulting metabundle should be parsed |
||||||
155 | */ |
||||||
156 | public function normalizeMetaBundleData(bool $parse = true) |
||||||
157 | { |
||||||
158 | // Decode any JSON data |
||||||
159 | $properties = $this->getAttributes(); |
||||||
160 | foreach ($properties as $property => $value) { |
||||||
161 | if (!empty($value) && is_string($value)) { |
||||||
162 | $this->$property = JsonHelper::decodeIfJson($value); |
||||||
163 | } |
||||||
164 | } |
||||||
165 | // Meta global variables |
||||||
166 | if (is_array($this->metaGlobalVars)) { |
||||||
167 | $this->metaGlobalVars = MetaGlobalVars::create($this->metaGlobalVars); |
||||||
168 | } |
||||||
169 | // Meta site variables |
||||||
170 | if (is_array($this->metaSiteVars)) { |
||||||
171 | $this->metaSiteVars = MetaSiteVars::create($this->metaSiteVars); |
||||||
172 | } |
||||||
173 | // Meta sitemap variables |
||||||
174 | if (is_array($this->metaSitemapVars)) { |
||||||
175 | $this->metaSitemapVars = MetaSitemapVars::create($this->metaSitemapVars); |
||||||
176 | } |
||||||
177 | // Meta bundle settings |
||||||
178 | if (is_array($this->metaBundleSettings)) { |
||||||
179 | $this->metaBundleSettings = MetaBundleSettings::create($this->metaBundleSettings); |
||||||
180 | } |
||||||
181 | // Frontend templates |
||||||
182 | if (is_array($this->frontendTemplatesContainer)) { |
||||||
183 | $this->frontendTemplatesContainer = FrontendTemplateContainer::create($this->frontendTemplatesContainer); |
||||||
184 | } |
||||||
185 | // Create our variable so that meta containers can be parsed based on dynamic values |
||||||
186 | // Make sure Twig is loaded and instantiated first by priming the pump |
||||||
187 | if ($parse) { |
||||||
188 | MetaValueHelper::parseString('{{ "prime" }}'); |
||||||
189 | $oldSeomaticVariable = Seomatic::$seomaticVariable; |
||||||
190 | if (Seomatic::$seomaticVariable === null) { |
||||||
191 | Seomatic::$seomaticVariable = new SeomaticVariable(); |
||||||
192 | } |
||||||
193 | $oldMeta = Seomatic::$seomaticVariable->meta; |
||||||
194 | $oldSite = Seomatic::$seomaticVariable->site; |
||||||
195 | $oldLoadingContainers = Seomatic::$loadingMetaContainers; |
||||||
196 | $oldPreviewingMetaContainers = Seomatic::$previewingMetaContainers; |
||||||
197 | Seomatic::$loadingMetaContainers = false; |
||||||
198 | Seomatic::$previewingMetaContainers = false; |
||||||
199 | // Merge these global vars with the MetaContainers global vars |
||||||
200 | $globalVars = []; |
||||||
201 | if (Seomatic::$plugin->metaContainers->metaGlobalVars !== null) { |
||||||
202 | $globalVars = Seomatic::$plugin->metaContainers->metaGlobalVars->getAttributes(); |
||||||
203 | } |
||||||
204 | $thisGlobalVars = $this->metaGlobalVars->getAttributes(); |
||||||
0 ignored issues
–
show
|
|||||||
205 | $thisGlobals = MetaGlobalVars::create(ArrayHelper::merge($globalVars, $thisGlobalVars)); |
||||||
206 | // Merge these site vars with the MetaContainers site vars |
||||||
207 | $siteVars = []; |
||||||
208 | if (Seomatic::$plugin->metaContainers->metaSiteVars !== null) { |
||||||
209 | $siteVars = Seomatic::$plugin->metaContainers->metaSiteVars->getAttributes(); |
||||||
210 | } |
||||||
211 | $thisSiteVars = $this->metaSiteVars->getAttributes(); |
||||||
0 ignored issues
–
show
The method
getAttributes() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
212 | $thisSite = MetaSiteVars::create(ArrayHelper::merge($siteVars, $thisSiteVars)); |
||||||
213 | Seomatic::$seomaticVariable->meta = $thisGlobals; |
||||||
214 | Seomatic::$seomaticVariable->site = $thisSite; |
||||||
215 | MetaValueHelper::cache(); |
||||||
216 | Seomatic::$previewingMetaContainers = $oldPreviewingMetaContainers; |
||||||
217 | |||||||
218 | // Meta containers |
||||||
219 | if (!empty($this->metaContainers)) { |
||||||
220 | $metaContainers = $this->metaContainers; |
||||||
221 | $this->metaContainers = []; |
||||||
222 | foreach ($metaContainers as $key => $metaContainer) { |
||||||
223 | /** @var MetaContainer $containerClass */ |
||||||
224 | $containerClass = $metaContainer['class']; |
||||||
225 | /** @var array $metaContainer */ |
||||||
226 | $this->metaContainers[$key] = $containerClass::create($metaContainer); |
||||||
227 | } |
||||||
228 | } |
||||||
229 | // Restore the $seomaticVariable |
||||||
230 | Seomatic::$loadingMetaContainers = $oldLoadingContainers; |
||||||
231 | Seomatic::$seomaticVariable->meta = $oldMeta; |
||||||
232 | Seomatic::$seomaticVariable->site = $oldSite; |
||||||
233 | Seomatic::$seomaticVariable = $oldSeomaticVariable; |
||||||
234 | MetaValueHelper::cache(); |
||||||
235 | } |
||||||
236 | } |
||||||
237 | |||||||
238 | /** |
||||||
239 | * @inheritdoc |
||||||
240 | */ |
||||||
241 | public function datetimeAttributes(): array |
||||||
242 | { |
||||||
243 | $names = parent::datetimeAttributes(); |
||||||
0 ignored issues
–
show
The function
craft\base\Model::datetimeAttributes() has been deprecated: in 4.0.0. Use [[\DateTime]] type declarations 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. ![]() |
|||||||
244 | $names[] = 'sourceDateUpdated'; |
||||||
245 | |||||||
246 | return $names; |
||||||
247 | } |
||||||
248 | |||||||
249 | /** |
||||||
250 | * Validation rules |
||||||
251 | * @return array the validation rules |
||||||
252 | */ |
||||||
253 | public function rules(): array |
||||||
254 | { |
||||||
255 | $rules = [ |
||||||
256 | [ |
||||||
257 | [ |
||||||
258 | 'bundleVersion', |
||||||
259 | 'sourceType', |
||||||
260 | 'sourceName', |
||||||
261 | 'sourceHandle', |
||||||
262 | 'sourceTemplate', |
||||||
263 | 'sourceType', |
||||||
264 | ], |
||||||
265 | 'string', |
||||||
266 | ], |
||||||
267 | [ |
||||||
268 | [ |
||||||
269 | 'sourceId', |
||||||
270 | 'sourceSiteId', |
||||||
271 | 'typeId', |
||||||
272 | ], |
||||||
273 | 'number', |
||||||
274 | 'skipOnEmpty' => true, |
||||||
275 | ], |
||||||
276 | [ |
||||||
277 | [ |
||||||
278 | 'sourceDateUpdated', |
||||||
279 | ], |
||||||
280 | DateTimeValidator::class, |
||||||
281 | ], |
||||||
282 | [ |
||||||
283 | [ |
||||||
284 | 'sourceAltSiteSettings', |
||||||
285 | ], |
||||||
286 | 'safe', |
||||||
287 | ], |
||||||
288 | [ |
||||||
289 | [ |
||||||
290 | 'metaContainers', |
||||||
291 | 'redirectsContainer', |
||||||
292 | ], |
||||||
293 | ArrayValidator::class, |
||||||
294 | ], |
||||||
295 | [ |
||||||
296 | [ |
||||||
297 | 'metaGlobalVars', |
||||||
298 | 'metaSiteVars', |
||||||
299 | 'metaSitemapVars', |
||||||
300 | 'metaBundleSettings', |
||||||
301 | 'frontendTemplatesContainer', |
||||||
302 | ], |
||||||
303 | 'safe', |
||||||
304 | ], |
||||||
305 | ]; |
||||||
306 | |||||||
307 | return $rules; |
||||||
308 | } |
||||||
309 | |||||||
310 | /** |
||||||
311 | * @return array |
||||||
312 | */ |
||||||
313 | public function behaviors(): array |
||||||
314 | { |
||||||
315 | $behaviors = parent::behaviors(); |
||||||
316 | |||||||
317 | return array_merge($behaviors, [ |
||||||
318 | 'parser' => [ |
||||||
319 | 'class' => EnvAttributeParserBehavior::class, |
||||||
320 | 'attributes' => [ |
||||||
321 | ], |
||||||
322 | ], |
||||||
323 | ]); |
||||||
324 | } |
||||||
325 | } |
||||||
326 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.