You are here

sitemap.module in Sitemap 8

Same filename and directory in other branches
  1. 8.2 sitemap.module
  2. 2.0.x sitemap.module

Provides sitemap functionality.

File

sitemap.module
View source
<?php

/**
 * @file
 * Provides sitemap functionality.
 */
use Drupal\system\Entity\Menu;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Url;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Link;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_theme().
 */
function sitemap_theme() {
  return [
    'sitemap' => [
      'variables' => [
        'message' => NULL,
        'rss_legend' => NULL,
        'sitemap_items' => [],
        'additional' => NULL,
      ],
      'file' => 'sitemap.theme.inc',
    ],
    'sitemap_feed_icon' => [
      'variables' => [
        'url' => NULL,
        'name' => NULL,
        'type' => 'node',
      ],
    ],
    'sitemap_menu_link' => [
      'render element' => 'element',
      'function' => 'theme_sitemap_menu_link',
      'file' => 'sitemap.theme.inc',
    ],
    'sitemap_menu_tree' => [
      'render element' => 'tree',
      'function' => 'theme_sitemap_menu_tree',
      'file' => 'sitemap.theme.inc',
    ],
  ];
}

/**
 * Helper callback for the sitemap front page.
 *
 * @return array
 *   Returns a keyed array with variables for rendering front page sitemap box.
 */
function _sitemap_front_page() {
  $config = \Drupal::config('sitemap.settings');
  $title = t('Front page');
  $content = Link::fromTextAndUrl(t('Front page of %sn', [
    '%sn' => \Drupal::config('system.site')
      ->get('name'),
  ]), Url::fromRoute('<front>', [], [
    'html' => TRUE,
  ]))
    ->toString();
  $attributes = new Attribute();
  $options = [];
  if ($config
    ->get('show_rss_links') != 0) {
    $feed_icon = [
      '#theme' => 'sitemap_feed_icon',
      '#url' => $config
        ->get('rss_front'),
      '#name' => 'front page',
    ];
    $rss_link = \Drupal::service('renderer')
      ->render($feed_icon);
    if ($config
      ->get('show_rss_links') == 1) {
      $content .= ' ' . $rss_link;
    }
    else {
      $attributes
        ->addClass('sitemap-rss-left');
      $content = $rss_link . ' ' . $content;
    }
  }
  \Drupal::service('sitemap.helper')
    ->setOption($options, 'show_titles', 1, 'show_titles', TRUE);
  $attributes
    ->addClass('sitemap-box-front');
  $sitemap_box = [
    'title' => $title,
    'content' => [
      '#markup' => $content,
    ],
    'attributes' => $attributes,
    'options' => $options,
  ];
  return $sitemap_box;
}

/**
 * Helper callback for the sitemap books.
 *
 * @return array
 *   Returns a keyed array with variables for rendering the books sitemap box.
 */
function _sitemap_books() {
  $config = \Drupal::config('sitemap.settings');
  $sitemap_box = [];
  $content = '';
  $options = [];
  $book_titles = [];
  $bids = array_filter($config
    ->get('show_books'));
  if (\Drupal::service('module_handler')
    ->moduleExists('book') && !empty($bids)) {
    $books_expanded = $config
      ->get('books_expanded');
    $title = t('Books');
    $description = '<div class="description">' . t('Books at %sn.', [
      '%sn' => \Drupal::config('system.site')
        ->get('name'),
    ]) . '</div>';
    foreach (\Drupal::service('book.manager')
      ->getAllBooks() as $book) {
      if (in_array($book['bid'], $bids)) {
        if ($books_expanded) {

          // Retrieve the expanded tree.
          // @TODO Ensure the outline is properly translated.
          // @see https://www.drupal.org/node/2615642
          $tree = \Drupal::service('book.manager')
            ->bookTreeAllData($book['bid']);
          $tree_output = \Drupal::service('book.manager')
            ->bookTreeOutput($tree);
          $content .= \Drupal::service('renderer')
            ->render($tree_output);
        }
        else {
          $book_titles[] = Link::fromTextAndUrl($book['title'], Url::fromRoute('entity.node.canonical', [
            'node' => $book['bid'],
          ]))
            ->toString();
        }
      }
    }
    \Drupal::service('sitemap.helper')
      ->setOption($options, 'show_titles', 1, 'show_titles', TRUE);
    if (!$books_expanded && !empty($book_titles)) {
      $book_titles = [
        '#theme' => 'item_list',
        '#items' => $book_titles,
      ];
      $content .= \Drupal::service('renderer')
        ->render($book_titles);
    }
    if (!empty($content)) {
      $attributes = new Attribute();
      $attributes
        ->addClass('sitemap-box-book');
      $sitemap_box = [
        'title' => $title,
        'content' => [
          '#markup' => $description . $content,
        ],
        'attributes' => $attributes,
        'options' => $options,
      ];
    }
  }
  return $sitemap_box;
}

/**
 * Helper callback for the sitemap menus.
 *
 * @return array
 *   Returns a keyed array with variables for rendering the menu's sitemap box.
 */
function _sitemap_menus($mid) {
  $sitemap_box = [];
  $attributes = new Attribute();
  $options = [];
  if (!empty($mid)) {
    $menu = Menu::load($mid);

    // Retrieve the expanded tree.
    $tree = \Drupal::service('sitemap.menu.link_tree')
      ->load($mid, new MenuTreeParameters());
    $manipulators = [
      [
        'callable' => 'menu.default_tree_manipulators:checkAccess',
      ],
      [
        'callable' => 'menu.default_tree_manipulators:generateIndexAndSort',
      ],
    ];
    $tree = \Drupal::service('sitemap.menu.link_tree')
      ->transform($tree, $manipulators);

    // Add an alter hook so that other modules can manipulate the
    // menu tree prior to rendering.
    $alter_mid = preg_replace('/[^a-z0-9_]+/', '_', $mid);
    \Drupal::moduleHandler()
      ->alter([
      'sitemap_menu_tree',
      'sitemap_menu_tree_' . $alter_mid,
    ], $tree, $menu);
    $menu_display = \Drupal::service('sitemap.menu.link_tree')
      ->buildForSitemap($tree);
    $menu_html = \Drupal::service('renderer')
      ->render($menu_display);
    if (!empty($menu_html)) {

      // If the menu does not have a special Sitemap display name provided,
      // supply the default menu name.
      if (!empty($menu
        ->getThirdPartySetting('sitemap', 'sitemap_display_name'))) {
        $title = $menu
          ->getThirdPartySetting('sitemap', 'sitemap_display_name');
      }
      else {
        $title = $menu
          ->label();
      }
      \Drupal::service('sitemap.helper')
        ->setOption($options, 'show_titles', 1, 'show_titles', TRUE);
      $attributes
        ->addClass('sitemap-box-menu', 'sitemap-box-menu-' . $mid);
      $sitemap_box = [
        'title' => $title,
        'content' => $menu_html,
        'attributes' => $attributes,
        'options' => $options,
      ];
    }
  }
  return $sitemap_box;
}

/**
 * Count the number of published nodes classified by a term.
 *
 * This is a re-implementation of taxonomy_term_count_nodes() that has been
 * removed from D7 core.
 *
 * Implementation note: the normal way to count field instances is through
 * field_attach_query(), but taxonomy.module has a special denormalized
 * table taxonomy_index which we can use for more speed. THX to taxonews.
 *
 * @param string $tid
 *   The term's ID.
 *
 * @return string
 *   An integer representing a number of nodes. Results are statically cached.
 */
function sitemap_taxonomy_term_count_nodes($tid) {
  $query = db_select('taxonomy_index', 'ti');
  $query
    ->addExpression('COUNT(ti.nid)');
  $count = $query
    ->condition('ti.tid', $tid)
    ->execute()
    ->fetchCol();
  return $count[0];
}

/**
 * Implements hook_form_alter().
 */
function sitemap_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Apply the same form_alter both the add and edit forms.
  if ($form_id === 'menu_add_form' || $form_id === 'menu_edit_form') {
    sitemap_alter_menu_forms($form, $form_state, $form_id);
  }
}

/**
 * Handles the form alter for the menu_add_form and menu_edit_form forms to add
 * a settings field to the menu entity.
 */
function sitemap_alter_menu_forms(&$form, FormStateInterface $form_state, $form_id) {
  $menu = $form_state
    ->getFormObject()
    ->getEntity();
  $form['sitemap_display_name'] = [
    '#type' => 'textfield',
    '#title' => t('Sitemap display name'),
    '#description' => t('A user-friendly name for the menu that will display on the sitemap.'),
    '#default_value' => $menu
      ->getThirdPartySetting('sitemap', 'sitemap_display_name'),
    '#weight' => 1,
  ];
  if (isset($form['links'])) {
    $form['links']['#weight'] = 2;
  }
  $form['#entity_builders'][] = 'sitemap_form_menu_add_form_builder';
}

/**
 * Entity builder for the menu configuration entity.
 */
function sitemap_form_menu_add_form_builder($entity_type, Menu $menu, &$form, FormStateInterface $form_state) {
  if ($form_state
    ->getValue('sitemap_display_name')) {
    $menu
      ->setThirdPartySetting('sitemap', 'sitemap_display_name', $form_state
      ->getValue('sitemap_display_name'));
    return;
  }
}

Functions

Namesort descending Description
sitemap_alter_menu_forms Handles the form alter for the menu_add_form and menu_edit_form forms to add a settings field to the menu entity.
sitemap_form_alter Implements hook_form_alter().
sitemap_form_menu_add_form_builder Entity builder for the menu configuration entity.
sitemap_taxonomy_term_count_nodes Count the number of published nodes classified by a term.
sitemap_theme Implements hook_theme().
_sitemap_books Helper callback for the sitemap books.
_sitemap_front_page Helper callback for the sitemap front page.
_sitemap_menus Helper callback for the sitemap menus.