You are here

function tracker_cron in Drupal 8

Same name and namespace in other branches
  1. 7 modules/tracker/tracker.module \tracker_cron()
  2. 9 core/modules/tracker/tracker.module \tracker_cron()

Implements hook_cron().

Updates tracking information for any items still to be tracked. The state 'tracker.index_nid' is set to ((the last node ID that was indexed) - 1) and used to select the nodes to be processed. If there are no remaining nodes to process, 'tracker.index_nid' will be 0. This process does not run regularly on live sites, rather it updates tracking info once on an existing site just after the tracker module was installed.

3 calls to tracker_cron()
TrackerNodeAccessTest::testTrackerNodeAccessIndexing in core/modules/tracker/tests/src/Functional/TrackerNodeAccessTest.php
Ensure that tracker_cron is not access sensitive.
TrackerTest::testTrackerCronIndexing in core/modules/tracker/tests/src/Functional/TrackerTest.php
Tests that existing nodes are indexed by cron.
tracker_install in core/modules/tracker/tracker.install
Implements hook_install().

File

core/modules/tracker/tracker.module, line 45
Tracks recent content posted by a user or users.

Code

function tracker_cron() {
  $state = \Drupal::state();
  $max_nid = $state
    ->get('tracker.index_nid') ?: 0;
  if ($max_nid > 0) {
    $last_nid = FALSE;
    $count = 0;
    $nids = \Drupal::entityQuery('node')
      ->accessCheck(FALSE)
      ->condition('nid', $max_nid, '<=')
      ->sort('nid', 'DESC')
      ->range(0, \Drupal::config('tracker.settings')
      ->get('cron_index_limit'))
      ->execute();
    $nodes = Node::loadMultiple($nids);
    $connection = \Drupal::database();
    foreach ($nodes as $nid => $node) {

      // Calculate the changed timestamp for this node.
      $changed = _tracker_calculate_changed($node);

      // Remove existing data for this node.
      $connection
        ->delete('tracker_node')
        ->condition('nid', $nid)
        ->execute();
      $connection
        ->delete('tracker_user')
        ->condition('nid', $nid)
        ->execute();

      // Insert the node-level data.
      $connection
        ->insert('tracker_node')
        ->fields([
        'nid' => $nid,
        'published' => (int) $node
          ->isPublished(),
        'changed' => $changed,
      ])
        ->execute();

      // Insert the user-level data for the node's author.
      $connection
        ->insert('tracker_user')
        ->fields([
        'nid' => $nid,
        'published' => (int) $node
          ->isPublished(),
        'changed' => $changed,
        'uid' => $node
          ->getOwnerId(),
      ])
        ->execute();

      // Insert the user-level data for the commenters (except if a commenter
      // is the node's author).
      // Get unique user IDs via entityQueryAggregate because it's the easiest
      // database agnostic way. We don't actually care about the comments here
      // so don't add an aggregate field.
      $result = \Drupal::entityQueryAggregate('comment')
        ->accessCheck(FALSE)
        ->condition('entity_type', 'node')
        ->condition('entity_id', $node
        ->id())
        ->condition('uid', $node
        ->getOwnerId(), '<>')
        ->condition('status', CommentInterface::PUBLISHED)
        ->groupBy('uid')
        ->execute();
      if ($result) {
        $query = $connection
          ->insert('tracker_user');
        foreach ($result as $row) {
          $query
            ->fields([
            'uid' => $row['uid'],
            'nid' => $nid,
            'published' => CommentInterface::PUBLISHED,
            'changed' => $changed,
          ]);
        }
        $query
          ->execute();
      }

      // Note that we have indexed at least one node.
      $last_nid = $nid;
      $count++;
    }
    if ($last_nid !== FALSE) {

      // Prepare a starting point for the next run.
      $state
        ->set('tracker.index_nid', $last_nid - 1);
      \Drupal::logger('tracker')
        ->notice('Indexed %count content items for tracking.', [
        '%count' => $count,
      ]);
    }
    else {

      // If all nodes have been indexed, set to zero to skip future cron runs.
      $state
        ->set('tracker.index_nid', 0);
    }
  }
}