function node_access_rebuild

Same name in other branches
  1. 7.x modules/node/node.module \node_access_rebuild()
  2. 9 core/modules/node/node.module \node_access_rebuild()
  3. 10 core/modules/node/node.module \node_access_rebuild()
  4. 11.x core/modules/node/node.module \node_access_rebuild()

Rebuilds the node access database.

This rebuild is occasionally needed by modules that make system-wide changes to access levels. When the rebuild is required by an admin-triggered action (e.g module settings form), calling node_access_needs_rebuild(TRUE) instead of node_access_rebuild() lets the user perform changes and actually rebuild only once done.

Note : As of Drupal 6, node access modules are not required to (and actually should not) call node_access_rebuild() in hook_install/uninstall anymore.

Parameters

$batch_mode: (optional) Set to TRUE to process in 'batch' mode, spawning processing over several HTTP requests (thus avoiding the risk of PHP timeout if the site has a large number of nodes). hook_update_N() and any form submit handler are safe contexts to use the 'batch mode'. Less decidable cases (such as calls from hook_user(), hook_taxonomy(), etc.) might consider using the non-batch mode. Defaults to FALSE.

See also

node_access_needs_rebuild()

Related topics

28 calls to node_access_rebuild()
BookTest::setUp in core/modules/book/tests/src/Functional/BookTest.php
BulkFormAccessTest::setUp in core/modules/node/tests/src/Functional/Views/BulkFormAccessTest.php
CommentNodeAccessTest::setUp in core/modules/comment/tests/src/Functional/CommentNodeAccessTest.php
FilePrivateTest::setUp in core/modules/file/tests/src/Functional/FilePrivateTest.php
FilterNodeAccessTest::setUp in core/modules/node/tests/src/Functional/Views/FilterNodeAccessTest.php

... See full list

File

core/modules/node/node.module, line 1244

Code

function node_access_rebuild($batch_mode = FALSE) {
    $node_storage = \Drupal::entityTypeManager()->getStorage('node');
    
    /** @var \Drupal\node\NodeAccessControlHandlerInterface $access_control_handler */
    $access_control_handler = \Drupal::entityTypeManager()->getAccessControlHandler('node');
    $access_control_handler->deleteGrants();
    // Only recalculate if the site is using a node_access module.
    if (count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
        if ($batch_mode) {
            $batch = [
                'title' => t('Rebuilding content access permissions'),
                'operations' => [
                    [
                        '_node_access_rebuild_batch_operation',
                        [],
                    ],
                ],
                'finished' => '_node_access_rebuild_batch_finished',
            ];
            batch_set($batch);
        }
        else {
            // Try to allocate enough time to rebuild node grants
            Environment::setTimeLimit(240);
            // Rebuild newest nodes first so that recent content becomes available
            // quickly.
            $entity_query = \Drupal::entityQuery('node');
            $entity_query->sort('nid', 'DESC');
            // Disable access checking since all nodes must be processed even if the
            // user does not have access. And unless the current user has the bypass
            // node access permission, no nodes are accessible since the grants have
            // just been deleted.
            $entity_query->accessCheck(FALSE);
            $nids = $entity_query->execute();
            foreach ($nids as $nid) {
                $node_storage->resetCache([
                    $nid,
                ]);
                $node = Node::load($nid);
                // To preserve database integrity, only write grants if the node
                // loads successfully.
                if (!empty($node)) {
                    $grants = $access_control_handler->acquireGrants($node);
                    \Drupal::service('node.grant_storage')->write($node, $grants);
                }
            }
        }
    }
    else {
        // Not using any node_access modules. Add the default grant.
        $access_control_handler->writeDefaultGrant();
    }
    if (!isset($batch)) {
        \Drupal::messenger()->addStatus(t('Content permissions have been rebuilt.'));
        node_access_needs_rebuild(FALSE);
    }
}

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