simple_sitemap.module 7.82 KB
Newer Older
Pawel G's avatar
Pawel G committed
1
<?php
Pawel G's avatar
Pawel G committed
2

3 4 5 6
/**
 * @file
 * Main module file containing hooks.
 */
Pawel G's avatar
Pawel G committed
7

Pawel G's avatar
Pawel G committed
8
use Drupal\Core\Form\FormStateInterface;
Pawel G's avatar
Pawel G committed
9 10
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
11
use Drupal\system\MenuInterface;
12
use Drupal\language\ConfigurableLanguageInterface;
13

14
/**
Pawel G's avatar
Pawel G committed
15 16 17 18 19
 *Implements hook_help.
 *
 * @param $route_name
 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
 * @return \Drupal\Component\Render\MarkupInterface|null
20
 */
Pawel G's avatar
Pawel G committed
21
function simple_sitemap_help($route_name, RouteMatchInterface $route_match) {
22
  return $route_name === 'help.page.simple_sitemap' ?
23
    check_markup(file_get_contents(dirname(__FILE__) . "/README.md")) : NULL;
24 25
}

26 27
/**
 * Implements hook_form_alter.
28 29
 *
 * Adds sitemap settings to entity types that are supported via plugins.
Pawel G's avatar
Pawel G committed
30 31 32 33
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
34
 */
Pawel G's avatar
Pawel G committed
35
function simple_sitemap_form_alter(&$form, FormStateInterface $form_state, $form_id) {
36

37
  /** @var Drupal\simple_sitemap\Form\FormHelper $f */
Pawel G's avatar
Pawel G committed
38 39
  $f = \Drupal::service('simple_sitemap.form_helper');
  if (!$f->processForm($form_state)) {
40
    return;
Pawel G's avatar
Pawel G committed
41
  }
Pawel G's avatar
Pawel G committed
42 43 44 45 46

  $form['simple_sitemap'] = [
    '#type' => 'details',
    '#group' => isset($form['additional_settings']) ? 'additional_settings' : 'advanced',
    '#title' => t('Simple XML sitemap'),
Pawel G's avatar
Pawel G committed
47
    '#description' => $f->getEntityCategory() === 'instance' ? t('Settings for this entity can be overridden here.') : '',
Pawel G's avatar
Pawel G committed
48
  ];
49

Pawel G's avatar
Pawel G committed
50
  // Attach some js magic to forms.
Pawel G's avatar
Pawel G committed
51
  // todo: JS not working on comment entity form, hence disabling.
Pawel G's avatar
Pawel G committed
52
  if ($f->getEntityTypeId() !== 'comment' || $f->getEntityCategory() !== 'instance') {
Pawel G's avatar
Pawel G committed
53
    $form['#attached']['library'][] = 'simple_sitemap/form';
Pawel G's avatar
Pawel G committed
54
  }
55

Pawel G's avatar
Pawel G committed
56 57 58
  // Only attach fieldset summary js to 'additional settings' vertical tabs.
  if (isset($form['additional_settings'])) {
    $form['#attached']['library'][] = 'simple_sitemap/fieldsetSummaries';
59
  }
60

Pawel G's avatar
Pawel G committed
61
  $f->displayEntitySettings($form['simple_sitemap'])
Pawel G's avatar
Pawel G committed
62 63
  // todo: do not show setting when creating new bundle.
    ->displayRegenerateNow($form['simple_sitemap']);
64

65
  // Add submission handler.
66
  if (isset($form['actions']['submit']['#submit'])) {
67
    foreach (array_keys($form['actions']) as $action) {
Pawel G's avatar
Pawel G committed
68
      if ($action !== 'preview'
69 70
        && isset($form['actions'][$action]['#type'])
        && $form['actions'][$action]['#type'] === 'submit') {
71 72 73
        $form['actions'][$action]['#submit'][] = 'simple_sitemap_entity_form_submit';
      }
    }
74
  }
Pawel G's avatar
Pawel G committed
75 76
  // Fix for account page rendering other submit handlers not usable.
  else {
Pawel G's avatar
Pawel G committed
77
    $form['#submit'][] = 'simple_sitemap_entity_form_submit';
78
  }
Pawel G's avatar
Pawel G committed
79 80
}

81
/**
82
 * Form submission handler called in hook_form_alter.
Pawel G's avatar
Pawel G committed
83 84 85
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
86
 */
Pawel G's avatar
Pawel G committed
87
function simple_sitemap_entity_form_submit($form, FormStateInterface &$form_state) {
88

89
  /** @var Drupal\simple_sitemap\Form\FormHelper $f */
Pawel G's avatar
Pawel G committed
90 91 92 93
  $f = \Drupal::service('simple_sitemap.form_helper');
  if (!$f->processForm($form_state)) {
    return;
  }
94

95 96 97 98
  $values = $form_state->getValues();

  // Fix for values appearing in a sub array on a commerce product entity.
  $values = isset($values['simple_sitemap']) ? $values['simple_sitemap'] : $values;
99

100
  // Only make changes in DB if sitemap settings actually changed.
101
  if ($f->valuesChanged($form, $values)) {
102

103
    /** @var \Drupal\simple_sitemap\Simplesitemap $generator */
Pawel G's avatar
Pawel G committed
104
    $generator = \Drupal::service('simple_sitemap.generator');
105

106
    $settings = [
107
      'index' => (bool) $values['simple_sitemap_index_content'],
108 109
      'priority' => $values['simple_sitemap_priority'],
      'changefreq' => $values['simple_sitemap_changefreq'],
110
      'include_images' => (bool) $values['simple_sitemap_include_images'],
111 112
    ];

113
    switch ($f->getEntityCategory()) {
114 115

      case 'bundle':
116 117 118
        $generator->setBundleSettings(
          $f->getEntityTypeId(),
          !empty($f->getBundleName()) ? $f->getBundleName() : $f->getFormEntityId(),
119
          $settings
120
        );
121 122
        break;

123
      case 'instance':
124 125 126
        $generator->setEntityInstanceSettings(
          $f->getEntityTypeId(),
          !empty($f->getInstanceId()) ? $f->getInstanceId() : $f->getFormEntityId(),
127
          $settings
128
        );
129
        break;
130
    }
131 132 133

    // Regenerate sitemaps according to user setting.
    if ($values['simple_sitemap_regenerate_now']) {
Pawel G's avatar
Pawel G committed
134
      $generator->rebuildQueue()->generateSitemap();
135
    }
136 137 138 139 140 141
  }
}

/**
 * Implements hook_cron.
 */
Pawel G's avatar
Pawel G committed
142
function simple_sitemap_cron() {
143

144
  /** @var \Drupal\simple_sitemap\Simplesitemap $generator */
Pawel G's avatar
Pawel G committed
145 146
  $generator = \Drupal::service('simple_sitemap.generator');
  if ($generator->getSetting('cron_generate')) {
147
    $interval = (int) $generator->getSetting('cron_generate_interval', 0) * 60 * 60;
148 149 150
    $requestTime = \Drupal::service('datetime.time')->getRequestTime();
    if ($interval === 0 || ((\Drupal::state()->get('simple_sitemap.last_cron_generate', 0) + $interval) <= $requestTime)) {
      \Drupal::state()->set('simple_sitemap.last_cron_generate', $requestTime);
151
      $generator->generateSitemap('cron');
152
    }
153
  }
Pawel G's avatar
Pawel G committed
154
}
155

156 157 158 159 160 161 162
/**
 * Implements hook_ENTITY_TYPE_delete().
 *
 * When a language is removed from the system remove it also from settings.
 */
function simple_sitemap_configurable_language_delete(ConfigurableLanguageInterface $language) {

163
  /** @var \Drupal\simple_sitemap\Simplesitemap $generator */
164 165 166 167 168 169 170 171
  $generator = \Drupal::service('simple_sitemap.generator');
  $excluded_languages = $generator->getSetting('excluded_languages');
  if (isset($excluded_languages[$language->id()])) {
    unset($excluded_languages[$language->id()]);
    $generator->saveSetting('excluded_languages', $excluded_languages);
  }
}

172 173 174 175
/**
 * Implements hook_entity_delete().
 *
 * Removes settings of the removed entity.
176 177
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
178
 */
Pawel G's avatar
Pawel G committed
179
function simple_sitemap_entity_delete(EntityInterface $entity) {
180

181
  /** @var \Drupal\simple_sitemap\Simplesitemap $generator */
182 183 184 185
  $generator = \Drupal::service('simple_sitemap.generator');
  $generator->removeEntityInstanceSettings(
    $entity->getEntityTypeId(), $entity->id()
  );
186
}
187 188 189 190 191

/**
 * Implements hook_entity_bundle_delete().
 *
 * Removes settings of the removed bundle.
Pawel G's avatar
Pawel G committed
192 193 194
 *
 * @param string $entity_type_id
 * @param string $bundle
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
 */
function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
  simple_sitemap_delete_bundle_config($entity_type_id, $bundle);
}

/**
 * Implements hook_menu_delete().
 *
 * Removes settings for the removed menu.
 *
 * @param \Drupal\system\MenuInterface $menu
 */
function simple_sitemap_menu_delete(MenuInterface $menu) {
  simple_sitemap_delete_bundle_config('menu_link_content', $menu->id());
}

/**
 * Helper function used by simple_sitemap_entity_bundle_delete() and
 * simple_sitemap_menu_delete() hooks. This is needed, as menus are technically
 * not bundles.
 *
 * @param string $entity_type_id
 * @param string $bundle
 */
function simple_sitemap_delete_bundle_config($entity_type_id, $bundle) {
220

221
  /** @var \Drupal\simple_sitemap\Simplesitemap $generator */
222 223
  $generator = \Drupal::service('simple_sitemap.generator');
  $deleted_bundle_settings = $generator->getBundleSettings($entity_type_id, $bundle);
224
  if (!empty($deleted_bundle_settings['index'])) {
225 226 227 228

    // Delete bundle settings.
    \Drupal::service('config.factory')->getEditable("simple_sitemap.bundle_settings.$entity_type_id.$bundle")->delete();

229
    $message = 'You may want to <a href="@url">regenerate</a> your XML sitemaps now.';
230
    if ($generator->getSetting('cron_generate')) {
231
      $message .= ' Otherwise the sitemaps will be regenerated during a future cron run.';
232
    }
233
    \Drupal::messenger()->addMessage(t($message, ['@url' => $GLOBALS['base_url'] . '/admin/config/search/simplesitemap']));
234 235
  }
}
236 237 238

/**
 * Implements hook_robotstxt().
239 240 241
 *
 * @todo Use sitemap base URL setting?
 * @todo include non-default sitemaps as well?
242 243 244
 */
function simple_sitemap_robotstxt() {
  return [
245 246
    '# XML sitemaps',
    'Sitemap: ' . $GLOBALS['base_url'] . '/sitemap.xml',
247 248
  ];
}
249