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

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

Pawel G's avatar
Pawel G committed
5 6 7
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\PathValidator;
Pawel G's avatar
Pawel G committed
8 9
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Datetime\DateFormatter;
10
use Drupal\Component\Datetime\Time;
11
use Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorManager;
12

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

Pawel G's avatar
Pawel G committed
19 20 21
  /**
   * @var \Drupal\simple_sitemap\SitemapGenerator
   */
22
  protected $sitemapGenerator;
Pawel G's avatar
Pawel G committed
23 24 25 26

  /**
   * @var \Drupal\simple_sitemap\EntityHelper
   */
27
  protected $entityHelper;
Pawel G's avatar
Pawel G committed
28 29 30 31

  /**
   * @var \Drupal\Core\Config\ConfigFactory
   */
32
  protected $configFactory;
Pawel G's avatar
Pawel G committed
33 34 35 36

  /**
   * @var \Drupal\Core\Database\Connection
   */
37
  protected $db;
Pawel G's avatar
Pawel G committed
38 39 40 41

  /**
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
42
  protected $entityTypeManager;
Pawel G's avatar
Pawel G committed
43 44 45 46

  /**
   * @var \Drupal\Core\Path\PathValidator
   */
47
  protected $pathValidator;
Pawel G's avatar
Pawel G committed
48

49 50 51 52 53
  /**
   * @var \Drupal\Core\Datetime\DateFormatter
   */
  protected $dateFormatter;

54 55 56 57 58
  /**
   * @var \Drupal\Component\Datetime\Time
   */
  protected $time;

59
  /**
60
   * @var \Drupal\simple_sitemap\Batch
61 62 63 64 65 66 67 68
   */
  protected $batch;

  /**
   * @var \Drupal\Core\Extension\ModuleHandler
   */
  protected $moduleHandler;

69 70 71 72 73
  /**
   * @var \Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorManager
   */
  protected $urlGeneratorManager;

Pawel G's avatar
Pawel G committed
74 75 76
  /**
   * @var array
   */
Pawel G's avatar
Pawel G committed
77
  protected static $allowedLinkSettings = [
78
    'entity' => ['index', 'priority', 'changefreq', 'include_images'],
79 80 81
    'custom' => ['priority', 'changefreq'],
  ];

Pawel G's avatar
Pawel G committed
82 83 84 85
  /**
   * @var array
   */
  protected static $linkSettingDefaults = [
86
    'index' => 1,
87
    'priority' => 0.5,
88
    'changefreq' => '',
89
    'include_images' => 0,
90
  ];
91

92 93 94 95 96 97
  protected static $generatorServices = [
    'simple_sitemap.custom_url_generator',
    'simple_sitemap.entity_url_generator',
    'simple_sitemap.arbitrary_url_generator',
  ];

98 99
  /**
   * Simplesitemap constructor.
Pawel G's avatar
Pawel G committed
100
   * @param \Drupal\simple_sitemap\SitemapGenerator $sitemapGenerator
101
   * @param \Drupal\simple_sitemap\EntityHelper $entityHelper
Pawel G's avatar
Pawel G committed
102 103 104 105 106
   * @param \Drupal\Core\Config\ConfigFactory $configFactory
   * @param \Drupal\Core\Database\Connection $database
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   * @param \Drupal\Core\Path\PathValidator $pathValidator
   * @param \Drupal\Core\Datetime\DateFormatter $dateFormatter
107
   * @param \Drupal\Component\Datetime\Time $time
108 109
   * @param \Drupal\simple_sitemap\Batch $batch
   * @param \Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorManager $urlGeneratorManager
110
   */
111
  public function __construct(
Pawel G's avatar
Pawel G committed
112
    SitemapGenerator $sitemapGenerator,
113
    EntityHelper $entityHelper,
Pawel G's avatar
Pawel G committed
114
    ConfigFactory $configFactory,
Pawel G's avatar
Pawel G committed
115 116 117
    Connection $database,
    EntityTypeManagerInterface $entityTypeManager,
    PathValidator $pathValidator,
118
    DateFormatter $dateFormatter,
119 120
    Time $time,
    Batch $batch,
121
    UrlGeneratorManager $urlGeneratorManager
122 123
  ) {
    $this->sitemapGenerator = $sitemapGenerator;
124
    $this->entityHelper = $entityHelper;
Pawel G's avatar
Pawel G committed
125
    $this->configFactory = $configFactory;
126 127
    $this->db = $database;
    $this->entityTypeManager = $entityTypeManager;
128
    $this->pathValidator = $pathValidator;
129
    $this->dateFormatter = $dateFormatter;
130
    $this->time = $time;
131
    $this->batch = $batch;
132
    $this->urlGeneratorManager = $urlGeneratorManager;
133 134
  }

135
  /**
136 137
   * Returns a specific sitemap setting or a default value if setting does not
   * exist.
Pawel G's avatar
Pawel G committed
138
   *
139 140 141 142 143 144 145 146
   * @param string $name
   *   Name of the setting, like 'max_links'.
   *
   * @param mixed $default
   *   Value to be returned if the setting does not exist in the configuration.
   *
   * @return mixed
   *   The current setting from configuration or a default value.
Pawel G's avatar
Pawel G committed
147
   */
148 149 150 151 152 153 154 155 156 157 158 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 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
  public function getSetting($name, $default = FALSE) {
    $setting = $this->configFactory
      ->get('simple_sitemap.settings')
      ->get($name);
    return NULL !== $setting ? $setting : $default;
  }

  /**
   * Stores a specific sitemap setting in configuration.
   *
   * @param string $name
   *   Setting name, like 'max_links'.
   * @param mixed $setting
   *   The setting to be saved.
   *
   * @return $this
   */
  public function saveSetting($name, $setting) {
    $this->configFactory->getEditable("simple_sitemap.settings")
      ->set($name, $setting)->save();
    return $this;
  }

  /**
   * Returns the whole sitemap, a requested sitemap chunk,
   * or the sitemap index file.
   *
   * @param int $chunk_id
   *
   * @return string|false
   *   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.
   */
  public function getSitemap($chunk_id = NULL) {
    $chunk_info = $this->fetchSitemapChunkInfo();

    if (NULL === $chunk_id || !isset($chunk_info[$chunk_id])) {

      if (count($chunk_info) > 1) {
        // Return sitemap index, if there are multiple sitemap chunks.
        return $this->getSitemapIndex($chunk_info);
      }
      else {
        // Return sitemap if there is only one chunk.
        return count($chunk_info) === 1
        && isset($chunk_info[SitemapGenerator::FIRST_CHUNK_INDEX])
          ? $this->fetchSitemapChunk(SitemapGenerator::FIRST_CHUNK_INDEX)
            ->sitemap_string
          : FALSE;
      }
    }
    else {
      // Return specific sitemap chunk.
      return $this->fetchSitemapChunk($chunk_id)->sitemap_string;
    }
  }

  /**
   * Fetches all sitemap chunk timestamps keyed by chunk ID.
   *
   * @return array
   *   An array containing chunk creation timestamps keyed by chunk ID.
   */
  protected function fetchSitemapChunkInfo() {
214
    return $this->db
215
      ->query("SELECT id, sitemap_created FROM {simple_sitemap}")
216 217 218
      ->fetchAllAssoc('id');
  }

219 220 221 222 223 224 225 226 227
  /**
   * Fetches a single sitemap chunk by ID.
   *
   * @param int $id
   *   The chunk ID.
   *
   * @return object
   *   A sitemap chunk object.
   */
228
  protected function fetchSitemapChunk($id) {
229 230 231 232 233
    return $this->db->query('SELECT * FROM {simple_sitemap} WHERE id = :id',
      [':id' => $id])->fetchObject();
  }

  /**
Pawel G's avatar
Pawel G committed
234
   * Generates the XML sitemap and saves it to the db.
235 236
   *
   * @param string $from
Pawel G's avatar
Pawel G committed
237
   *   Can be 'form', 'backend', 'drush' or 'nobatch'.
238
   *   This decides how the batch process is to be run.
Pawel G's avatar
Pawel G committed
239 240
   *
   * @return bool|\Drupal\simple_sitemap\Simplesitemap
241 242
   */
  public function generateSitemap($from = 'form') {
243

Pawel G's avatar
Pawel G committed
244
    $this->batch->setBatchSettings([
245 246 247 248 249 250 251 252 253
      'base_url' => $this->getSetting('base_url', ''),
      'batch_process_limit' => $this->getSetting('batch_process_limit', NULL),
      'max_links' => $this->getSetting('max_links', 2000),
      'skip_untranslated' => $this->getSetting('skip_untranslated', FALSE),
      'remove_duplicates' => $this->getSetting('remove_duplicates', TRUE),
      'excluded_languages' => $this->getSetting('excluded_languages', []),
      'from' => $from,
    ]);

Pawel G's avatar
Pawel G committed
254 255 256 257 258 259 260
    $plugins = $this->urlGeneratorManager->getDefinitions();

    usort($plugins, function($a, $b) {
      return $a['weight'] - $b['weight'];
    });

    foreach ($plugins as $plugin) {
261 262 263 264 265 266 267 268
      if ($plugin['instantiateForEachDataSet']) {
        foreach ($this->urlGeneratorManager->createInstance($plugin['id'])->getDataSets() as $data_sets) {
          $this->batch->addOperation($plugin['id'], $data_sets);
        }
      }
      else {
        $this->batch->addOperation($plugin['id']);
      }
269 270
    }

Pawel G's avatar
Pawel G committed
271 272
    $success = $this->batch->start();
    return $from === 'nobatch' ? $this : $success;
273 274 275 276 277
  }

  /**
   * Generates and returns the sitemap index as string.
   *
Pawel G's avatar
Pawel G committed
278 279
   * @param array $chunk_info
   *   Array containing chunk creation timestamps keyed by chunk ID.
280 281 282
   *
   * @return string
   *   The sitemap index.
283 284
   *
   * @todo Need to make sure response is cached.
285
   */
Pawel G's avatar
Pawel G committed
286
  protected function getSitemapIndex($chunk_info) {
287
    return $this->sitemapGenerator
Pawel G's avatar
Pawel G committed
288
      ->setSettings(['base_url' => $this->getSetting('base_url', '')])
Pawel G's avatar
Pawel G committed
289
      ->generateSitemapIndex($chunk_info);
290 291 292 293 294 295 296 297 298 299 300 301
  }

  /**
   * Returns a 'time ago' string of last timestamp generation.
   *
   * @return string|false
   *   Formatted timestamp of last sitemap generation, otherwise FALSE.
   */
  public function getGeneratedAgo() {
    $chunks = $this->fetchSitemapChunkInfo();
    if (isset($chunks[SitemapGenerator::FIRST_CHUNK_INDEX]->sitemap_created)) {
      return $this->dateFormatter
302
        ->formatInterval($this->time->getRequestTime() - $chunks[SitemapGenerator::FIRST_CHUNK_INDEX]
303 304 305 306 307
            ->sitemap_created);
    }
    return FALSE;
  }

308 309
  /**
   * Enables sitemap support for an entity type. Enabled entity types show
310 311
   * sitemap settings on their bundle setting forms. If an enabled entity type
   * features bundles (e.g. 'node'), it needs to be set up with
312 313 314
   * setBundleSettings() as well.
   *
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
315
   *   Entity type id like 'node'.
316
   *
Pawel G's avatar
Pawel G committed
317
   * @return $this
318 319
   */
  public function enableEntityType($entity_type_id) {
320 321 322 323
    $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);
324
    }
Pawel G's avatar
Pawel G committed
325
    return $this;
326 327 328 329 330 331 332 333
  }

  /**
   * 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
334
   *  Entity type id like 'node'.
335
   *
Pawel G's avatar
Pawel G committed
336
   * @return $this
337 338
   */
  public function disableEntityType($entity_type_id) {
339 340 341

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

    // Deleting inclusion settings.
348
    $config_names = $this->configFactory->listAll("simple_sitemap.bundle_settings.$entity_type_id.");
349 350
    foreach($config_names as $config_name) {
      $this->configFactory->getEditable($config_name)->delete();
351
    }
352 353 354

    // Deleting entity overrides.
    $this->removeEntityInstanceSettings($entity_type_id);
Pawel G's avatar
Pawel G committed
355
    return $this;
356 357 358
  }

  /**
Pawel G's avatar
Pawel G committed
359
   * Sets sitemap settings for a non-bundle entity type (e.g. user) or a bundle
360 361 362
   * of an entity type (e.g. page).
   *
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
363
   *   Entity type id like 'node' the bundle belongs to.
364
   * @param string $bundle_name
Pawel G's avatar
Pawel G committed
365
   *   Name of the bundle. NULL if entity type has no bundles.
366
   * @param array $settings
Pawel G's avatar
Pawel G committed
367
   *   An array of sitemap settings for this bundle/entity type.
368
   *   Example: ['index' => TRUE, 'priority' => 0.5, 'changefreq' => 'never', 'include_images' => FALSE].
Pawel G's avatar
Pawel G committed
369 370
   *
   * @return $this
371 372
   *
   * @todo: enableEntityType automatically
373
   */
374
  public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings = []) {
375
    $bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
376

377 378 379 380 381
    $old_settings = $this->getBundleSettings($entity_type_id, $bundle_name);
    $settings = !empty($old_settings) ? array_merge($old_settings, $settings) : $this->supplementDefaultSettings('entity', $settings);

    $bundle_settings = $this->configFactory
      ->getEditable("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name");
382
    foreach($settings as $setting_key => $setting) {
383
      if ($setting_key === 'index') {
384 385
        $setting = intval($setting);
      }
386
      $bundle_settings->set($setting_key, $setting);
387
    }
388
    $bundle_settings->save();
389 390

    // Delete entity overrides which are identical to new bundle setting.
Pawel G's avatar
Pawel G committed
391
    $sitemap_entity_types = $this->entityHelper->getSupportedEntityTypes();
392 393 394
    if (isset($sitemap_entity_types[$entity_type_id])) {
      $entity_type = $sitemap_entity_types[$entity_type_id];
      $keys = $entity_type->getKeys();
395 396

      // Menu fix.
397 398
      $keys['bundle'] = $entity_type_id == 'menu_link_content' ? 'menu_name' : $keys['bundle'];

399
      $query = $this->entityTypeManager->getStorage($entity_type_id)->getQuery();
400
      if (!$this->entityHelper->entityTypeIsAtomic($entity_type_id)) {
401
        $query->condition($keys['bundle'], $bundle_name);
402
      }
403 404 405 406 407 408 409 410 411
      $entity_ids = $query->execute();

      $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');
      }

412
      $delete_instances = [];
413
      foreach($query->execute()->fetchAll() as $result) {
414 415 416
        $delete = TRUE;
        $instance_settings = unserialize($result->inclusion_settings);
        foreach ($instance_settings as $setting_key => $instance_setting) {
417
          if ($instance_setting != $settings[$setting_key]) {
418 419 420 421 422
            $delete = FALSE;
            break;
          }
        }
        if ($delete) {
423
          $delete_instances[] = $result->id;
424
        }
425
      }
426 427 428 429 430
      if (!empty($delete_instances)) {
        $this->db->delete('simple_sitemap_entity_overrides')
          ->condition('id', $delete_instances, 'IN')
          ->execute();
      }
431
    }
432 433 434
    else {
      //todo: log error
    }
Pawel G's avatar
Pawel G committed
435
    return $this;
436 437
  }

438
  /**
439 440
   * Gets sitemap settings for an entity bundle, a non-bundle entity type or for
   * all entity types and their bundles.
441
   *
442 443 444
   * @param string|null $entity_type_id
   *  If set to null, sitemap settings for all entity types and their bundles
   *  are fetched.
445 446 447
   * @param string|null $bundle_name
   *
   * @return array|false
Pawel G's avatar
Pawel G committed
448 449
   *  Array of sitemap settings for an entity bundle, a non-bundle entity type
   *  or for all entity types and their bundles.
450
   *  False if entity type does not exist.
451
   */
452
  public function getBundleSettings($entity_type_id = NULL, $bundle_name = NULL) {
453
    if (NULL !== $entity_type_id) {
454
      $bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
455
      $bundle_settings = $this->configFactory
456 457
        ->get("simple_sitemap.bundle_settings.$entity_type_id.$bundle_name")
        ->get();
458
      return !empty($bundle_settings) ? $bundle_settings : FALSE;
459
    }
460
    else {
461
      $config_names = $this->configFactory->listAll("simple_sitemap.bundle_settings.");
462
      $all_settings = [];
463 464
      foreach($config_names as $config_name) {
        $config_name_parts = explode('.', $config_name);
465
        $all_settings[$config_name_parts[2]][$config_name_parts[3]] = $this->configFactory->get($config_name)->get();
466 467 468 469 470 471
      }
      return $all_settings;
    }
  }

  /**
472 473
   * Supplements all missing link setting with default values.
   *
474 475 476 477 478
   * @param string $type
   * @param array $settings
   * @return array
   */
  protected function supplementDefaultSettings($type, $settings) {
Pawel G's avatar
Pawel G committed
479
    foreach(self::$allowedLinkSettings[$type] as $allowed_link_setting) {
480
      if (!isset($settings[$allowed_link_setting])
Pawel G's avatar
Pawel G committed
481 482
        && isset(self::$linkSettingDefaults[$allowed_link_setting])) {
        $settings[$allowed_link_setting] = self::$linkSettingDefaults[$allowed_link_setting];
483 484
      }
    }
485
    return $settings;
486 487
  }

Pawel G's avatar
Pawel G committed
488 489 490
  /**
   * Overrides entity bundle/entity type sitemap settings for a single entity.
   *
Pawel G's avatar
Pawel G committed
491 492 493
   * @param string $entity_type_id
   * @param int $id
   * @param array $settings
Pawel G's avatar
Pawel G committed
494
   *
Pawel G's avatar
Pawel G committed
495 496
   * @return $this
   */
497
  public function setEntityInstanceSettings($entity_type_id, $id, $settings) {
498
    $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($id);
499 500 501
    $bundle_settings = $this->getBundleSettings(
      $entity_type_id, $this->entityHelper->getEntityInstanceBundleName($entity)
    );
502
    if (!empty($bundle_settings)) {
503 504 505 506

      // Check if overrides are different from bundle setting before saving.
      $override = FALSE;
      foreach ($settings as $key => $setting) {
507
        if (!isset($bundle_settings[$key]) || $setting != $bundle_settings[$key]) {
508 509 510 511
          $override = TRUE;
          break;
        }
      }
Pawel G's avatar
Pawel G committed
512 513
      // Save overrides for this entity if something is different.
      if ($override) {
514 515 516 517 518 519 520
        $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,
521
            'inclusion_settings' => serialize(array_merge($bundle_settings, $settings)),])
522
          ->execute();
523
      }
Pawel G's avatar
Pawel G committed
524 525
      // Else unset override.
      else {
526
        $this->removeEntityInstanceSettings($entity_type_id, $id);
527
      }
528 529 530
    }
    else {
      //todo: log error
531
    }
Pawel G's avatar
Pawel G committed
532
    return $this;
533 534
  }

Pawel G's avatar
Pawel G committed
535
  /**
536
   * Gets sitemap settings for an entity instance which overrides the sitemap
537
   * settings of its bundle, or bundle settings, if they are not overridden.
Pawel G's avatar
Pawel G committed
538
   *
Pawel G's avatar
Pawel G committed
539
   * @param string $entity_type_id
540
   * @param int $id
Pawel G's avatar
Pawel G committed
541
   *
542
   * @return array|false
Pawel G's avatar
Pawel G committed
543
   */
544 545 546 547 548 549 550 551 552
  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)) {
553
      return unserialize($results);
554 555
    }
    else {
556 557 558 559 560 561
      $entity = $this->entityTypeManager->getStorage($entity_type_id)
        ->load($id);
      return $this->getBundleSettings(
        $entity_type_id,
        $this->entityHelper->getEntityInstanceBundleName($entity)
      );
562 563 564
    }
  }

565 566 567 568 569 570 571 572 573 574 575 576
  /**
   * 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);
577
    if (NULL !== $entity_ids) {
578 579 580 581 582 583 584
      $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
585 586 587 588
  /**
   * Checks if an entity bundle (or a non-bundle entity type) is set to be
   * indexed in the sitemap settings.
   *
589 590
   * @param string $entity_type_id
   * @param string|null $bundle_name
Pawel G's avatar
Pawel G committed
591
   *
Pawel G's avatar
Pawel G committed
592 593
   * @return bool
   */
594
  public function bundleIsIndexed($entity_type_id, $bundle_name = NULL) {
595 596 597 598
    $settings = $this->getBundleSettings($entity_type_id, $bundle_name);
    return !empty($settings['index']);
  }

Pawel G's avatar
Pawel G committed
599 600 601
  /**
   * Checks if an entity type is enabled in the sitemap settings.
   *
602
   * @param string $entity_type_id
Pawel G's avatar
Pawel G committed
603
   *
Pawel G's avatar
Pawel G committed
604 605
   * @return bool
   */
606
  public function entityTypeIsEnabled($entity_type_id) {
607
    return in_array($entity_type_id, $this->getSetting('enabled_entity_types', []));
608 609
  }

Pawel G's avatar
Pawel G committed
610
  /**
611
   * Stores a custom path along with its sitemap settings to configuration.
Pawel G's avatar
Pawel G committed
612
   *
Pawel G's avatar
Pawel G committed
613 614
   * @param string $path
   * @param array $settings
Pawel G's avatar
Pawel G committed
615
   *
Pawel G's avatar
Pawel G committed
616
   * @return $this
617 618
   *
   * @todo Validate $settings and throw exceptions
Pawel G's avatar
Pawel G committed
619
   */
620
  public function addCustomLink($path, $settings = []) {
Pawel G's avatar
Pawel G committed
621 622 623 624 625 626 627 628
    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
629

630
    $custom_links = $this->getCustomLinks(FALSE);
Pawel G's avatar
Pawel G committed
631
    foreach ($custom_links as $key => $link) {
632
      if ($link['path'] === $path) {
633 634 635 636 637
        $link_key = $key;
        break;
      }
    }
    $link_key = isset($link_key) ? $link_key : count($custom_links);
638
    $custom_links[$link_key] = ['path' => $path] + $settings;
639
    $this->configFactory->getEditable("simple_sitemap.custom")
640
      ->set('links', $custom_links)->save();
Pawel G's avatar
Pawel G committed
641
    return $this;
642 643
  }

644 645 646
  /**
   * Returns an array of custom paths and their sitemap settings.
   *
647
   * @param bool $supplement_default_settings
648 649
   * @return array
   */
650
  public function getCustomLinks($supplement_default_settings = TRUE) {
651 652
    $custom_links = $this->configFactory
      ->get('simple_sitemap.custom')
653
      ->get('links');
654 655 656 657 658 659 660

    if ($supplement_default_settings) {
      foreach ($custom_links as $i => $link_settings) {
        $custom_links[$i] = $this->supplementDefaultSettings('custom', $link_settings);
      }
    }

661
    return $custom_links !== NULL ? $custom_links : [];
662 663
  }

Pawel G's avatar
Pawel G committed
664 665 666
  /**
   * Returns settings for a custom path added to the sitemap settings.
   *
Pawel G's avatar
Pawel G committed
667
   * @param string $path
Pawel G's avatar
Pawel G committed
668
   *
Pawel G's avatar
Pawel G committed
669
   * @return array|false
Pawel G's avatar
Pawel G committed
670
   */
671
  public function getCustomLink($path) {
672
    foreach ($this->getCustomLinks() as $key => $link) {
673
      if ($link['path'] === $path) {
674
        return $link;
675 676 677 678 679
      }
    }
    return FALSE;
  }

Pawel G's avatar
Pawel G committed
680 681 682
  /**
   * Removes a custom path from the sitemap settings.
   *
Pawel G's avatar
Pawel G committed
683
   * @param string $path
Pawel G's avatar
Pawel G committed
684
   *
Pawel G's avatar
Pawel G committed
685 686
   * @return $this
   */
687
  public function removeCustomLink($path) {
688
    $custom_links = $this->getCustomLinks(FALSE);
Pawel G's avatar
Pawel G committed
689
    foreach ($custom_links as $key => $link) {
690
      if ($link['path'] === $path) {
691 692
        unset($custom_links[$key]);
        $custom_links = array_values($custom_links);
693
        $this->configFactory->getEditable("simple_sitemap.custom")
694
          ->set('links', $custom_links)->save();
695
        break;
696 697
      }
    }
Pawel G's avatar
Pawel G committed
698
    return $this;
699 700
  }

Pawel G's avatar
Pawel G committed
701 702
  /**
   * Removes all custom paths from the sitemap settings.
Pawel G's avatar
Pawel G committed
703 704
   *
   * @return $this
Pawel G's avatar
Pawel G committed
705
   */
706
  public function removeCustomLinks() {
707
    $this->configFactory->getEditable("simple_sitemap.custom")
708
      ->set('links', [])->save();
Pawel G's avatar
Pawel G committed
709
    return $this;
710
  }
711
}