diff --git a/composer.json b/composer.json index f98dc8b7b63a323bce78c4ba2e9bf87f6e1b0e91..bb6612a3cd9857914452c10bcc3608236dfe1314 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "drupal/metatag": "~1.4", "drupal/schema_metatag": "~1.3", "drupal/pathauto": "~1.0", - "drupal/simple_sitemap": "~2.7", + "drupal/simple_sitemap": "~3.1", "drupal/migrate_source_csv": "~2.2", "drupal/colorbox": "~1.4", "drupal/slick": "~1.0", diff --git a/src/Plugin/simple_sitemap/SitemapGenerator/PerLanguageSitemapGenerator.php b/src/Plugin/simple_sitemap/SitemapGenerator/PerLanguageSitemapGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..a1bb3b483552260713fd8974dea4560a01459c31 --- /dev/null +++ b/src/Plugin/simple_sitemap/SitemapGenerator/PerLanguageSitemapGenerator.php @@ -0,0 +1,197 @@ +<?php + +namespace Drupal\rocketship_core\Plugin\simple_sitemap\SitemapGenerator; + +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorBase; +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapWriter; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Database\Connection; +use Drupal\Core\Extension\ModuleHandler; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Component\Datetime\Time; + +/** + * Class DefaultSitemapGenerator + * + * @package Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator + * + * @SitemapGenerator( + * id = "per_language_generator", + * label = @Translation("Per language sitemap generator"), + * description = @Translation("Generates a sitemap which links to sitemaps + * per language."), + * ) + */ +class PerLanguageSitemapGenerator extends SitemapGeneratorBase { + + const XMLNS_XHTML = 'http://www.w3.org/1999/xhtml'; + + const XMLNS_IMAGE = 'http://www.google.com/schemas/sitemap-image/1.1'; + + /** + * @var bool + */ + protected $isHreflangSitemap; + + /** + * @var array + */ + protected static $attributes = [ + 'xmlns' => self::XMLNS, + 'xmlns:xhtml' => self::XMLNS_XHTML, + 'xmlns:image' => self::XMLNS_IMAGE, + ]; + + /** + * DefaultSitemapGenerator constructor. + * + * @param array $configuration + * @param string $plugin_id + * @param mixed $plugin_definition + * @param \Drupal\Core\Database\Connection $database + * @param \Drupal\Core\Extension\ModuleHandler $module_handler + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * @param \Drupal\Component\Datetime\Time $time + * @param \Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapWriter $sitemapWriter + */ + public function __construct( + array $configuration, + $plugin_id, + $plugin_definition, + Connection $database, + ModuleHandler $module_handler, + LanguageManagerInterface $language_manager, + Time $time, + SitemapWriter $sitemapWriter + ) { + parent::__construct( + $configuration, + $plugin_id, + $plugin_definition, + $database, + $module_handler, + $language_manager, + $time, + $sitemapWriter + ); + } + + public static function create( + ContainerInterface $container, + array $configuration, + $plugin_id, + $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('database'), + $container->get('module_handler'), + $container->get('language_manager'), + $container->get('datetime.time'), + $container->get('simple_sitemap.sitemap_writer') + ); + } + + /** + * Generates and returns a sitemap chunk. + * + * @param array $links + * All links with their multilingual versions and settings. + * + * @return string + * Sitemap chunk + */ + protected function getXml(array $links) { + $this->writer->openMemory(); + $this->writer->setIndent(TRUE); + $this->writer->startSitemapDocument(); + + // Add the XML stylesheet to document if enabled. + if ($this->settings['xsl']) { + $this->writer->writeXsl(); + } + + $this->writer->writeGeneratedBy(); + $this->writer->startElement('urlset'); + + // Add attributes to document. + $attributes = self::$attributes; + if (!$this->isHreflangSitemap()) { + unset($attributes['xmlns:xhtml']); + } + $sitemap_variant = $this->sitemapVariant; + $this->moduleHandler->alter('simple_sitemap_attributes', $attributes, $sitemap_variant); + foreach ($attributes as $name => $value) { + $this->writer->writeAttribute($name, $value); + } + + // Add URLs to document. + $sitemap_variant = $this->sitemapVariant; + $this->moduleHandler->alter('simple_sitemap_links', $links, $sitemap_variant); + foreach ($links as $link) { + + // Add each translation variant URL as location to the sitemap. + $this->writer->startElement('url'); + $this->writer->writeElement('loc', $link['url']); + + // If more than one language is enabled, add all translation variant URLs + // as alternate links to this location turning the sitemap into a hreflang + // sitemap. + if (isset($link['alternate_urls']) && $this->isHreflangSitemap()) { + foreach ($link['alternate_urls'] as $language_id => $alternate_url) { + $this->writer->startElement('xhtml:link'); + $this->writer->writeAttribute('rel', 'alternate'); + $this->writer->writeAttribute('hreflang', $language_id); + $this->writer->writeAttribute('href', $alternate_url); + $this->writer->endElement(); + } + } + + // Add lastmod if any. + if (isset($link['lastmod'])) { + $this->writer->writeElement('lastmod', $link['lastmod']); + } + + // Add changefreq if any. + if (isset($link['changefreq'])) { + $this->writer->writeElement('changefreq', $link['changefreq']); + } + + // Add priority if any. + if (isset($link['priority'])) { + $this->writer->writeElement('priority', $link['priority']); + } + + // Add images if any. + if (!empty($link['images'])) { + foreach ($link['images'] as $image) { + $this->writer->startElement('image:image'); + $this->writer->writeElement('image:loc', $image['path']); + $this->writer->endElement(); + } + } + + $this->writer->endElement(); + } + $this->writer->endElement(); + $this->writer->endDocument(); + + return $this->writer->outputMemory(); + } + + /** + * @return bool + */ + protected function isHreflangSitemap() { + return false; + if (NULL === $this->isHreflangSitemap) { + $this->isHreflangSitemap = count( + array_diff_key($this->languageManager->getLanguages(), + $this->settings['excluded_languages']) + ) > 1; + } + return $this->isHreflangSitemap; + } + +} diff --git a/src/Plugin/simple_sitemap/SitemapGenerator/VariantSitemapGenerator.php b/src/Plugin/simple_sitemap/SitemapGenerator/VariantSitemapGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..43ebfece1dc207f2f7579a80342c30036a370198 --- /dev/null +++ b/src/Plugin/simple_sitemap/SitemapGenerator/VariantSitemapGenerator.php @@ -0,0 +1,124 @@ +<?php + +namespace Drupal\rocketship_core\Plugin\simple_sitemap\SitemapGenerator; + +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorBase; +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapWriter; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Database\Connection; +use Drupal\Core\Extension\ModuleHandler; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Component\Datetime\Time; + +/** + * Class DefaultSitemapGenerator + * + * @package Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator + * + * @SitemapGenerator( + * id = "variant_generator", + * label = @Translation("Variant sitemap generator"), + * description = @Translation("Generates a sitemap that links to variants"), + * ) + */ +class VariantSitemapGenerator extends SitemapGeneratorBase { + + const XMLNS_XHTML = 'http://www.w3.org/1999/xhtml'; + + const XMLNS_IMAGE = 'http://www.google.com/schemas/sitemap-image/1.1'; + + /** + * @var array + */ + protected static $attributes = [ + 'xmlns' => self::XMLNS, + 'xmlns:xhtml' => self::XMLNS_XHTML, + 'xmlns:image' => self::XMLNS_IMAGE, + ]; + + /** + * Generates and returns a sitemap chunk. + * + * @param array $links + * All links with their multilingual versions and settings. + * + * @return string + * Sitemap chunk + */ + protected function getXml(array $links) { + $this->writer->openMemory(); + $this->writer->setIndent(TRUE); + $this->writer->startSitemapDocument(); + + // Add the XML stylesheet to document if enabled. + if ($this->settings['xsl']) { + $this->writer->writeXsl(); + } + + $this->writer->writeGeneratedBy(); + $this->writer->startElement('urlset'); + + // Add attributes to document. + $attributes = self::$attributes; + $sitemap_variant = $this->sitemapVariant; + $this->moduleHandler->alter('simple_sitemap_attributes', $attributes, $sitemap_variant); + foreach ($attributes as $name => $value) { + $this->writer->writeAttribute($name, $value); + } + + // Add URLs to document. + $sitemap_variant = $this->sitemapVariant; + $this->moduleHandler->alter('simple_sitemap_links', $links, $sitemap_variant); + foreach ($links as $link) { + + // Add each translation variant URL as location to the sitemap. + $this->writer->startElement('url'); + $this->writer->writeElement('loc', $link['url']); + + // If more than one language is enabled, add all translation variant URLs + // as alternate links to this location turning the sitemap into a hreflang + // sitemap. + if (isset($link['alternate_urls']) && $this->isHreflangSitemap()) { + foreach ($link['alternate_urls'] as $language_id => $alternate_url) { + $this->writer->startElement('xhtml:link'); + $this->writer->writeAttribute('rel', 'alternate'); + $this->writer->writeAttribute('hreflang', $language_id); + $this->writer->writeAttribute('href', $alternate_url); + $this->writer->endElement(); + } + } + + // Add lastmod if any. + if (isset($link['lastmod'])) { + $this->writer->writeElement('lastmod', $link['lastmod']); + } + + // Add changefreq if any. + if (isset($link['changefreq'])) { + $this->writer->writeElement('changefreq', $link['changefreq']); + } + + // Add priority if any. + if (isset($link['priority'])) { + $this->writer->writeElement('priority', $link['priority']); + } + + // Add images if any. + if (!empty($link['images'])) { + foreach ($link['images'] as $image) { + $this->writer->startElement('image:image'); + $this->writer->writeElement('image:loc', $image['path']); + $this->writer->endElement(); + } + } + + $this->writer->endElement(); + } + $this->writer->endElement(); + $this->writer->endDocument(); + + return $this->writer->outputMemory(); + } + + +} diff --git a/src/Plugin/simple_sitemap/SitemapType/PerLanguageSitemapType.php b/src/Plugin/simple_sitemap/SitemapType/PerLanguageSitemapType.php new file mode 100644 index 0000000000000000000000000000000000000000..2f8c964a85c4f9d8b5668e8e6ef94597e7ca60dd --- /dev/null +++ b/src/Plugin/simple_sitemap/SitemapType/PerLanguageSitemapType.php @@ -0,0 +1,26 @@ +<?php + +namespace Drupal\rocketship_core\Plugin\simple_sitemap\SitemapType; + +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapType\SitemapTypeBase; + +/** + * Class DefaultHreflangSitemapType + * + * @package Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapType + * + * @SitemapType( + * id = "per_language", + * label = @Translation("Per language"), + * description = @Translation("Generates a sitemap bundled per language."), + * sitemapGenerator = "per_language_generator", + * urlGenerators = { + * "custom", + * "entity", + * "entity_menu_link_content", + * "arbitrary", + * }, + * ) + */ +class PerLanguageSitemapType extends SitemapTypeBase { +} diff --git a/src/Plugin/simple_sitemap/SitemapType/VariantSitemapType.php b/src/Plugin/simple_sitemap/SitemapType/VariantSitemapType.php new file mode 100644 index 0000000000000000000000000000000000000000..85a43dd3828ba5dfd1a8d32793272e1bd291a278 --- /dev/null +++ b/src/Plugin/simple_sitemap/SitemapType/VariantSitemapType.php @@ -0,0 +1,23 @@ +<?php + +namespace Drupal\rocketship_core\Plugin\simple_sitemap\SitemapType; + +use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapType\SitemapTypeBase; + +/** + * Class DefaultHreflangSitemapType + * + * @package Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapType + * + * @SitemapType( + * id = "variants_type", + * label = @Translation("Variants type"), + * description = @Translation("Generates a sitemap that links to other variants."), + * sitemapGenerator = "variant_generator", + * urlGenerators = { + * "variant_generator", + * }, + * ) + */ +class VariantSitemapType extends SitemapTypeBase { +} diff --git a/src/Plugin/simple_sitemap/UrlGenerator/VariantUrlGenerator.php b/src/Plugin/simple_sitemap/UrlGenerator/VariantUrlGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..712974954377a061b217992df056795e7bda7120 --- /dev/null +++ b/src/Plugin/simple_sitemap/UrlGenerator/VariantUrlGenerator.php @@ -0,0 +1,60 @@ +<?php + +namespace Drupal\rocketship_core\Plugin\simple_sitemap\UrlGenerator; + +use Drupal\Core\Url; +use Drupal\simple_sitemap\EntityHelper; +use Drupal\simple_sitemap\Logger; +use Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorBase; +use Drupal\simple_sitemap\Simplesitemap; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Class EntityUrlGenerator. + * + * @package Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator + * + * @UrlGenerator( + * id = "variant_generator", + * label = @Translation("Variant URL generator"), + * description = @Translation("Generates URLs for variant sitemaps."), + * ) + */ +class VariantUrlGenerator extends UrlGeneratorBase { + + /** + * @inheritdoc + */ + public function getDataSets() { + + /** @var \Drupal\simple_sitemap\Simplesitemap $generator */ + $generator = \Drupal::service('simple_sitemap.generator'); + + + $variants = $generator->getSitemapManager() + ->getSitemapVariants('per_language'); + + foreach ($variants as $key => &$variant) { + $variant['key'] = $key; + } + + return $variants; + } + + /** + * @inheritdoc + */ + protected function processDataSet($data_set) { + $language = \Drupal::languageManager()->getLanguage($data_set['key']); + return [ + 'url' => Url::fromUserInput('/sitemap.xml', ['language' => $language]), + 'lastmod' => NULL, + 'priority' => NULL, + 'changefreq' => NULL, + 'images' => [], + 'meta' => [], + ]; + } +}