EntityMenuLinkContentUrlGenerator.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. namespace Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator;
  3. use Drupal\simple_sitemap\EntityHelper;
  4. use Drupal\simple_sitemap\Logger;
  5. use Drupal\simple_sitemap\Simplesitemap;
  6. use Drupal\Core\Language\LanguageManagerInterface;
  7. use Drupal\Core\Entity\EntityTypeManagerInterface;
  8. use Drupal\Core\Menu\MenuTreeParameters;
  9. use Symfony\Component\DependencyInjection\ContainerInterface;
  10. use Drupal\Core\Menu\MenuLinkTree;
  11. use Drupal\Core\Menu\MenuLinkBase;
  12. /**
  13. * Class EntityMenuLinkContentUrlGenerator
  14. * @package Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator
  15. *
  16. * @UrlGenerator(
  17. * id = "entity_menu_link_content",
  18. * label = @Translation("Menu link URL generator"),
  19. * description = @Translation("Generates menu link URLs by overriding the 'entity' URL generator."),
  20. * settings = {
  21. * "overrides_entity_type" = "menu_link_content",
  22. * },
  23. * )
  24. *
  25. * @todo Find way of adding just a menu link item pointer to the queue instead of whole object.
  26. */
  27. class EntityMenuLinkContentUrlGenerator extends EntityUrlGeneratorBase {
  28. /**
  29. * @var \Drupal\Core\Menu\MenuLinkTree
  30. */
  31. protected $menuLinkTree;
  32. /**
  33. * EntityMenuLinkContentUrlGenerator constructor.
  34. * @param array $configuration
  35. * @param $plugin_id
  36. * @param $plugin_definition
  37. * @param \Drupal\simple_sitemap\Simplesitemap $generator
  38. * @param \Drupal\simple_sitemap\Logger $logger
  39. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
  40. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
  41. * @param \Drupal\simple_sitemap\EntityHelper $entityHelper
  42. * @param \Drupal\Core\Menu\MenuLinkTree $menu_link_tree
  43. */
  44. public function __construct(
  45. array $configuration,
  46. $plugin_id,
  47. $plugin_definition,
  48. Simplesitemap $generator,
  49. Logger $logger,
  50. LanguageManagerInterface $language_manager,
  51. EntityTypeManagerInterface $entity_type_manager,
  52. EntityHelper $entityHelper,
  53. MenuLinkTree $menu_link_tree
  54. ) {
  55. parent::__construct(
  56. $configuration,
  57. $plugin_id,
  58. $plugin_definition,
  59. $generator,
  60. $logger,
  61. $language_manager,
  62. $entity_type_manager,
  63. $entityHelper
  64. );
  65. $this->menuLinkTree = $menu_link_tree;
  66. }
  67. public static function create(
  68. ContainerInterface $container,
  69. array $configuration,
  70. $plugin_id,
  71. $plugin_definition) {
  72. return new static(
  73. $configuration,
  74. $plugin_id,
  75. $plugin_definition,
  76. $container->get('simple_sitemap.generator'),
  77. $container->get('simple_sitemap.logger'),
  78. $container->get('language_manager'),
  79. $container->get('entity_type.manager'),
  80. $container->get('simple_sitemap.entity_helper'),
  81. $container->get('menu.link_tree')
  82. );
  83. }
  84. /**
  85. * @inheritdoc
  86. */
  87. public function getDataSets() {
  88. $data_sets = [];
  89. $bundle_settings = $this->generator
  90. ->setVariants($this->sitemapVariant)
  91. ->getBundleSettings();
  92. if (!empty($bundle_settings['menu_link_content'])) {
  93. foreach ($bundle_settings['menu_link_content'] as $bundle_name => $bundle_settings) {
  94. if (!empty($bundle_settings['index'])) {
  95. // Retrieve the expanded tree.
  96. $tree = $this->menuLinkTree->load($bundle_name, new MenuTreeParameters());
  97. $tree = $this->menuLinkTree->transform($tree, [
  98. ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
  99. ['callable' => 'menu.default_tree_manipulators:flatten'],
  100. ]);
  101. foreach ($tree as $i => $item) {
  102. $data_sets[] = $item->link;
  103. }
  104. }
  105. }
  106. }
  107. return $data_sets;
  108. }
  109. /**
  110. * @inheritdoc
  111. *
  112. * @todo Check if menu link has not been deleted after the queue has been built.
  113. */
  114. protected function processDataSet($data_set) {
  115. /** @var MenuLinkBase $data_set */
  116. if (!$data_set->isEnabled()) {
  117. return FALSE;
  118. }
  119. $url_object = $data_set->getUrlObject();
  120. // Do not include external paths.
  121. if ($url_object->isExternal()) {
  122. return FALSE;
  123. }
  124. // If not a menu_link_content link, use bundle settings.
  125. $meta_data = $data_set->getMetaData();
  126. if (empty($meta_data['entity_id'])) {
  127. $entity_settings = $this->generator
  128. ->setVariants($this->sitemapVariant)
  129. ->getBundleSettings('menu_link_content', $data_set->getMenuName());
  130. }
  131. // If menu link is of entity type menu_link_content, take under account its entity override.
  132. else {
  133. $entity_settings = $this->generator->getEntityInstanceSettings('menu_link_content', $meta_data['entity_id']);
  134. if (empty($entity_settings['index'])) {
  135. return FALSE;
  136. }
  137. }
  138. // There can be internal paths that are not rooted, like 'base:/path'.
  139. if ($url_object->isRouted()) {
  140. $path = $url_object->getInternalPath();
  141. }
  142. else { // Handle base scheme.
  143. if (strpos($uri = $url_object->toUriString(), 'base:/') === 0 ) {
  144. $path = $uri[6] === '/' ? substr($uri, 7) : substr($uri, 6);
  145. }
  146. else { // Handle unforeseen schemes.
  147. $path = $uri;
  148. }
  149. }
  150. $url_object->setOption('absolute', TRUE);
  151. $entity = $this->entityHelper->getEntityFromUrlObject($url_object);
  152. $path_data = [
  153. 'url' => $url_object,
  154. 'lastmod' => !empty($entity) && method_exists($entity, 'getChangedTime')
  155. ? date_iso8601($entity->getChangedTime())
  156. : NULL,
  157. 'priority' => isset($entity_settings['priority']) ? $entity_settings['priority'] : NULL,
  158. 'changefreq' => !empty($entity_settings['changefreq']) ? $entity_settings['changefreq'] : NULL,
  159. 'images' => !empty($entity_settings['include_images']) && !empty($entity)
  160. ? $this->getImages($entity->getEntityTypeId(), $entity->id())
  161. : [],
  162. // Additional info useful in hooks.
  163. 'meta' => [
  164. 'path' => $path,
  165. ]
  166. ];
  167. if (!empty($entity)) {
  168. $path_data['meta']['entity_info'] = [
  169. 'entity_type' => $entity->getEntityTypeId(),
  170. 'id' => $entity->id(),
  171. ];
  172. }
  173. return $path_data;
  174. }
  175. }