Created
December 3, 2014 23:47
-
-
Save deekayen/85fd52c56da2836b7d3d to your computer and use it in GitHub Desktop.
Rebuild node access permissions in Drupal 6 using drush.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Drush code to rebuild node access. | |
*/ | |
/** | |
* Implementation of hook_drush_command(). | |
*/ | |
function dnar_drush_command() { | |
$items = array(); | |
$items['node-access-rebuild'] = array( | |
'callback' => 'dnar_drush_node_access_rebuild', | |
'description' => dt('Rebuild node access perrmissions.'), | |
'examples' => array( | |
'drush node-access-rebuild' => dt('Rebuild the node permissions'), | |
), | |
'aliases' => array('dnar'), | |
); | |
return $items; | |
} | |
/** | |
* Implementation of hook_drush_help(). | |
*/ | |
function dnar_drush_help($section) { | |
switch ($section) { | |
case 'drush:node-access-rebuild': | |
return dt('Rebuild node access permissions.'); | |
} | |
} | |
function dnar_drush_node_access_rebuild() { | |
// Try to allocate enough time to rebuild node grants | |
if (function_exists('set_time_limit')) { | |
@set_time_limit(0); | |
} | |
ini_set('memory_limit', '1800M'); | |
// Remove orphaned nodes. | |
db_query("DELETE na.* FROM {node_access} AS na LEFT JOIN {node} AS n USING (nid) WHERE n.nid IS NULL | |
AND na.nid <> 0"); | |
$changed = db_affected_rows(); | |
drush_log(dt('@count orphaned node records removed from the node access table.', array('@count' => $changed)), 'ok'); | |
// Get a list of nodes. | |
$good = array(); | |
$bad = array(); | |
// We have 2 passes; first pass is for missing node_access entries. | |
// Second pass is a general refresh. | |
$sql_commands = array( | |
'missing' => array( | |
'count' => 'SELECT COUNT(n.nid) FROM {node} AS n LEFT JOIN {node_access} AS na USING (nid) WHERE na.nid IS NULL', | |
'results' => 'SELECT n.nid FROM {node} AS n LEFT JOIN {node_access} AS na USING (nid) WHERE na.nid IS NULL ORDER BY n.nid DESC', | |
), | |
'full refresh' => array( | |
'count' => 'SELECT COUNT(*) FROM {node} AS n', | |
'results' => 'SELECT n.nid FROM {node} AS n ORDER BY n.nid DESC', | |
), | |
); | |
// Do the dirty work. | |
foreach ($sql_commands AS $type => $command) { | |
$count = db_result(db_query($command['count'])); | |
drush_log(dt('Going to process @count nodes. Mode: @mode.', array('@count' => $count, '@mode' => $type)), 'ok'); | |
$result = db_query($command['results']); | |
timer_start('rebuild'); | |
while ($node = db_fetch_object($result)) { | |
// Skip nodes we already hit. | |
if (isset($good[$node->nid])) { | |
continue; | |
} | |
// Load the node. | |
$loaded_node = node_load($node->nid, NULL, TRUE); | |
// Remove old records for this node. | |
db_query("DELETE FROM {node_access} WHERE nid = %d", $node->nid); | |
// To preserve database integrity, only aquire grants if the node | |
// loads successfully. | |
if (!empty($loaded_node)) { | |
// Set node access. | |
node_access_acquire_grants($loaded_node); | |
$good[$node->nid] = TRUE; | |
// Output a * every 5 nodes. | |
if (count($good) % 5 == 0) { | |
print('*'); | |
} | |
// Check if a status update is needed every 100 nodes. | |
if (count($good) > 500 && count($good) % 100 == 0) { | |
// Convert time from ms to seconds. | |
$running_time = timer_read('rebuild')/1000; | |
// Output status update every 100 seconds. | |
if (round($running_time, -1) % 100 == 0) { | |
$eta = $running_time * count($good) / $count; | |
print("\n"); | |
drush_log(dt('@count of @good nodes have had their permissions rebuild. ETA: @time. Current NID: @nid.', | |
array( | |
'@count' => count($good), | |
'@good' => $count, | |
'@time' => format_interval(round($eta)) . ' ' . round($running_time, -1), | |
'@nid' => $node->nid, | |
) | |
), 'ok'); | |
} | |
} | |
} | |
else { | |
$bad[$node->nid] = TRUE; | |
print('!'); | |
} | |
} | |
drush_log(dt('Rebuilt permissions for @count nodes. @good where correctly rebuild, @bad failed on the node load. Here is a list of the bad nodes: @badlist', | |
array( | |
'@count' => $count, | |
'@good' => count($good), | |
'@bad' => count($bad), | |
'@badlist' => implode("\n", $bad), | |
) | |
), 'ok'); | |
} | |
node_access_needs_rebuild(FALSE); | |
cache_clear_all(); | |
drush_log(dt('Block and page caches cleared.'), 'ok'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name = Drush node access rebuild | |
description = Use Drush to rebuild node access permissions. | |
core = 6.x |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Disable Core's Node Rebuild. | |
*/ | |
/** | |
* Implementation of hook_menu_alter(). | |
*/ | |
function dnar_menu_alter(&$items) { | |
// Disable node access rebuilding from the web. | |
$items['admin/content/node-settings/rebuild']['page arguments'] = array(); | |
$items['admin/content/node-settings/rebuild']['page callback'] = 'dnar_rebuild_message'; | |
} | |
/** | |
* Output some interesting info. | |
*/ | |
function dnar_rebuild_message() { | |
$output = ''; | |
$output = t('Rebuilding the permissions on this site can only be done from drush. "%command" is the command. There are %orphaned orphaned node records in the node access table. There are %missing missing records from the node access table.', array( | |
'%command' => 'drush node-access-rebuild', | |
'%orphaned' => db_result(db_query("SELECT COUNT(*) FROM {node_access} AS na LEFT JOIN {node} AS n USING (nid) WHERE n.nid IS NULL AND na.nid <> 0")), | |
'%missing' => db_result(db_query("SELECT COUNT(nid) FROM {node} AS n LEFT JOIN {node_access} AS na USING (nid) WHERE na.nid IS NULL")), | |
)); | |
return $output; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment