homepage/bundle/SiteMapBundle/SiteMapGenerator.php

118 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Homepage\SiteMapBundle;
use Sculpin\Core\DataProvider\DataProviderInterface;
use Sculpin\Core\Event\SourceSetEvent;
use Sculpin\Core\Sculpin;
use Sculpin\Core\Source\SourceInterface;
use Sculpin\Core\Source\SourceSet;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SiteMapGenerator implements DataProviderInterface, EventSubscriberInterface
{
/**
* @var array|null
*/
private $siteMap;
/**
* @var SourceSet
*/
private $sources;
public static function getSubscribedEvents(): array
{
return [
Sculpin::EVENT_BEFORE_RUN => 'saveSourceSet',
];
}
/**
* Provide data.
*/
public function provideData(): array
{
$this->buildSiteMap();
return $this->siteMap;
}
/**
* Before run.
*
* @param SourceSetEvent $sourceSetEvent Source Set Event
*/
public function saveSourceSet(SourceSetEvent $sourceSetEvent)
{
$this->sources = $sourceSetEvent->sourceSet();
}
protected function buildSiteMap(): array
{
if ($this->siteMap !== null) {
return $this->siteMap;
}
$this->siteMap = $this->createSiteMap();
return $this->siteMap;
}
private function createSiteMap(): array
{
$siteMap = [];
/** @var \Sculpin\Core\Source\FileSource $source */
foreach ($this->sources->allSources() as $source) {
$url = $this->createSiteUrlFromSource($source);
if (!$url) {
continue;
}
$siteMap[$url['loc']] = $url;
}
return $siteMap;
}
private function createSiteUrlFromSource(SourceInterface $source): array
{
$data = $source->data()->export();
if (empty($data) || $source->useFileReference()) {
return [];
}
if (array_key_exists('draft', $data) && $data['draft']) {
return [];
}
$siteMapData = $data['sitemap'] ?? [];
if (array_key_exists('_exclude', $siteMapData)) {
return [];
}
$loc = $data['canonical'] ?? $data['url'];
if (is_callable([$source, 'file'])) {
$lastmod = date(DATE_W3C, $source->file()->getMTime());
} else {
$lastmod = date(DATE_W3C);
}
$url = [
'loc' => $loc,
'lastmod' => $lastmod,
];
if (isset($data['sitemap'])) {
$url = array_merge($url, $data['sitemap']);
}
return $url;
}
}