function tracker_cron

Same name in other branches
  1. 7.x modules/tracker/tracker.module \tracker_cron()
  2. 9 core/modules/tracker/tracker.module \tracker_cron()
  3. 8.9.x core/modules/tracker/tracker.module \tracker_cron()
  4. 10 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 44

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);
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.