Simplesitemap.php 18.5 KB
Newer Older
1 2
<?php

Pawel G's avatar
Pawel G committed
3
namespace Drupal\simple_sitemap;
4

5
use Drupal\Core\Entity\ContentEntityTypeInterface;
6
use Drupal\simple_sitemap\Form\FormHelper;
Pawel G's avatar
Pawel G committed
7 8 9
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\PathValidator;
10

11
/**
Pawel G's avatar
Pawel G committed
12 13
 * Class Simplesitemap.
 *
Pawel G's avatar
Pawel G committed
14
 * @package Drupal\simple_sitemap
15 16 17
 */
class Simplesitemap {

18
  private $sitemapGenerator;
19 20
  private $configFactory;
  private $db;
21
  private $entityQuery;
22
  private $entityTypeManager;
23
  private $pathValidator;
24 25
  private static $allowed_link_settings = [
    'entity' => ['index', 'priority'],
Pawel G's avatar
Pawel G committed
26
    'custom' => ['priority'],
27
  ];
28

29 30
  /**
   * Simplesitemap constructor.
Pawel G's avatar
Pawel G committed
31
   *
32
   * @param $sitemapGenerator
33
   * @param $configFactoryInterface
34
   * @param $database
35
   * @param $entityQuery
36
   * @param $entityTypeManager
37 38
   * @param $pathValidator
   * @param $dateFormatter
39
   */
40
  public function __construct(
Pawel G's avatar
Pawel G committed
41
    SitemapGenerator $sitemapGenerator,
42
    $configFactoryInterface,
Pawel G's avatar
Pawel G committed
43
    Connection $database,
44
    $entityQuery,
Pawel G's avatar
Pawel G committed
45 46
    EntityTypeManagerInterface $entityTypeManager,
    PathValidator $pathValidator,
47
    $dateFormatter
48 49
  ) {
    $this->sitemapGenerator = $sitemapGenerator;
50 51
    $this->configFactory = $configFactoryInterface;
    $this->db = $database;
52
    $this->entityQuery = $entityQuery;
53
    $this->entityTypeManager = $entityTypeManager;
54
    $this->pathValidator = $pathValidator;
55
    $this->dateFormatter = $dateFormatter;
56 57
  }

58
  /**
59
   * Fetches all sitemap chunks indexed by chunk ID.
Pawel G's avatar
Pawel G committed
60
   *
61
   * @return string
Pawel G's avatar
Pawel G committed
62
   */
Pawel G's avatar
Pawel G committed
63
  private function fetchSitemapChunks() {
64
    return $this->db
65 66 67 68
      ->query("SELECT * FROM {simple_sitemap}")
      ->fetchAllAssoc('id');
  }

69 70
  /**
   * Enables sitemap support for an entity type. Enabled entity types show
71 72
   * sitemap settings on their bundle setting forms. If an enabled entity type
   * features bundles (e.g. 'node'), it needs to be set up with
73 74 75
   * setBundleSettings() as well.
   *
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
76
   *   Entity type id like 'node'.
77
   *
Pawel G's avatar
Pawel G committed
78
   * @return $this
79 80
   */
  public function enableEntityType($entity_type_id) {
81 82 83 84
    $enabled_entity_types = $this->getSetting('enabled_entity_types');
    if (!in_array($entity_type_id, $enabled_entity_types)) {
      $enabled_entity_types[] = $entity_type_id;
      $this->saveSetting('enabled_entity_types', $enabled_entity_types);
85
    }
Pawel G's avatar
Pawel G committed
86
    return $this;
87 88 89 90 91 92 93 94
  }

  /**
   * Disables sitemap support for an entity type. Disabling support for an
   * entity type deletes its sitemap settings permanently and removes sitemap
   * settings from entity forms.
   *
   * @param string $entity_type_id
95
   *  Entity type id like 'node'.
96
   *
Pawel G's avatar
Pawel G committed
97
   * @return $this
98 99
   */
  public function disableEntityType($entity_type_id) {
100 101 102 103 104 105 106 107 108 109 110 111 112

    // Updating settings.
    $enabled_entity_types = $this->getSetting('enabled_entity_types');
    if (($key = array_search($entity_type_id, $enabled_entity_types)) !== FALSE) {
      unset ($enabled_entity_types[$key]);
      array_values($enabled_entity_types);
      $this->saveSetting('enabled_entity_types', $enabled_entity_types);
    }

    // Deleting inclusion settings.
    $config_names = $this->configFactory->listAll("simple_sitemap.bundle_settings.$entity_type_id");
    foreach($config_names as $config_name) {
      $this->configFactory->getEditable($config_name)->delete();
113
    }
114 115 116

    // Deleting entity overrides.
    $this->removeEntityInstanceSettings($entity_type_id);
Pawel G's avatar
Pawel G committed
117
    return $this;
118 119 120
  }

  /**
Pawel G's avatar
Pawel G committed
121
   * Sets sitemap settings for a non-bundle entity type (e.g. user) or a bundle
122 123 124
   * of an entity type (e.g. page).
   *
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
125
   *   Entity type id like 'node' the bundle belongs to.
126
   * @param string $bundle_name
Pawel G's avatar
Pawel G committed
127
   *   Name of the bundle. NULL if entity type has no bundles.
128
   * @param array $settings
Pawel G's avatar
Pawel G committed
129 130
   *   An array of sitemap settings for this bundle/entity type.
   *   Example: ['index' => TRUE, 'priority' => 0.5].
Pawel G's avatar
Pawel G committed
131 132
   *
   * @return $this
133 134
   */
  public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings) {
135

136
    $bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
137

138 139 140 141 142 143 144 145 146 147
    foreach($settings as $setting_key => $setting) {
      if ($setting_key == 'index') {
        $setting = intval($setting);
      }
      $this->configFactory
        ->getEditable("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name")
        ->set($setting_key, $setting)
        ->save();
    }
    //todo: Use addLinkSettings()?
148 149

    // Delete entity overrides which are identical to new bundle setting.
150 151 152 153 154 155 156 157 158
    $sitemap_entity_types = $this->getSitemapEntityTypes();
    if (isset($sitemap_entity_types[$entity_type_id])) {
      $entity_type = $sitemap_entity_types[$entity_type_id];
      $keys = $entity_type->getKeys();
      $keys['bundle'] = $entity_type_id == 'menu_link_content' ? 'menu_name' : $keys['bundle'];

      $query = $this->entityQuery->get($entity_type_id);
      if (!$this->entityTypeIsAtomic($entity_type_id)) {
        $query->condition($keys['bundle'], $bundle_name);
159
      }
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
      $entity_ids = $query->execute();

      $bundle_settings = $this->configFactory
        ->get("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name");

      $query = $this->db->select('simple_sitemap_entity_overrides', 'o')
        ->fields('o', ['id', 'inclusion_settings'])
        ->condition('o.entity_type', $entity_type_id);
      if (!empty($entity_ids)) {
        $query->condition('o.entity_id', $entity_ids, 'IN');
      }
      $results = $query->execute()
        ->fetchAll();

      foreach($results as $result) {
        $delete = TRUE;
        $instance_settings = unserialize($result->inclusion_settings);
        foreach ($instance_settings as $setting_key => $instance_setting) {
          if ($instance_setting != $bundle_settings->get($setting_key)) {
            $delete = FALSE;
            break;
          }
        }
        if ($delete) {
          $this->db->delete('simple_sitemap_entity_overrides')
            ->condition('id', $result->id)
            ->execute();
        }
188 189
      }
    }
190 191 192
    else {
      //todo: log error
    }
Pawel G's avatar
Pawel G committed
193
    return $this;
194 195
  }

196
  /**
197 198
   * Gets sitemap settings for an entity bundle, a non-bundle entity type or for
   * all entity types and their bundles.
199
   *
200 201 202
   * @param string|null $entity_type_id
   *  If set to null, sitemap settings for all entity types and their bundles
   *  are fetched.
203 204 205
   * @param string|null $bundle_name
   *
   * @return array|false
206 207
   *  Array of sitemap settings or array of entity types with their settings.
   *  False if entity type does not exist.
208
   */
209 210 211 212 213 214 215
  public function getBundleSettings($entity_type_id = NULL, $bundle_name = NULL) {
    if (!is_null($entity_type_id)) {
      $bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
      $settings = $this->configFactory
        ->get("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name")
        ->get();
      $bundle_settings = !empty($settings) ? $settings : FALSE;
216
    }
217 218 219 220 221 222 223 224 225 226
    else {
      $config_names = $this->configFactory->listAll("simple_sitemap.bundle_settings");
      $bundle_settings = [];
      foreach($config_names as $config_name) {
        $config_name_parts = explode('.', $config_name);
        $bundle_settings[$config_name_parts[2]][$config_name_parts[3]]
          = $this->configFactory->get($config_name)->get();
      }
    }
    return $bundle_settings;
227 228
  }

Pawel G's avatar
Pawel G committed
229 230 231
  /**
   * Overrides entity bundle/entity type sitemap settings for a single entity.
   *
Pawel G's avatar
Pawel G committed
232 233 234
   * @param string $entity_type_id
   * @param int $id
   * @param array $settings
Pawel G's avatar
Pawel G committed
235
   *
Pawel G's avatar
Pawel G committed
236 237
   * @return $this
   */
238
  public function setEntityInstanceSettings($entity_type_id, $id, $settings) {
239

240 241
    $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($id);
    $bundle_name = $this->getEntityInstanceBundleName($entity);
242 243 244 245 246
    $bundle_settings = $this->configFactory
      ->get("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name")
      ->get();

    if (!empty($bundle_settings)) {
247 248 249 250

      // Check if overrides are different from bundle setting before saving.
      $override = FALSE;
      foreach ($settings as $key => $setting) {
251
        if ($setting != $bundle_settings[$key]) {
252 253 254 255
          $override = TRUE;
          break;
        }
      }
Pawel G's avatar
Pawel G committed
256 257
      // Save overrides for this entity if something is different.
      if ($override) {
258 259 260 261 262 263 264 265 266 267
        $this->db->merge('simple_sitemap_entity_overrides')
          ->key([
            'entity_type' => $entity_type_id,
            'entity_id' => $id])
          ->fields([
            'entity_type' => $entity_type_id,
            'entity_id' => $id,
            'inclusion_settings' => serialize($settings),
          ])
          ->execute();
268
      }
Pawel G's avatar
Pawel G committed
269 270
      // Else unset override.
      else {
271
        $this->removeEntityInstanceSettings($entity_type_id, $id);
272
      }
273 274 275
    }
    else {
      //todo: log error
276
    }
Pawel G's avatar
Pawel G committed
277
    return $this;
278 279
  }

Pawel G's avatar
Pawel G committed
280
  /**
281 282
   * Gets sitemap settings for an entity instance which overrides the sitemap
   * settings of its bundle.
Pawel G's avatar
Pawel G committed
283
   *
Pawel G's avatar
Pawel G committed
284
   * @param string $entity_type_id
285
   * @param int $id
Pawel G's avatar
Pawel G committed
286
   *
287
   * @return array
Pawel G's avatar
Pawel G committed
288
   */
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
  public function getEntityInstanceSettings($entity_type_id, $id) {
    $results = $this->db->select('simple_sitemap_entity_overrides', 'o')
      ->fields('o', ['inclusion_settings'])
      ->condition('o.entity_type', $entity_type_id)
      ->condition('o.entity_id', $id)
      ->execute()
      ->fetchField();

    if (!empty($results)) {
      return unserialize($results);
    }
    else {
      $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($id);
      $bundle_name = $this->getEntityInstanceBundleName($entity);
      return $this->getBundleSettings($entity_type_id, $bundle_name);
304 305 306
    }
  }

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
  /**
   * Removes sitemap settings for an entity that overrides the sitemap settings
   * of its bundle.
   *
   * @param string $entity_type_id
   * @param string|null $entity_ids
   *
   * @return $this
   */
  public function removeEntityInstanceSettings($entity_type_id, $entity_ids = NULL) {
    $query = $this->db->delete('simple_sitemap_entity_overrides')
      ->condition('entity_type', $entity_type_id);
    if (!is_null($entity_ids)) {
      $entity_ids = !is_array($entity_ids) ? [$entity_ids] : $entity_ids;
      $query->condition('entity_id', $entity_ids, 'IN');
    }
    $query->execute();
    return $this;
  }

Pawel G's avatar
Pawel G committed
327 328 329 330
  /**
   * Checks if an entity bundle (or a non-bundle entity type) is set to be
   * indexed in the sitemap settings.
   *
331 332
   * @param string $entity_type_id
   * @param string|null $bundle_name
Pawel G's avatar
Pawel G committed
333
   *
Pawel G's avatar
Pawel G committed
334 335
   * @return bool
   */
336
  public function bundleIsIndexed($entity_type_id, $bundle_name = NULL) {
337 338 339 340
    $settings = $this->getBundleSettings($entity_type_id, $bundle_name);
    return !empty($settings['index']);
  }

Pawel G's avatar
Pawel G committed
341 342 343
  /**
   * Checks if an entity type is enabled in the sitemap settings.
   *
344
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
345
   *
Pawel G's avatar
Pawel G committed
346 347
   * @return bool
   */
348
  public function entityTypeIsEnabled($entity_type_id) {
349
    return in_array($entity_type_id, $this->getSetting('enabled_entity_types', []));
350 351
  }

Pawel G's avatar
Pawel G committed
352
  /**
353
   * Stores a custom path along with its sitemap settings to configuration.
Pawel G's avatar
Pawel G committed
354
   *
Pawel G's avatar
Pawel G committed
355 356
   * @param string $path
   * @param array $settings
Pawel G's avatar
Pawel G committed
357
   *
Pawel G's avatar
Pawel G committed
358
   * @return $this
Pawel G's avatar
Pawel G committed
359
   */
360
  public function addCustomLink($path, $settings) {
Pawel G's avatar
Pawel G committed
361 362 363 364 365 366 367 368
    if (!$this->pathValidator->isValid($path)) {
      // todo: log error.
      return $this;
    }
    if ($path[0] != '/') {
      // todo: log error.
      return $this;
    }
Pawel G's avatar
Pawel G committed
369

370
    $custom_links = $this->getCustomLinks();
Pawel G's avatar
Pawel G committed
371
    foreach ($custom_links as $key => $link) {
372 373 374 375 376 377 378
      if ($link['path'] == $path) {
        $link_key = $key;
        break;
      }
    }
    $link_key = isset($link_key) ? $link_key : count($custom_links);
    $custom_links[$link_key]['path'] = $path;
379 380 381
    $this->addLinkSettings('custom', $settings, $custom_links[$link_key]); //todo: dirty
    $this->configFactory->getEditable("simple_sitemap.custom")
      ->setData($custom_links)->save();
Pawel G's avatar
Pawel G committed
382
    return $this;
383 384
  }

385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
  /**
   *
   */
  private function addLinkSettings($type, $settings, &$target) {
    foreach ($settings as $setting_key => $setting) {
      if (in_array($setting_key, self::$allowed_link_settings[$type])) {
        switch ($setting_key) {
          case 'priority':
            if (!FormHelper::isValidPriority($setting)) {
              // todo: log error.
              continue;
            }
            break;

          // todo: add index check.
        }
        $target[$setting_key] = $setting;
      }
    }
  }

  /**
   * Returns an array of custom paths and their sitemap settings.
   *
   * @return array
   */
  public function getCustomLinks() {
    $custom_links = $this->configFactory
      ->get('simple_sitemap.custom')
      ->get();
    unset($custom_links['_core']);
    return $custom_links;
  }

Pawel G's avatar
Pawel G committed
419 420 421
  /**
   * Returns settings for a custom path added to the sitemap settings.
   *
Pawel G's avatar
Pawel G committed
422
   * @param string $path
Pawel G's avatar
Pawel G committed
423
   *
Pawel G's avatar
Pawel G committed
424
   * @return array|false
Pawel G's avatar
Pawel G committed
425
   */
426
  public function getCustomLink($path) {
427
    foreach ($this->getCustomLinks() as $key => $link) {
428
      if ($link['path'] == $path) {
429
        return $link;
430 431 432 433 434
      }
    }
    return FALSE;
  }

Pawel G's avatar
Pawel G committed
435 436 437
  /**
   * Removes a custom path from the sitemap settings.
   *
Pawel G's avatar
Pawel G committed
438
   * @param string $path
Pawel G's avatar
Pawel G committed
439
   *
Pawel G's avatar
Pawel G committed
440 441
   * @return $this
   */
442
  public function removeCustomLink($path) {
443
    $custom_links = $this->getCustomLinks();
Pawel G's avatar
Pawel G committed
444
    foreach ($custom_links as $key => $link) {
445 446 447
      if ($link['path'] == $path) {
        unset($custom_links[$key]);
        $custom_links = array_values($custom_links);
448 449 450
        $this->configFactory->getEditable("simple_sitemap.custom")
          ->setData($custom_links)->save();
        break;
451 452
      }
    }
Pawel G's avatar
Pawel G committed
453
    return $this;
454 455
  }

Pawel G's avatar
Pawel G committed
456 457
  /**
   * Removes all custom paths from the sitemap settings.
Pawel G's avatar
Pawel G committed
458 459
   *
   * @return $this
Pawel G's avatar
Pawel G committed
460
   */
461
  public function removeCustomLinks() {
462 463
    $this->configFactory->getEditable("simple_sitemap.custom")
      ->setData([])->save();
Pawel G's avatar
Pawel G committed
464
    return $this;
465 466
  }

Pawel G's avatar
Pawel G committed
467
  /**
468
   * Gets an entity's bundle name.
Pawel G's avatar
Pawel G committed
469
   *
470 471
   * @param string $entity
   * @return string
Pawel G's avatar
Pawel G committed
472
   */
Pawel G's avatar
Pawel G committed
473 474
  public function getEntityInstanceBundleName($entity) {
    return $entity->getEntityTypeId() == 'menu_link_content'
Pawel G's avatar
Pawel G committed
475 476
    // Menu fix.
      ? $entity->getMenuName() : $entity->bundle();
Pawel G's avatar
Pawel G committed
477 478
  }

Pawel G's avatar
Pawel G committed
479
  /**
480 481 482
   * Gets the entity type id for a bundle.
   *
   * @param string $entity
Pawel G's avatar
Pawel G committed
483 484
   * @return string
   */
Pawel G's avatar
Pawel G committed
485 486
  public function getBundleEntityTypeId($entity) {
    return $entity->getEntityTypeId() == 'menu'
Pawel G's avatar
Pawel G committed
487 488
    // Menu fix.
      ? 'menu_link_content' : $entity->getEntityType()->getBundleOf();
Pawel G's avatar
Pawel G committed
489 490
  }

491 492 493 494
  /**
   * Returns the whole sitemap, a requested sitemap chunk,
   * or the sitemap index file.
   *
Pawel G's avatar
Pawel G committed
495
   * @param int $chunk_id
496
   *
Pawel G's avatar
Pawel G committed
497
   * @return string|false
Pawel G's avatar
Pawel G committed
498 499 500 501
   *   If no sitemap id provided, either a sitemap index is returned, or the
   *   whole sitemap, if the amount of links does not exceed the max links
   *   setting. If a sitemap id is provided, a sitemap chunk is returned. False
   *   if sitemap is not retrievable from the database.
502
   */
Pawel G's avatar
Pawel G committed
503 504 505
  public function getSitemap($chunk_id = NULL) {
    $chunks = $this->fetchSitemapChunks();
    if (is_null($chunk_id) || !isset($chunks[$chunk_id])) {
506 507

      // Return sitemap index, if there are multiple sitemap chunks.
Pawel G's avatar
Pawel G committed
508 509
      if (count($chunks) > 1) {
        return $this->getSitemapIndex($chunks);
510
      }
Pawel G's avatar
Pawel G committed
511 512
      // Return sitemap if there is only one chunk.
      else {
Pawel G's avatar
Pawel G committed
513 514
        if (isset($chunks[1])) {
          return $chunks[1]->sitemap_string;
515 516
        }
        return FALSE;
517 518
      }
    }
Pawel G's avatar
Pawel G committed
519 520
    // Return specific sitemap chunk.
    else {
Pawel G's avatar
Pawel G committed
521
      return $chunks[$chunk_id]->sitemap_string;
522
    }
523 524
  }

525 526
  /**
   * Generates the sitemap for all languages and saves it to the db.
527 528
   *
   * @param string $from
Pawel G's avatar
Pawel G committed
529 530
   *   Can be 'form', 'cron', 'drush' or 'nobatch'.
   *   This decides how the batch process is to be run.
531
   */
532
  public function generateSitemap($from = 'form') {
533 534 535 536
    $this->sitemapGenerator
      ->setGenerator($this)
      ->setGenerateFrom($from)
      ->startGeneration();
537 538
  }

539
  /**
540 541
   * Generates and returns the sitemap index as string.
   *
Pawel G's avatar
Pawel G committed
542
   * @param array $chunks
Pawel G's avatar
Pawel G committed
543
   *   Sitemap chunks which to generate the index from.
544
   *
545
   * @return string
Pawel G's avatar
Pawel G committed
546
   *   The sitemap index.
547
   */
Pawel G's avatar
Pawel G committed
548
  private function getSitemapIndex($chunks) {
549 550
    return $this->sitemapGenerator
      ->setGenerator($this)
Pawel G's avatar
Pawel G committed
551
      ->generateSitemapIndex($chunks);
Pawel G's avatar
Pawel G committed
552 553
  }

554
  /**
555 556
   * Returns a specific sitemap setting or a default value if setting does not
   * exist.
557 558
   *
   * @param string $name
Pawel G's avatar
Pawel G committed
559
   *   Name of the setting, like 'max_links'.
560
   *
561
   * @param mixed $default
Pawel G's avatar
Pawel G committed
562
   *   Value to be returned if the setting does not exist in the configuration.
563
   *
564
   * @return mixed
565
   *   The current setting from configuration or a default value.
566
   */
567
  public function getSetting($name, $default = FALSE) {
568 569 570 571
    $setting = $this->configFactory
      ->get('simple_sitemap.settings')
      ->get($name);
    return !is_null($setting) ? $setting : $default;
572
  }
573

574
  /**
575
   * Stores a specific sitemap setting in configuration.
576
   *
Pawel G's avatar
Pawel G committed
577
   * @param string $name
Pawel G's avatar
Pawel G committed
578
   *   Setting name, like 'max_links'.
Pawel G's avatar
Pawel G committed
579
   * @param mixed $setting
Pawel G's avatar
Pawel G committed
580
   *   The setting to be saved.
Pawel G's avatar
Pawel G committed
581 582
   *
   * @return $this
583
   */
584
  public function saveSetting($name, $setting) {
585 586
    $this->configFactory->getEditable("simple_sitemap.settings")
      ->set($name, $setting)->save();
Pawel G's avatar
Pawel G committed
587
    return $this;
588
  }
589

Pawel G's avatar
Pawel G committed
590 591
  /**
   * Returns a 'time ago' string of last timestamp generation.
592
   *
Pawel G's avatar
Pawel G committed
593
   * @return string|false
Pawel G's avatar
Pawel G committed
594
   *   Formatted timestamp of last sitemap generation, otherwise FALSE.
Pawel G's avatar
Pawel G committed
595
   */
596
  public function getGeneratedAgo() {
597
    $chunks = $this->fetchSitemapChunks();
Pawel G's avatar
Pawel G committed
598
    if (isset($chunks[1]->sitemap_created)) {
599
      return $this->dateFormatter
Pawel G's avatar
Pawel G committed
600
        ->formatInterval(REQUEST_TIME - $chunks[1]->sitemap_created);
601 602 603
    }
    return FALSE;
  }
Pawel G's avatar
Pawel G committed
604

605
  /**
606
   * Returns objects of entity types that can be indexed.
607 608
   *
   * @return array
Pawel G's avatar
Pawel G committed
609
   *   Objects of entity types that can be indexed by the sitemap.
610
   */
611 612
  public function getSitemapEntityTypes() {
    $entity_types = $this->entityTypeManager->getDefinitions();
613 614

    foreach ($entity_types as $entity_type_id => $entity_type) {
615 616 617
      if (!$entity_type instanceof ContentEntityTypeInterface
        || !method_exists($entity_type, 'getBundleEntityType')
        || !$entity_type->hasLinkTemplate('canonical')) {
618 619 620 621 622
        unset($entity_types[$entity_type_id]);
      }
    }
    return $entity_types;
  }
623

Pawel G's avatar
Pawel G committed
624
  /**
625 626 627
   * Checks whether an entity type does not provide bundles.
   *
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
628 629
   * @return bool
   */
630
  public function entityTypeIsAtomic($entity_type_id) {
Pawel G's avatar
Pawel G committed
631 632
    // Menu fix.
    if ($entity_type_id == 'menu_link_content') {
633
      return FALSE;
Pawel G's avatar
Pawel G committed
634
    }
635

636
    $sitemap_entity_types = $this->getSitemapEntityTypes();
637 638 639 640 641 642
    if (isset($sitemap_entity_types[$entity_type_id])) {
      $entity_type = $sitemap_entity_types[$entity_type_id];
      if (empty($entity_type->getBundleEntityType())) {
        return TRUE;
      }
    }
Pawel G's avatar
Pawel G committed
643 644
    // todo: throw exception.
    return FALSE;
645
  }
Pawel G's avatar
Pawel G committed
646

647
}