You are here

public function XmlSitemapGenerator::generateChunk in XML sitemap 8

Same name and namespace in other branches
  1. 2.x src/XmlSitemapGenerator.php \Drupal\xmlsitemap\XmlSitemapGenerator::generateChunk()

Generates one chunk of the sitemap.

Parameters

\Drupal\xmlsitemap\XmlSitemapInterface $sitemap: The XML sitemap config entity.

\Drupal\xmlsitemap\XmlSitemapWriter $writer: XML writer object.

int $chunk: Chunk value.

Overrides XmlSitemapGeneratorInterface::generateChunk

1 call to XmlSitemapGenerator::generateChunk()
XmlSitemapGenerator::generatePage in src/XmlSitemapGenerator.php
Generate one page (chunk) of the sitemap.

File

src/XmlSitemapGenerator.php, line 264

Class

XmlSitemapGenerator
XmlSitemap generator service class.

Namespace

Drupal\xmlsitemap

Code

public function generateChunk(XmlSitemapInterface $sitemap, XmlSitemapWriter $writer, $chunk) {
  $lastmod_format = $this->config
    ->get('lastmod_format');
  $url_options = $sitemap->uri['options'];
  $url_options += [
    'absolute' => TRUE,
    'base_url' => rtrim(Settings::get('xmlsitemap_base_url', $this->state
      ->get('xmlsitemap_base_url')), '/'),
    'language' => $this->languageManager
      ->getDefaultLanguage(),
    // @todo Figure out a way to bring back the alias preloading optimization.
    // 'alias' => $this->config->get('prefetch_aliases'),
    'alias' => FALSE,
  ];
  $last_url = '';
  $link_count = 0;
  $query = $this->connection
    ->select('xmlsitemap', 'x');
  $query
    ->fields('x', [
    'loc',
    'type',
    'subtype',
    'id',
    'lastmod',
    'changefreq',
    'changecount',
    'priority',
    'language',
    'access',
    'status',
  ]);
  $query
    ->condition('x.access', 1);
  $query
    ->condition('x.status', 1);
  $query
    ->orderBy('x.language', 'DESC');
  $query
    ->orderBy('x.loc');
  $query
    ->addTag('xmlsitemap_generate');
  $query
    ->addMetaData('sitemap', $sitemap);
  $offset = max($chunk - 1, 0) * xmlsitemap_get_chunk_size();
  $limit = xmlsitemap_get_chunk_size();
  $query
    ->range($offset, $limit);
  $links = $query
    ->execute();
  while ($link = $links
    ->fetchAssoc()) {

    // Preserve the language code for hook_xmlsitemap_element_alter().
    $link['langcode'] = $link['language'];
    $link['language'] = $link['language'] != LanguageInterface::LANGCODE_NOT_SPECIFIED ? xmlsitemap_language_load($link['language']) : $url_options['language'];
    $link_options = [
      'language' => $link['language'],
      'xmlsitemap_link' => $link,
      'xmlsitemap_sitemap' => $sitemap,
    ];

    // Ensure every link starts with a slash.
    // @see \Drupal\Core\Url::fromInternalUri()
    if ($link['loc'][0] !== '/') {
      trigger_error("The XML sitemap link path {$link['loc']} for {$link['type']} {$link['id']} is invalid because it does not start with a slash.", E_USER_ERROR);
      $link['loc'] = '/' . $link['loc'];
    }

    // @todo Add a separate hook_xmlsitemap_link_url_alter() here?
    $link_url = Url::fromUri('internal:' . $link['loc'], $link_options + $url_options)
      ->toString();

    // Skip this link if it was a duplicate of the last one.
    // @todo Figure out a way to do this before generation so we can report
    // back to the user about this.
    if ($link_url == $last_url) {
      continue;
    }
    else {
      $last_url = $link_url;

      // Keep track of the total number of links written.
      $link_count++;
    }
    $element = [];
    $element['loc'] = $link_url;
    if ($link['lastmod']) {
      $element['lastmod'] = gmdate($lastmod_format, $link['lastmod']);

      // If the link has a lastmod value, update the changefreq so that links
      // with a short changefreq but updated two years ago show decay.
      // We use abs() here just incase items were created on this same cron
      // run because lastmod would be greater than the request time.
      $link['changefreq'] = (abs($this->time
        ->getRequestTime() - $link['lastmod']) + $link['changefreq']) / 2;
    }
    if ($link['changefreq']) {
      $element['changefreq'] = xmlsitemap_get_changefreq($link['changefreq']);
    }
    if (isset($link['priority']) && $link['priority'] != 0.5) {

      // Don't output the priority value for links that have 0.5 priority.
      // This is the default 'assumed' value if priority is not included as
      // per the sitemaps.org specification.
      $element['priority'] = number_format($link['priority'], 1);
    }

    // @todo Should this be moved to XMLSitemapWriter::writeSitemapElement()?
    $this->moduleHandler
      ->alter('xmlsitemap_element', $element, $link, $sitemap);
    $writer
      ->writeElement('url', $element);
  }
  return $link_count;
}