SimplesitemapVariantsForm.php 6.32 KB
Newer Older
1 2 3 4 5
<?php

namespace Drupal\simple_sitemap\Form;

use Drupal\Core\Form\FormStateInterface;
6
use Drupal\simple_sitemap\SimplesitemapManager;
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

/**
 * Class SimplesitemapVariantsForm
 * @package Drupal\simple_sitemap\Form
 */
class SimplesitemapVariantsForm extends SimplesitemapFormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'simple_sitemap_variants_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['simple_sitemap_variants'] = [
      '#title' => $this->t('Sitemap variants'),
      '#type' => 'fieldset',
29
      '#markup' => '<div class="description">' . $this->t('Define sitemap variants. A sitemap variant is a sitemap instance of a certain type (specific sitemap generator and URL generators) accessible under a certain URL.<br>Each variant can have its own entity bundle settings (to be defined on bundle edit pages).') . '</div>',
gbyte.co's avatar
gbyte.co committed
30
      '#prefix' => FormHelper::getDonationText(),
31 32 33 34 35
    ];

    $form['simple_sitemap_variants']['variants'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Variants'),
36
      '#default_value' => $this->variantsToString($this->generator->getSitemapManager()->getSitemapVariants(NULL, TRUE)),
37
      '#description' => $this->t("Please specify sitemap variants, one per line. <strong>Caution: </strong>Removing variants here will delete their bundle settings, custom links and corresponding sitemap instances.<br><br>A variant definition consists of the variant name (used as the variant's path), the sitemap type it belongs to (optional) and the variant label (optional). These three values have to be separated by the | pipe | symbol.<br><br><strong>Examples:</strong><br><em>default | default_hreflang | Default</em> -> variant of the <em>default_hreflang</em> sitemap type and <em>Default</em> as label; accessible under <em>/default/sitemap.xml</em><br><em>test</em> -> variant of the <em>@default_sitemap_type</em> sitemap type and <em>test</em> as label; accessible under <em>/test/sitemap.xml</em><br><br><strong>Available sitemap types:</strong>", ['@default_sitemap_type' => SimplesitemapManager::DEFAULT_SITEMAP_TYPE]),
38 39
    ];

40
    foreach ($this->generator->getSitemapManager()->getSitemapTypes() as $sitemap_type => $definition) {
41
      $form['simple_sitemap_variants']['variants']['#description'] .= '<br>' . '<em>' . $sitemap_type . '</em>' . (!empty($definition['description']) ? (': ' . $definition['description']) : '');
gbyte.co's avatar
gbyte.co committed
42 43
    }

44 45 46 47 48 49 50 51
    $this->formHelper->displayRegenerateNow($form['simple_sitemap_custom']);

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   *
52 53
   * @todo Show multiple errors at once.
   * @todo Allow numeric variant names, but bear in mind that they are stored as integer array keys due to how php arrays work.
54 55 56
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $line = 0;
57
    $sitemap_types = $this->generator->getSitemapManager()->getSitemapTypes();
58 59 60 61 62 63 64 65 66 67 68 69
    foreach ($this->stringToVariants($form_state->getValue('variants')) as $variant_name => $variant_definition) {
      $placeholders = [
        '@line' => ++$line,
        '@name' => $variant_name,
        '@type' => isset($variant_definition['type']) ? $variant_definition['type'] : '',
        '@label' => isset($variant_definition['label']) ? $variant_definition['label'] : '',
      ];

      if (trim($variant_name) === '') {
        $form_state->setErrorByName('', $this->t("<strong>Line @line</strong>: The variant name cannot be empty.", $placeholders));
      }

70
      if (!preg_match('/^[\w\-_]+$/', $variant_name)) {
71 72 73
        $form_state->setErrorByName('', $this->t("<strong>Line @line</strong>: The variant name <em>@name</em> can only include alphanumeric characters, dashes and underscores.", $placeholders));
      }

74 75 76 77
      if (is_numeric($variant_name)) {
        $form_state->setErrorByName('', $this->t("<strong>Line @line</strong>: The variant name cannot be numeric.", $placeholders));
      }

78 79 80 81 82 83 84 85 86 87
      if (!isset($sitemap_types[$variant_definition['type']])) {
        $form_state->setErrorByName('', $this->t("<strong>Line @line</strong>: The variant <em>@name</em> is of a sitemap type <em>@type</em> that does not exist.", $placeholders));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
88
    $manager = $this->generator->getSitemapManager();
gbyte.co's avatar
gbyte.co committed
89
    $new_variants = $this->stringToVariants($form_state->getValue('variants'));
90 91 92 93 94
    $remove_variants = array_values(array_diff(
      array_keys($manager->getSitemapVariants(NULL, FALSE)),
      array_keys($new_variants)
    ));
    $manager->removeSitemapVariants($remove_variants);
95
    $weight = 0;
gbyte.co's avatar
gbyte.co committed
96
    foreach ($new_variants as $variant_name => $variant_definition) {
97
      $manager->addSitemapVariant($variant_name, $variant_definition + ['weight' => $weight]);
98
      $weight++;
99
    }
gbyte.co's avatar
gbyte.co committed
100

101 102 103 104
    parent::submitForm($form, $form_state);

    // Regenerate sitemaps according to user setting.
    if ($form_state->getValue('simple_sitemap_regenerate_now')) {
105 106 107
      $this->generator->setVariants(TRUE)
        ->rebuildQueue()
        ->generateSitemap();
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    }
  }

  /**
   * @param $variant_string
   * @return array
   */
  protected function stringToVariants($variant_string) {

    // Unify newline characters and explode into array.
    $variants_string_lines = explode("\n", str_replace("\r\n", "\n", $variant_string));

    // Remove empty values and whitespaces from array.
    $variants_string_lines = array_filter(array_map('trim', $variants_string_lines));

    $variants = [];
    foreach ($variants_string_lines as $i => &$line) {
      $variant_settings = explode('|', $line);
      $name = strtolower(trim($variant_settings[0]));
127
      $variants[$name]['type'] = !empty($variant_settings[1]) ? trim($variant_settings[1]) : SimplesitemapManager::DEFAULT_SITEMAP_TYPE;
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
      $variants[$name]['label'] = !empty($variant_settings[2]) ? trim($variant_settings[2]) : $name;
    }
    return $variants;
  }

  /**
   * @param array $variants
   * @return string
   */
  protected function variantsToString(array $variants) {
    $variants_string = '';
    foreach ($variants as $variant_name => $variant_definition) {
      $variants_string .= $variant_name
        . ' | ' . $variant_definition['type']
        . ' | ' . $variant_definition['label']
        . "\r\n";
    }
    return $variants_string;
  }
}