EntityMenuLinkContentUrlGenerator.php 7.19 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator;

5
use Drupal\Core\Extension\ModuleHandler;
6 7 8
use Drupal\simple_sitemap\EntityHelper;
use Drupal\simple_sitemap\Logger;
use Drupal\simple_sitemap\Simplesitemap;
9
use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorManager;
10 11 12 13 14 15
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Menu\MenuLinkTree;

16 17 18 19 20 21 22 23 24
/**
 * Class EntityMenuLinkContentUrlGenerator
 * @package Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator
 *
 * @UrlGenerator(
 *   id = "entity_menu_link_content",
 *   title = @Translation("Menu link URL generator"),
 *   description = @Translation("Generates menu link URLs by overriding the 'entity' URL generator."),
 *   settings = {
25
 *     "overrides_entity_type" = "menu_link_content",
26 27 28
 *   },
 * )
 */
29 30 31 32 33 34 35
class EntityMenuLinkContentUrlGenerator extends UrlGeneratorBase {

  /**
   * @var \Drupal\Core\Menu\MenuLinkTree
   */
  protected $menuLinkTree;

36 37 38 39 40
  /**
   * @var \Drupal\Core\Extension\ModuleHandler
   */
  protected $moduleHandler;

41 42 43
  /**
   * EntityMenuLinkContentUrlGenerator constructor.
   * @param array $configuration
44 45
   * @param $plugin_id
   * @param $plugin_definition
46
   * @param \Drupal\simple_sitemap\Simplesitemap $generator
47
   * @param \Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorManager $sitemap_generator_manager
48 49 50 51 52
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * @param \Drupal\simple_sitemap\Logger $logger
   * @param \Drupal\simple_sitemap\EntityHelper $entityHelper
   * @param \Drupal\Core\Menu\MenuLinkTree $menu_link_tree
53
   * @param \Drupal\Core\Extension\ModuleHandler $module_handler
54 55 56 57 58 59
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    Simplesitemap $generator,
60
    SitemapGeneratorManager $sitemap_generator_manager,
61 62 63 64
    LanguageManagerInterface $language_manager,
    EntityTypeManagerInterface $entity_type_manager,
    Logger $logger,
    EntityHelper $entityHelper,
65 66
    MenuLinkTree $menu_link_tree,
    ModuleHandler $module_handler
67 68 69 70 71 72
  ) {
    parent::__construct(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $generator,
73
      $sitemap_generator_manager,
74 75 76 77 78 79
      $language_manager,
      $entity_type_manager,
      $logger,
      $entityHelper
    );
    $this->menuLinkTree = $menu_link_tree;
80
    $this->moduleHandler = $module_handler;
81 82 83 84 85 86 87 88 89 90 91 92
  }

  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('simple_sitemap.generator'),
93
      $container->get('plugin.manager.simple_sitemap.sitemap_generator'),
94 95 96 97
      $container->get('language_manager'),
      $container->get('entity_type.manager'),
      $container->get('simple_sitemap.logger'),
      $container->get('simple_sitemap.entity_helper'),
98 99
      $container->get('menu.link_tree'),
      $container->get('module_handler')
100 101
    );
  }
102 103 104 105 106

  /**
   * @inheritdoc
   */
  public function getDataSets() {
107
    $data_sets = [];
108
    $bundle_settings = $this->generator->getBundleSettings();
109 110 111 112 113 114 115 116 117 118 119 120 121
    $entity_type_name = 'menu_link_content';
    if (!empty($bundle_settings[$entity_type_name])) {
      foreach ($bundle_settings[$entity_type_name] as $bundle_name => $settings) {
        $bundle_name_alterable = $bundle_name;

        $this->moduleHandler->alter('simple_sitemap_bundle_settings', $settings, $entity_type_name, $bundle_name_alterable);

        // Skip this bundle if it is to be generated in a different sitemap variant.
        if (NULL !== $this->sitemapVariant && isset($settings['variant'])
          && $settings['variant'] !== $this->sitemapVariant) {
          continue;
        }

122
        if ($settings['index']) {
123
          $data_sets[] = $bundle_name;
124 125 126 127
        }
      }
    }

128
    return $data_sets;
129 130 131 132 133
  }

  /**
   * @inheritdoc
   */
134
  protected function processDataSet($link) {
135

136 137 138
    if (!$link->isEnabled()) {
      return FALSE;
    }
139

140
    $url_object = $link->getUrlObject();
141

142
    // Do not include external paths.
143
    if ($url_object->isExternal()) {
144 145 146
      return FALSE;
    }

147 148 149 150
    // If not a menu_link_content link, use bundle settings.
    $meta_data = $link->getMetaData();
    if (empty($meta_data['entity_id'])) {
      $entity_settings = $this->generator->getBundleSettings('menu_link_content', $link->getMenuName());
151 152
    }

153 154 155
    // If menu link is of entity type menu_link_content, take under account its entity override.
    else {
      $entity_settings = $this->generator->getEntityInstanceSettings('menu_link_content', $meta_data['entity_id']);
156

157 158 159
      if (empty($entity_settings['index'])) {
        return FALSE;
      }
160 161
    }

162 163 164 165 166 167 168 169 170 171 172 173
    // There can be internal paths that are not rooted, like 'base:/path'.
    if ($url_object->isRouted()) {
     $path = $url_object->getInternalPath();
    }
    else { // Handle base scheme.
      if (strpos($uri = $url_object->toUriString(), 'base:/') === 0 ) {
        $path = $uri[6] === '/' ? substr($uri, 7) : substr($uri, 6);
      }
      else { // Handle unforeseen schemes.
        $path = $uri;
      }
    }
174 175

    // Do not include paths that have been already indexed.
176
    if ($this->settings['remove_duplicates'] && $this->pathProcessed($path)) {
177 178 179 180 181
      return FALSE;
    }

    $url_object->setOption('absolute', TRUE);

182 183 184
    $entity = $this->entityHelper->getEntityFromUrlObject($url_object);

    $path_data = [
185
      'url' => $url_object,
186 187 188
      'lastmod' => !empty($entity) && method_exists($entity, 'getChangedTime')
        ? date_iso8601($entity->getChangedTime())
        : NULL,
189 190
      'priority' => isset($entity_settings['priority']) ? $entity_settings['priority'] : NULL,
      'changefreq' => !empty($entity_settings['changefreq']) ? $entity_settings['changefreq'] : NULL,
191 192
      'images' => !empty($entity_settings['include_images']) && !empty($entity)
        ? $this->getImages($entity->getEntityTypeId(), $entity->id())
193 194 195 196 197 198 199
        : [],

      // Additional info useful in hooks.
      'meta' => [
        'path' => $path,
      ]
    ];
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    if (!empty($entity)) {
      $path_data['meta']['entity_info'] = [
        'entity_type' => $entity->getEntityTypeId(),
        'id' => $entity->id(),
      ];
    }

    return $path_data;
  }

  /**
   * @inheritdoc
   */
  protected function getBatchIterationElements($menu_name) {

    // Retrieve the expanded tree.
    $tree = $this->menuLinkTree->load($menu_name, new MenuTreeParameters());
    $tree = $this->menuLinkTree->transform($tree, [['callable' => 'menu.default_tree_manipulators:generateIndexAndSort']]);

    $elements = [];
    foreach ($tree as $i => $item) {
      $elements[] = $item->link;
    }
    $elements = array_values($elements);

225 226
    if ($this->batchOperationNeedsInitialization()) {
      $this->initializeBatchOperation(count($elements));
227 228
    }

229
    return $this->isDrupalBatch()
230
      ? array_slice($elements, $this->context['sandbox']['progress'], $this->settings['batch_process_limit'])
231
      : $elements;
232
  }
233

234
}