Skip to content

Commit

Permalink
Merge pull request #188 from quantcdn/feat/simple-sitemap-4.1-support
Browse files Browse the repository at this point in the history
Feat: Support simple sitemap 4.1
  • Loading branch information
steveworley authored Aug 25, 2023
2 parents 68797c1 + 7c7e341 commit 3c09b3e
Show file tree
Hide file tree
Showing 8 changed files with 472 additions and 146 deletions.
26 changes: 26 additions & 0 deletions modules/quant_sitemap/quant_sitemap.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* @file
* Install hooks for quant_sitemap.
*/

/**
* Implements hook_requirements().
*/
function quant_sitemap_requirements($phase) {
$requirements = [];
if ($phase != 'runtime') {
return $requirements;
}

[$available, $reason] = \Drupal::service('quant_sitemap.sitemap_manager')->isAvailable();

$requirements['quant_sitemap'] = [
'title' => t('Quant Sitemap'),
'severity' => $available ? REQUIREMENT_OK : REQUIREMENT_WARNING,
'description' => $reason,
];

return $requirements;
}
9 changes: 8 additions & 1 deletion modules/quant_sitemap/quant_sitemap.module
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ use Drupal\quant\Form\SeedForm;
* Implements hook_form_FORM_ID_alter().
*/
function quant_sitemap_form_quant_seed_form_alter(&$form, FormStateInterface $form_state) {
[$available, $reason] = \Drupal::service('quant_sitemap.sitemap_manager')->isAvailable();

if (!$available) {
\Drupal::messenger()->addError($reason);
}

$form['export_sitemap'] = [
'#type' => 'checkbox',
'#title' => t('Sitemaps'),
'#description' => t('Export all sitemap variants to quant'),
'#description' => t('Export all sitemap variants to Quant'),
'#default_value' => \Drupal::config(SeedForm::SETTINGS)->get('export_sitemap'),
'#disabled' => !$available,
];

$form['#submit'][] = 'quant_sitemap_settings_submit';
Expand Down
10 changes: 8 additions & 2 deletions modules/quant_sitemap/quant_sitemap.services.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
services:

quant_sitemap.collection_subscriber:
class: Drupal\quant_sitemap\EventSubscriber\CollectionSubscriber
quant_sitemap.sitemap_manager:
class: Drupal\quant_sitemap\SitemapManager
arguments:
- '@module_handler'
- '@entity_type.manager'
- '@extension.list.module'

quant_sitemap.collection_subscriber:
class: Drupal\quant_sitemap\EventSubscriber\CollectionSubscriber
arguments:
- '@quant_sitemap.sitemap_manager'
tags:
- { name: 'event_subscriber' }
81 changes: 6 additions & 75 deletions modules/quant_sitemap/src/EventSubscriber/CollectionSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
use Drupal\quant\Event\CollectRoutesEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\quant\Event\QuantCollectionEvents;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\quant_sitemap\SitemapManager;

/**
* Collection subscriber for Sitemap routes.
Expand All @@ -16,9 +15,9 @@ class CollectionSubscriber implements EventSubscriberInterface {
/**
* The core module handler.
*
* @var Drupal\Core\Extension\ModuleHandler
* @var Drupal\quant_sitemap\SitemapManager
*/
protected $moduleHandler;
protected $manager;

/**
* The entity type manager.
Expand All @@ -30,9 +29,8 @@ class CollectionSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public function __construct(ModuleHandler $module_handler, EntityTypeManager $entity_type_manager) {
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
public function __construct(SitemapManager $manager) {
$this->manager = $manager;
}

/**
Expand All @@ -43,81 +41,14 @@ public static function getSubscribedEvents() {
return $events;
}

/**
* Get the simple sitemap manager.
*
* @return Drupal\simple_sitemap\SimplesitemapManager
* The sitemap manager.
*/
public function getSitemapManager() {
return \Drupal::service('simple_sitemap.manager');
}

/**
* The entity type manager.
*
* @return Drupal\Core\Entity\EntityTypeManager
* The entity type manager.
*/
public function getEntityTypeManager() {
return $this->entityTypeManager;
}

/**
* Simple sitemap support.
*
* Simple sitemap allows you to define accessible sitemap routes. This
* is always prefixed by the variant ID. As this is not a standard
* content entity we need to use the provided manager to load the values.
*
* @return array
* A list of routes that sitemaps are accessible by.
*/
public function getSimpleSitemapItems() : array {
$items = ['/sitemap.xml'];
foreach ($this->getSitemapManager()->getSitemapVariants() as $variant => $def) {
$items[] = "/$variant/sitemap.xml";
}
return $items;
}

/**
* XMLSitemap support.
*
* XMLSitemap only allows base level sitemaps with language prefixes.
* Each enabled language context can only have one sitemap, the admin
* UI returns an error if you try to double up.
*
* @return array
* A list of routes that sitemaps are accessible by.
*/
public function getXmlsitemapItems() : array {
$items = [];
$sitemaps = $this->getEntityTypeManager()->getStorage('xmlsitemap')->loadMultiple();
foreach ($sitemaps as $sitemap) {
$items[] = "/{$sitemap->language()->getId()}/sitemap.xml";
}
return $items;
}

/**
* Collect the sitemap routes.
*/
public function collectRoutes(CollectRoutesEvent $event) {
if (empty($event->getFormState()->getValue('export_sitemap'))) {
return;
}

$items = [];

if ($this->moduleHandler->moduleExists('simple_sitemap')) {
$items = $this->getSimpleSitemapItems();
}
elseif ($this->moduleHandler->moduleExists('xmlsitemap')) {
$items = $this->getXmlsitemapItems();
}

foreach ($items as $route) {
foreach ($this->manager->getSitemaps() as $route) {
$event->queueItem(['route' => $route]);
}
}
Expand Down
201 changes: 201 additions & 0 deletions modules/quant_sitemap/src/SitemapManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<?php

namespace Drupal\quant_sitemap;

use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
* Sitemap manager for Quant Sitemap.
*/
class SitemapManager {

use StringTranslationTrait;

const SIMPLE_SITEMAP_MINIMUM_VERSION = "4.1.6";

const XMLSITEMAP_MINIMUM_VERSION = "8.x-1.5";

/**
* The core module handler.
*
* @var Drupal\Core\Extension\ModuleHandler
*/
protected $moduleHandler;

/**
* The entity type manager.
*
* @var Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;

/**
* The list of enabled modules.
*
* @var Drupal\Core\Extension\ModuleExtensionList
*/
protected $moduleList;

/**
* Construct the SitemapManager.
*/
public function __construct(ModuleHandler $module_handler, EntityTypeManager $entity_type_manager, ModuleExtensionList $modules) {
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
$this->moduleList = $modules;
}

/**
* Getter for module handler property.
*
* @return Drupal\Core\Extension\ModuleHandler
* The module handler.
*/
public function getModuleHandler() {
return $this->moduleHandler;
}

/**
* Getter for module list.
*
* @return Drupal\Core\Extension\ModuleExtensionList
* The module extension list.
*/
public function getModuleList() {
return $this->moduleList;
}

/**
* Getter for entity type manager.
*
* @return Drupal\Core\Entity\EntityTypeManager
* The entity type manager.
*/
public function getEntityTypeManager() {
return $this->entityTypeManager;
}

/**
* Determine if the sitemap integration is available for this site.
*
* @return array
* The status and a reason for it not being available.
*/
public function isAvailable() : array {
$reason = $this->t('quant_sitemap requires simple_sitemap or xmlsitemap');

if ($this->getModuleHandler()->moduleExists('simple_sitemap')) {
$module = $this->getModuleList()->get('simple_sitemap');
if (!empty($module) && version_compare($module->info['version'], self::SIMPLE_SITEMAP_MINIMUM_VERSION, '>=')) {
return [
TRUE,
$this->t('simple_sitemap is installed at a supported version (@ver)', [
'@ver' => $module->info['version'],
]),
];
}
else {
$reason = $this->t('quant_sitemap requires simple_sitemap to be version >= @ver', [
'@ver' => self::SIMPLE_SITEMAP_MINIMUM_VERSION,
]);
}
}

if ($this->moduleHandler->moduleExists('xmlsitemap')) {
$module = $this->moduleList->get('xmlsitemap');
if (!empty($module) && version_compare($module->info['version'], self::XMLSITEMAP_MINIMUM_VERSION, '>=')) {
return [
TRUE,
$this->t('xmlsitemap is installed at a supported version (@ver)', [
'@ver' => $module->info['version'],
]),
];
}
else {
$reason = $this->t('quant_sitemap requires xmlsitemap to be version >= @ver', [
'@ver' => self::XMLSITEMAP_MINIMUM_VERSION,
]);
}
}

return [FALSE, $reason];
}

/**
* Get configured sitemaps based on available sources.
*
* @return array
* A list of sitemap paths.
*/
public function getSitemaps() : array {
[$available] = $this->isAvailable();
if (!$available) {
return [];
}

if ($this->getModuleHandler()->moduleExists('simple_sitemap')) {
return $this->getSimpleSitemaps();
}

if ($this->getModuleHandler()->moduleExists('xmlsitemap')) {
return $this->getXmlSitemaps();
}

return [];
}

/**
* Get the simple sitemap manager.
*
* @return Drupal\simple_sitemap\Manager\EntityManager
* The sitemap manager.
*/
protected function getSitemapManager() {
return \Drupal::service('simple_sitemap.entity_manager');
}

/**
* Get sitemap items from simple_sitemap.
*
* @return array
* A list of sitemap items.
*/
protected function getSimpleSitemaps() : array {
$items = ['/sitemap.xml', '/sitemap_generator/default/sitemap.xsl'];
foreach ($this->getSitemapManager()->getAllBundleSettings() as $variant => $def) {
if ($variant == "default") {
continue;
}
$items[] = "/$variant/sitemap.xml";
}
return $items;
}

/**
* Get sitemap items from xmlsitemap.
*
* @return array
* A list of sitemap paths.
*/
protected function getXmlSitemaps() : array {
$items = ['/sitemap.xml', '/sitemap.xsl'];
$sitemaps = $this->getEntityTypeManager()->getStorage('xmlsitemap')->loadMultiple();
$lang_code = \Drupal::service('language.default')->get()->getId();

foreach ($sitemaps as $sitemap) {
$context = $sitemap->getContext();
if (empty($context['language']) || $context['language'] == $lang_code) {
// Default langcode is always served via sitemap.xml as a hard coded
// link from xmlsitemap and this will result in a 404 — so we just
// skip the default langauge for now.
continue;
}
$items[] = "/{$context['language']}/sitemap.xml";
}
return $items;
}

}
Loading

0 comments on commit 3c09b3e

Please sign in to comment.