Passed
Push — develop ( d7df58...421797 )
by Andrew
11:03
created

GenerateSitemap::combineEntryTypeSettings()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 19
c 1
b 0
f 0
nc 3
nop 3
dl 0
loc 27
ccs 0
cts 24
cp 0
crap 12
rs 9.6333
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
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\jobs;
13
14
use nystudio107\seomatic\base\SeoElementInterface;
15
use nystudio107\seomatic\fields\SeoSettings;
16
use nystudio107\seomatic\models\MetaBundle;
17
use nystudio107\seomatic\Seomatic;
18
use nystudio107\seomatic\helpers\ArrayHelper;
19
use nystudio107\seomatic\helpers\Field as FieldHelper;
20
use nystudio107\seomatic\helpers\UrlHelper;
21
use nystudio107\seomatic\models\SitemapTemplate;
22
23
use nystudio107\fastcgicachebust\FastcgiCacheBust;
24
25
use Craft;
26
use craft\base\Element;
27
use craft\base\ElementInterface;
28
use craft\console\Application as ConsoleApplication;
29
use craft\db\Paginator;
30
use craft\elements\Asset;
31
use craft\elements\MatrixBlock;
32
use craft\fields\Assets as AssetsField;
33
use craft\models\SiteGroup;
34
use craft\queue\BaseJob;
35
36
use verbb\supertable\elements\SuperTableBlockElement as SuperTableBlock;
37
38
use benf\neo\elements\Block as NeoBlock;
39
40
use yii\base\Exception;
41
use yii\caching\TagDependency;
42
use yii\helpers\Html;
43
44
/**
45
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
46
 * @package   Seomatic
47
 * @since     3.0.0
48
 */
49
class GenerateSitemap extends BaseJob
50
{
51
    /**
52
     * @const The number of assets to return in a single paginated query
53
     */
54
    const SITEMAP_QUERY_PAGE_SIZE = 100;
55
56
    // Properties
57
    // =========================================================================
58
59
    public $groupId;
60
61
    public $type;
62
63
    public $handle;
64
65
    public $siteId;
66
67
    public $queueJobCacheKey;
68
69
    // Public Methods
70
    // =========================================================================
71
72
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $queue should have a doc-comment as per coding-style.
Loading history...
73
     * @inheritdoc
74
     */
75
    public function execute($queue)
76
    {
77
        // Get an array of site ids for this site group
78
        $groupSiteIds = [];
79
        if (Seomatic::$settings->siteGroupsSeparate) {
80
            /** @var SiteGroup $siteGroup */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
81
            if (empty($this->groupId)) {
82
                try {
83
                    $thisSite = Craft::$app->getSites()->getSiteById($this->siteId);
84
                    if ($thisSite !== null) {
85
                        $group = $thisSite->getGroup();
86
                        $this->groupId = $group->id;
87
                    }
88
                } catch (\Throwable $e) {
89
                    Craft::error($e->getMessage(), __METHOD__);
90
                }
91
            }
92
            $siteGroup = Craft::$app->getSites()->getGroupById($this->groupId);
93
            if ($siteGroup !== null) {
94
                $groupSiteIds = $siteGroup->getSiteIds();
95
            }
96
        }
97
        if (empty($groupSiteIds)) {
98
            $groupSiteIds = Craft::$app->getSites()->allSiteIds;
99
        }
100
        // Output some info if this is a console app
101
        if (Craft::$app instanceof ConsoleApplication) {
102
            echo $this->description.PHP_EOL;
103
        }
104
        $lines = [];
105
        // Sitemap index XML header and opening tag
106
        $lines[] = '<?xml version="1.0" encoding="UTF-8"?>';
107
        $lines[] = '<?xml-stylesheet type="text/xsl" href="sitemap.xsl"?>';
108
        // One sitemap entry for each element
109
        $metaBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceHandle(
110
            $this->type,
111
            $this->handle,
112
            $this->siteId
113
        );
114
        // If it's disabled, just exit
115
        if ($metaBundle === null || !$metaBundle->metaSitemapVars->sitemapUrls) {
116
            return;
117
        }
118
        $multiSite = \count($metaBundle->sourceAltSiteSettings) > 1;
119
        $totalElements = null;
120
        if ($metaBundle) {
121
            $urlsetLine = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
122
            if ($metaBundle->metaSitemapVars->sitemapAssets) {
123
                $urlsetLine .= ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"';
124
                $urlsetLine .= ' xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"';
125
            }
126
            if ($multiSite) {
127
                $urlsetLine .= ' xmlns:xhtml="http://www.w3.org/1999/xhtml"';
128
            }
129
            $urlsetLine .= '>';
130
            $lines[] = $urlsetLine;
131
            // Get all of the elements for this meta bundle type
132
            $seoElement = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType($metaBundle->sourceBundleType);
133
            if ($seoElement !== null) {
134
                // Ensure `null` so that the resulting element query is correct
135
                if (empty($metaBundle->metaSitemapVars->sitemapLimit)) {
136
                    $metaBundle->metaSitemapVars->sitemapLimit = null;
137
                }
138
                $totalElements = $seoElement::sitemapElementsQuery($metaBundle)->count();
139
                if  ($metaBundle->metaSitemapVars->sitemapLimit && ($totalElements > $metaBundle->metaSitemapVars->sitemapLimit)) {
0 ignored issues
show
Coding Style introduced by
Expected "if (...) {\n"; found "if (...) {\n"
Loading history...
140
                    $totalElements = $metaBundle->metaSitemapVars->sitemapLimit;
141
                }
142
            }
143
            // If no elements exist, just exit
144
            if (!$totalElements) {
145
                return;
146
            }
147
            // Stash the sitemap attributes so they can be modified on a per-entry basis
148
            $stashedSitemapAttrs = $metaBundle->metaSitemapVars->getAttributes();
149
            $stashedGlobalVarsAttrs = $metaBundle->metaGlobalVars->getAttributes();
150
            // Use craft\db\Paginator to paginate the results so we don't exceed any memory limits
151
            // See batch() and each() discussion here: https://github.com/yiisoft/yii2/issues/8420
152
            // and here: https://github.com/craftcms/cms/issues/7338
153
            $paginator = new Paginator($seoElement::sitemapElementsQuery($metaBundle), [
154
                    'pageSize' => self::SITEMAP_QUERY_PAGE_SIZE,
155
            ]);
156
            $currentElement = 0;
157
            // Iterate through the paginated results
158
            while ($currentElement < $totalElements) {
159
                $elements = $paginator->getPageResults();
160
                if (Craft::$app instanceof ConsoleApplication) {
161
                    echo 'Query ' . $paginator->getCurrentPage() . '/' . $paginator->getTotalPages()
162
                        . ' - elements: ' . $paginator->getTotalResults()
163
                        . PHP_EOL;
164
                }
165
                /** @var ElementInterface $element */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
166
                foreach ($elements as $element) {
167
                    $this->setProgress($queue, $currentElement++ / $totalElements);
168
                    // Output some info if this is a console app
169
                    if (Craft::$app instanceof ConsoleApplication) {
170
                        echo "Processing element {$currentElement}/{$totalElements} - {$element->title}".PHP_EOL;
171
                    }
172
                    $metaBundle->metaSitemapVars->setAttributes($stashedSitemapAttrs, false);
173
                    $metaBundle->metaGlobalVars->setAttributes($stashedGlobalVarsAttrs, false);
174
                    // Combine in any per-entry type settings
175
                    $this->combineEntryTypeSettings($seoElement, $element, $metaBundle);
176
                    // Make sure this entry isn't disabled
177
                    $this->combineFieldSettings($element, $metaBundle);
178
                    // Special case for the __home__ URI
179
                    $path = ($element->uri === '__home__') ? '' : $element->uri;
180
                    // Check to see if robots is `none` or `no index`
181
                    $robotsEnabled = true;
182
                    if (!empty($metaBundle->metaGlobalVars->robots)) {
183
                        $robotsEnabled = $metaBundle->metaGlobalVars->robots !== 'none' &&
184
                            $metaBundle->metaGlobalVars->robots !== 'noindex';
185
                    }
186
                    // Only add in a sitemap entry if it meets our criteria
187
                    if ($path !== null && $metaBundle->metaSitemapVars->sitemapUrls && $robotsEnabled) {
188
                        try {
189
                            $url = UrlHelper::siteUrl($path, null, null, $metaBundle->sourceSiteId);
190
                        } catch (Exception $e) {
191
                            $url = '';
192
                        }
193
                        $url = UrlHelper::absoluteUrlWithProtocol($url);
194
                        $dateUpdated = $element->dateUpdated ?? $element->dateCreated ?? new \DateTime;
195
                        $lines[] = '<url>';
196
                        // Standard sitemap key/values
197
                        $lines[] = '<loc>';
198
                        $lines[] = Html::encode($url);
199
                        $lines[] = '</loc>';
200
                        $lines[] = '<lastmod>';
201
                        $lines[] = $dateUpdated->format(\DateTime::W3C);
202
                        $lines[] = '</lastmod>';
203
                        $lines[] = '<changefreq>';
204
                        $lines[] = $metaBundle->metaSitemapVars->sitemapChangeFreq;
205
                        $lines[] = '</changefreq>';
206
                        $lines[] = '<priority>';
207
                        $lines[] = $metaBundle->metaSitemapVars->sitemapPriority;
208
                        $lines[] = '</priority>';
209
                        // Handle alternate URLs if this is multi-site
210
                        if ($multiSite && $metaBundle->metaSitemapVars->sitemapAltLinks) {
211
                            $primarySiteId = Craft::$app->getSites()->getPrimarySite()->id;
212
                            /** @var  $altSiteSettings */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
213
                            foreach ($metaBundle->sourceAltSiteSettings as $altSiteSettings) {
214
                                if (\in_array($altSiteSettings['siteId'], $groupSiteIds, false)) {
215
                                    $altElement = null;
216
                                    if ($seoElement !== null) {
217
                                        $altElement = $seoElement::sitemapAltElement(
218
                                            $metaBundle,
219
                                            $element->id,
220
                                            $altSiteSettings['siteId']
221
                                        );
222
                                    }
223
                                    // Make sure to only include the `hreflang` if the element exists,
224
                                    // and sitemaps are on for it
225
                                    if ($altElement && $altElement->url) {
226
                                        list($altSourceId, $altSourceBundleType, $altSourceHandle, $altSourceSiteId, $altTypeId)
227
                                            = Seomatic::$plugin->metaBundles->getMetaSourceFromElement($altElement);
228
                                        $altMetaBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceId(
229
                                            $altSourceBundleType,
230
                                            $altSourceId,
231
                                            $altSourceSiteId
232
                                        );
233
                                        if ($altMetaBundle) {
234
                                            // Make sure this entry isn't disabled
235
                                            $this->combineFieldSettings($altElement, $altMetaBundle);
236
                                            $altUrl = UrlHelper::absoluteUrlWithProtocol($altElement->url);
237
                                            if ($altMetaBundle->metaSitemapVars->sitemapUrls) {
238
                                                // If this is the primary site, add it as x-default, too
239
                                                if ($primarySiteId === $altSourceSiteId && Seomatic::$settings->addXDefaultHrefLang) {
240
                                                    $lines[] = '<xhtml:link rel="alternate"'
241
                                                        .' hreflang="x-default"'
242
                                                        .' href="'.Html::encode($altUrl).'"'
243
                                                        .' />';
244
                                                }
245
                                                $lines[] = '<xhtml:link rel="alternate"'
246
                                                    .' hreflang="'.$altSiteSettings['language'].'"'
247
                                                    .' href="'.Html::encode($altUrl).'"'
248
                                                    .' />';
249
                                            }
250
                                        }
251
                                    }
252
                                }
253
                            }
254
                        }
255
                        // Handle any Assets
256
                        if ($metaBundle->metaSitemapVars->sitemapAssets) {
257
                            // Regular Assets fields
258
                            $assetFields = FieldHelper::fieldsOfTypeFromElement(
259
                                $element,
260
                                FieldHelper::ASSET_FIELD_CLASS_KEY,
261
                                true
262
                            );
263
                            foreach ($assetFields as $assetField) {
264
                                $assets = $element[$assetField]->all();
265
                                /** @var Asset[] $assets */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
266
                                foreach ($assets as $asset) {
267
                                    $this->assetSitemapItem($asset, $metaBundle, $lines);
268
                                }
269
                            }
270
                            // Assets embeded in Block fields
271
                            $blockFields = FieldHelper::fieldsOfTypeFromElement(
272
                                $element,
273
                                FieldHelper::BLOCK_FIELD_CLASS_KEY,
274
                                true
275
                            );
276
                            foreach ($blockFields as $blockField) {
277
                                $blocks = $element[$blockField]->all();
278
                                /** @var MatrixBlock[]|NeoBlock[]|SuperTableBlock[] $blocks */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
279
                                foreach ($blocks as $block) {
280
                                    $assetFields = [];
281
                                    if ($block instanceof MatrixBlock) {
282
                                        $assetFields = FieldHelper::matrixFieldsOfType($block, AssetsField::class);
283
                                    }
284
                                    if ($block instanceof NeoBlock) {
285
                                        $assetFields = FieldHelper::neoFieldsOfType($block, AssetsField::class);
286
                                    }
287
                                    if ($block instanceof SuperTableBlock) {
288
                                        $assetFields = FieldHelper::superTableFieldsOfType($block, AssetsField::class);
289
                                    }
290
                                    foreach ($assetFields as $assetField) {
291
                                        foreach ($block[$assetField]->all() as $asset) {
292
                                            $this->assetSitemapItem($asset, $metaBundle, $lines);
293
                                        }
294
                                    }
295
                                }
296
                            }
297
                        }
298
                        $lines[] = '</url>';
299
                    }
300
                    // Include links to any known file types in the assets fields
301
                    if ($metaBundle->metaSitemapVars->sitemapFiles) {
302
                        // Regular Assets fields
303
                        $assetFields = FieldHelper::fieldsOfTypeFromElement(
304
                            $element,
305
                            FieldHelper::ASSET_FIELD_CLASS_KEY,
306
                            true
307
                        );
308
                        foreach ($assetFields as $assetField) {
309
                            $assets = $element[$assetField]->all();
310
                            foreach ($assets as $asset) {
311
                                $this->assetFilesSitemapLink($asset, $metaBundle, $lines);
312
                            }
313
                        }
314
                        // Assets embeded in Block fields
315
                        $blockFields = FieldHelper::fieldsOfTypeFromElement(
316
                            $element,
317
                            FieldHelper::BLOCK_FIELD_CLASS_KEY,
318
                            true
319
                        );
320
                        foreach ($blockFields as $blockField) {
321
                            $blocks = $element[$blockField]->all();
322
                            /** @var MatrixBlock $block */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
323
                            foreach ($blocks as $block) {
324
                                $assetFields = [];
325
                                if ($block instanceof MatrixBlock) {
326
                                    $assetFields = FieldHelper::matrixFieldsOfType($block, AssetsField::class);
327
                                }
328
                                if ($block instanceof NeoBlock) {
329
                                    $assetFields = FieldHelper::neoFieldsOfType($block, AssetsField::class);
330
                                }
331
                                foreach ($assetFields as $assetField) {
332
                                    foreach ($block[$assetField]->all() as $asset) {
333
                                        $this->assetFilesSitemapLink($asset, $metaBundle, $lines);
334
                                    }
335
                                }
336
                            }
337
                        }
338
                    }
339
                }
340
                $paginator->currentPage++;
341
            }
342
            // Sitemap closing tag
343
            $lines[] = '</urlset>';
344
        }
345
346
        $cache = Craft::$app->getCache();
347
        $cacheKey = SitemapTemplate::CACHE_KEY.$this->groupId.$this->type.$this->handle.$this->siteId;
348
        $dependency = new TagDependency([
349
            'tags' => [
350
                SitemapTemplate::GLOBAL_SITEMAP_CACHE_TAG,
351
                SitemapTemplate::SITEMAP_CACHE_TAG.$this->handle.$this->siteId,
352
            ],
353
        ]);
354
        $lines = implode('', $lines);
355
        // Cache sitemap cache; we use this instead of Seomatic::$cacheDuration because for
356
        // Control Panel requests, we set Seomatic::$cacheDuration = 1 so that they are never
357
        // cached
358
        $cacheDuration = Seomatic::$devMode
359
            ? Seomatic::DEVMODE_CACHE_DURATION
360
            : null;
361
        $result = $cache->set($cacheKey, $lines, $cacheDuration, $dependency);
362
        // Remove the queue job id from the cache too
363
        $cache->delete($this->queueJobCacheKey);
364
        Craft::debug('Sitemap cache result: '.print_r($result, true).' for cache key: '.$cacheKey, __METHOD__);
365
        // Output some info if this is a console app
366
        if (Craft::$app instanceof ConsoleApplication) {
367
            echo 'Sitemap cache result: '.print_r($result, true).' for cache key: '.$cacheKey.PHP_EOL;
368
        }
369
        // If the FastCGI Cache Bust plugin is installed, clear its caches too
370
        $plugin = Craft::$app->getPlugins()->getPlugin('fastcgi-cache-bust');
371
        if ($plugin !== null) {
372
            FastcgiCacheBust::$plugin->cache->clearAll();
373
        }
374
    }
375
376
    // Protected Methods
377
    // =========================================================================
378
379
    /**
380
     * @inheritdoc
381
     */
382
    protected function defaultDescription(): string
383
    {
384
        return Craft::t('app', 'Generating {handle} sitemap', [
385
            'handle' => $this->handle,
386
        ]);
387
    }
388
389
390
    // Protected Methods
391
    // =========================================================================
392
393
    /**
394
     * Combine any per-entry type field settings from $element with the passed in
395
     * $metaBundle
396
     *
397
     * @param SeoElementInterface $seoElement
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
398
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 13 spaces after parameter type; 1 found
Loading history...
399
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
400
     */
401
    protected function combineEntryTypeSettings(SeoElementInterface $seoElement, Element $element, MetaBundle $metaBundle)
402
    {
403
        if (!empty($seoElement::typeMenuFromHandle($metaBundle->sourceHandle))) {
404
            list($sourceId, $sourceBundleType, $sourceHandle, $sourceSiteId, $typeId)
405
                = Seomatic::$plugin->metaBundles->getMetaSourceFromElement($element);
406
            $entryTypeBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceId(
407
                $sourceBundleType,
408
                $sourceId,
409
                $sourceSiteId,
410
                $typeId
411
            );
412
            // Combine in any settings for this entry type
413
            if ($entryTypeBundle) {
414
                // Combine the meta sitemap vars
415
                $attributes = $entryTypeBundle->metaSitemapVars->getAttributes();
416
                $attributes = array_filter(
417
                    $attributes,
418
                    [ArrayHelper::class, 'preserveBools']
419
                );
420
                $metaBundle->metaSitemapVars->setAttributes($attributes, false);
421
                // Combine the meta global vars
422
                $attributes = $entryTypeBundle->metaGlobalVars->getAttributes();
423
                $attributes = array_filter(
424
                    $attributes,
425
                    [ArrayHelper::class, 'preserveBools']
426
                );
427
                $metaBundle->metaGlobalVars->setAttributes($attributes, false);
428
            }
429
        }
430
    }
431
432
    /**
433
     * Combine any SEO Settings field settings from $element with the passed in
434
     * $metaBundle
435
     *
436
     * @param Element    $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
437
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
438
     */
439
    protected function combineFieldSettings(Element $element, MetaBundle $metaBundle)
440
    {
441
        $fieldHandles = FieldHelper::fieldsOfTypeFromElement(
442
            $element,
443
            FieldHelper::SEO_SETTINGS_CLASS_KEY,
444
            true
445
        );
446
        foreach ($fieldHandles as $fieldHandle) {
447
            if (!empty($element->$fieldHandle)) {
448
                /** @var SeoSettings $seoSettingsField */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
449
                $seoSettingsField = Craft::$app->getFields()->getFieldByHandle($fieldHandle);
450
                /** @var MetaBundle $metaBundle */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
451
                $fieldMetaBundle = $element->$fieldHandle;
452
                if ($fieldMetaBundle !== null && $seoSettingsField !== null && $seoSettingsField->sitemapTabEnabled) {
453
                    // Combine the meta sitemap vars
454
                    $attributes = $fieldMetaBundle->metaSitemapVars->getAttributes();
455
                    $attributes = \array_intersect_key(
456
                        $attributes,
457
                        array_flip($seoSettingsField->sitemapEnabledFields)
458
                    );
459
                    $attributes = array_filter(
460
                        $attributes,
461
                        [ArrayHelper::class, 'preserveBools']
462
                    );
463
                    $metaBundle->metaSitemapVars->setAttributes($attributes, false);
464
                    // Combine the meta global vars
465
                    $attributes = $fieldMetaBundle->metaGlobalVars->getAttributes();
466
                    $attributes = array_filter(
467
                        $attributes,
468
                        [ArrayHelper::class, 'preserveBools']
469
                    );
470
                    $metaBundle->metaGlobalVars->setAttributes($attributes, false);
471
                }
472
            }
473
        }
474
    }
475
476
    /**
477
     * @param Asset      $asset
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
478
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
479
     * @param array      $lines
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
480
     */
481
    protected function assetSitemapItem(Asset $asset, MetaBundle $metaBundle, array &$lines)
482
    {
483
        if ((bool)$asset->enabledForSite && $asset->getUrl() !== null) {
484
            switch ($asset->kind) {
485
                case 'image':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
486
                    $lines[] = '<image:image>';
487
                    $lines[] = '<image:loc>';
488
                    $lines[] = Html::encode(UrlHelper::absoluteUrlWithProtocol($asset->getUrl()));
489
                    $lines[] = '</image:loc>';
490
                    // Handle the dynamic field => property mappings
491
                    foreach ($metaBundle->metaSitemapVars->sitemapImageFieldMap as $row) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
492
                        $fieldName = $row['field'] ?? '';
493
                        $propName = $row['property'] ?? '';
494
                        if (!empty($asset[$fieldName]) && !empty($propName)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
495
                            $lines[] = '<image:'.$propName.'>';
496
                            $lines[] = Html::encode($asset[$fieldName]);
497
                            $lines[] = '</image:'.$propName.'>';
498
                        }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
499
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
500
                    $lines[] = '</image:image>';
501
                    break;
502
503
                case 'video':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
504
                    $lines[] = '<video:video>';
505
                    $lines[] = '<video:content_loc>';
506
                    $lines[] = Html::encode(UrlHelper::absoluteUrlWithProtocol($asset->getUrl()));
507
                    $lines[] = '</video:content_loc>';
508
                    // Handle the dynamic field => property mappings
509
                    foreach ($metaBundle->metaSitemapVars->sitemapVideoFieldMap as $row) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
510
                        $fieldName = $row['field'] ?? '';
511
                        $propName = $row['property'] ?? '';
512
                        if (!empty($asset[$fieldName]) && !empty($propName)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
513
                            $lines[] = '<video:'.$propName.'>';
514
                            $lines[] = Html::encode($asset[$fieldName]);
515
                            $lines[] = '</video:'.$propName.'>';
516
                        }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
517
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
518
                    $lines[] = '</video:video>';
519
                    break;
520
            }
521
        }
522
    }
523
524
    /**
525
     * @param Asset      $asset
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
526
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
527
     * @param array      $lines
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
528
     */
529
    protected function assetFilesSitemapLink(Asset $asset, MetaBundle $metaBundle, array &$lines)
530
    {
531
        if ((bool)$asset->enabledForSite && $asset->getUrl() !== null) {
532
            if (\in_array($asset->kind, SitemapTemplate::FILE_TYPES, false)) {
533
                $dateUpdated = $asset->dateUpdated ?? $asset->dateCreated ?? new \DateTime;
534
                $lines[] = '<url>';
535
                $lines[] = '<loc>';
536
                $lines[] = Html::encode(UrlHelper::absoluteUrlWithProtocol($asset->getUrl()));
537
                $lines[] = '</loc>';
538
                $lines[] = '<lastmod>';
539
                $lines[] = $dateUpdated->format(\DateTime::W3C);
540
                $lines[] = '</lastmod>';
541
                $lines[] = '<changefreq>';
542
                $lines[] = $metaBundle->metaSitemapVars->sitemapChangeFreq;
543
                $lines[] = '</changefreq>';
544
                $lines[] = '<priority>';
545
                $lines[] = $metaBundle->metaSitemapVars->sitemapPriority;
546
                $lines[] = '</priority>';
547
                $lines[] = '</url>';
548
            }
549
        }
550
    }
551
}
552