Add registry_rebuild.php
This commit is contained in:
parent
3cb9f04441
commit
239a8a9e0a
247
web/registry_rebuild.php
Normal file
247
web/registry_rebuild.php
Normal file
|
@ -0,0 +1,247 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Root directory of Drupal installation. Note that you can change this
|
||||
* if you need to. It just has to point to the actual root. This assumes
|
||||
* that the php file is being run in sites/all/modules/registry_rebuild.
|
||||
*/
|
||||
|
||||
ini_set('memory_limit', -1);
|
||||
define('DRUPAL_ROOT', define_drupal_root());
|
||||
chdir(DRUPAL_ROOT);
|
||||
print "DRUPAL_ROOT is " . DRUPAL_ROOT . ".<br/>\n";
|
||||
define('MAINTENANCE_MODE', 'update');
|
||||
|
||||
global $_SERVER;
|
||||
$_SERVER['REMOTE_ADDR'] = 'nothing';
|
||||
|
||||
global $include_dir;
|
||||
$include_dir = DRUPAL_ROOT . '/includes';
|
||||
$module_dir = DRUPAL_ROOT . '/modules';
|
||||
// Use core directory if it exists.
|
||||
if (file_exists(DRUPAL_ROOT . '/core/includes/bootstrap.inc')) {
|
||||
$include_dir = DRUPAL_ROOT . '/core/includes';
|
||||
$module_dir = DRUPAL_ROOT . '/core/modules';
|
||||
}
|
||||
|
||||
require_once($include_dir . '/bootstrap.inc');
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
|
||||
|
||||
$includes = array(
|
||||
$include_dir . '/common.inc',
|
||||
$include_dir . '/database.inc',
|
||||
$include_dir . '/schema.inc',
|
||||
$include_dir . '/actions.inc',
|
||||
$include_dir . '/entity.inc',
|
||||
$module_dir . '/system/system.module',
|
||||
$include_dir . '/database/database.inc',
|
||||
$include_dir . '/database/query.inc',
|
||||
$include_dir . '/database/select.inc',
|
||||
$include_dir . '/registry.inc',
|
||||
$include_dir . '/module.inc',
|
||||
$include_dir . '/menu.inc',
|
||||
$include_dir . '/file.inc',
|
||||
$include_dir . '/theme.inc',
|
||||
$include_dir . '/locale.inc',
|
||||
);
|
||||
|
||||
if (function_exists('registry_rebuild')) { // == D7
|
||||
$cache_lock_path_absolute = variable_get('lock_inc');
|
||||
if (!empty($cache_lock_path_absolute)) {
|
||||
$cache_lock_path_relative = DRUPAL_ROOT . '/'. variable_get('lock_inc');
|
||||
// Ensure that the configured lock.inc really exists at that location and
|
||||
// is accessible. Otherwise we use the core lock.inc as fallback.
|
||||
if (is_readable($cache_lock_path_relative) && is_file($cache_lock_path_relative)) {
|
||||
$includes[] = $cache_lock_path_relative;
|
||||
print "We will use relative variant of lock.inc.<br/>\n";
|
||||
}
|
||||
elseif (is_readable($cache_lock_path_absolute) && is_file($cache_lock_path_absolute)) {
|
||||
$includes[] = $cache_lock_path_absolute;
|
||||
print "We will use absolute variant of lock.inc.<br/>\n";
|
||||
}
|
||||
else {
|
||||
print "We will use core implementation of lock.inc as fallback.<br/>\n";
|
||||
$includes[] = DRUPAL_ROOT . '/includes/lock.inc';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$includes[] = DRUPAL_ROOT . '/includes/lock.inc';
|
||||
}
|
||||
}
|
||||
elseif (!function_exists('cache_clear_all')) { // D8+
|
||||
// TODO
|
||||
// http://api.drupal.org/api/drupal/namespace/Drupal!Core!Lock/8
|
||||
$includes[] = $module_dir . '/entity/entity.module';
|
||||
$includes[] = $module_dir . '/entity/entity.controller.inc';
|
||||
}
|
||||
// In Drupal 6 the configured lock.inc is already loaded during
|
||||
// DRUSH_BOOTSTRAP_DRUPAL_DATABASE
|
||||
|
||||
foreach ($includes as $include) {
|
||||
if (file_exists($include)) {
|
||||
require_once($include);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('module_list')) {
|
||||
print "ERROR! Registry Rebuild requires a working Drupal site to operate on.<br/>\n";
|
||||
print "Please run this script from the correct Drupal site directory,<br/>\n";
|
||||
print "or specify Drupal root path on command line, for example:<br/>\n";
|
||||
print "php registry_rebuild.php --root=/path/to/drupal/root<br/>\n";
|
||||
print "BYE!<br/>\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
print "Bootstrapping to DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
|
||||
|
||||
registry_rebuild_rebuild();
|
||||
|
||||
/**
|
||||
* Find the drupal root directory by looking in parent directories.
|
||||
* If unable to discover it, fail and exit.
|
||||
*/
|
||||
function define_drupal_root() {
|
||||
$args = getopt(NULL, array('root::'));
|
||||
if (!empty($args['root'])) {
|
||||
return $args['root'];
|
||||
}
|
||||
|
||||
// This is the smallest number of directories to go up: from /sites/all/modules/registry_rebuild.
|
||||
$parent_count = 4;
|
||||
// 8 seems reasonably far to go looking up.
|
||||
while ($parent_count < 8) {
|
||||
$dir = realpath(getcwd() . str_repeat('/..', $parent_count));
|
||||
if (file_exists($dir . '/index.php')) {
|
||||
return $dir;
|
||||
}
|
||||
$parent_count++;
|
||||
}
|
||||
print "Failure: Unable to discover DRUPAL_ROOT. You may want to explicitly define it near the top of registry_rebuild.php";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before calling this we need to be bootstrapped to DRUPAL_BOOTSTRAP_SESSION.
|
||||
*/
|
||||
function registry_rebuild_rebuild() {
|
||||
// This section is not functionally important. It's just using the
|
||||
// registry_get_parsed_files() so that it can report the change. Drupal 7 only.
|
||||
if (function_exists('registry_rebuild')) {
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
$driver = $connection_info['default']['driver'];
|
||||
global $include_dir;
|
||||
require_once $include_dir . '/database/' . $driver . '/query.inc';
|
||||
$parsed_before = registry_get_parsed_files();
|
||||
}
|
||||
|
||||
// Separate bootstrap cache exists only in Drupal 7 or newer.
|
||||
// They are cleared later again via drupal_flush_all_caches().
|
||||
if (function_exists('registry_rebuild')) { // D7
|
||||
cache_clear_all('lookup_cache', 'cache_bootstrap');
|
||||
cache_clear_all('variables', 'cache_bootstrap');
|
||||
cache_clear_all('module_implements', 'cache_bootstrap');
|
||||
print "Bootstrap caches have been cleared in DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
}
|
||||
elseif (!function_exists('cache_clear_all')) { // D8+
|
||||
cache('bootstrap')->deleteAll();
|
||||
print "Bootstrap caches have been cleared in DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
}
|
||||
|
||||
// We later run system_rebuild_module_data() and registry_update() on Drupal 7 via
|
||||
// D7-only registry_rebuild() wrapper, which is run inside drupal_flush_all_caches().
|
||||
// It is an equivalent of module_rebuild_cache() in D5-D6 and is normally run via
|
||||
// our universal wrapper registry_rebuild_cc_all() -- see further below.
|
||||
// However, we are still on the DRUPAL_BOOTSTRAP_SESSION level here,
|
||||
// and we want to make the initial rebuild as atomic as possible, so we can't
|
||||
// run everything from registry_rebuild_cc_all() yet, so we run an absolute
|
||||
// minimum we can at this stage, core specific.
|
||||
if (function_exists('registry_rebuild')) { // D7 only
|
||||
print "Doing registry_rebuild() in DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
registry_rebuild();
|
||||
}
|
||||
elseif (!function_exists('registry_rebuild') && function_exists('system_rebuild_module_data')) { // D8+
|
||||
print "Doing system_rebuild_module_data() in DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
system_rebuild_module_data();
|
||||
}
|
||||
else { // D5-D6
|
||||
print "Doing module_rebuild_cache() in DRUPAL_BOOTSTRAP_SESSION<br/>\n";
|
||||
module_list(TRUE, FALSE);
|
||||
module_rebuild_cache();
|
||||
}
|
||||
|
||||
print "Bootstrapping to DRUPAL_BOOTSTRAP_FULL<br/>\n";
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
|
||||
// We can run our wrapper now, since we are in a full bootstrap already.
|
||||
print "Rebuilding registry via registry_rebuild_cc_all in DRUPAL_BOOTSTRAP_FULL<br/>\n";
|
||||
registry_rebuild_cc_all();
|
||||
|
||||
// Extra cleanup available for D7 only.
|
||||
if (function_exists('registry_rebuild')) {
|
||||
$parsed_after = registry_get_parsed_files();
|
||||
// Remove files which don't exist anymore.
|
||||
$filenames = array();
|
||||
foreach ($parsed_after as $filename => $file) {
|
||||
if (!file_exists($filename)) {
|
||||
$filenames[] = $filename;
|
||||
}
|
||||
}
|
||||
if (!empty($filenames)) {
|
||||
db_delete('registry_file')
|
||||
->condition('filename', $filenames)
|
||||
->execute();
|
||||
db_delete('registry')
|
||||
->condition('filename', $filenames)
|
||||
->execute();
|
||||
print("Deleted " . count($filenames) . ' stale files from registry manually.');
|
||||
}
|
||||
$parsed_after = registry_get_parsed_files();
|
||||
print "There were " . count($parsed_before) . " files in the registry before and " . count($parsed_after) . " files now.<br/>\n";
|
||||
registry_rebuild_cc_all();
|
||||
}
|
||||
print "If you don't see any crazy fatal errors, your registry has been rebuilt.<br/>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Registry Rebuild needs to aggressively clear all caches,
|
||||
* not just some bins (at least to attempt it) also *before*
|
||||
* attempting to rebuild registry, or it may not be able
|
||||
* to fix the problem at all, if it relies on some cached
|
||||
* and no longer valid data/paths etc. This problem has been
|
||||
* confirmed and reproduced many times with option --fire-bazooka
|
||||
* which is available only in the Drush variant, but it confirms
|
||||
* the importance of starting with real, raw and not cached
|
||||
* in any way site state. While the --no-cache-clear option
|
||||
* still disables this procedure, --fire-bazooka takes precedence
|
||||
* and forces all caches clear action. All caches are cleared
|
||||
* by default in the PHP script variant.
|
||||
*/
|
||||
function registry_rebuild_cc_all() {
|
||||
module_invoke_all('pre_flush_all_caches');
|
||||
if (function_exists('cache_clear_all')) {
|
||||
cache_clear_all('*', 'cache', TRUE);
|
||||
cache_clear_all('*', 'cache_form', TRUE);
|
||||
}
|
||||
else {
|
||||
cache('cache')->deleteAll();
|
||||
cache('cache_form')->deleteAll();
|
||||
}
|
||||
|
||||
module_invoke_all('pre_flush_all_caches');
|
||||
|
||||
if (function_exists('module_rebuild_cache')) { // D5-D6
|
||||
module_list(TRUE, FALSE);
|
||||
module_rebuild_cache();
|
||||
}
|
||||
|
||||
if (function_exists('drupal_flush_all_caches')) { // D6+
|
||||
drupal_flush_all_caches();
|
||||
}
|
||||
else { // D5
|
||||
cache_clear_all();
|
||||
system_theme_data();
|
||||
node_types_rebuild();
|
||||
menu_rebuild();
|
||||
}
|
||||
print "All caches have been cleared with registry_rebuild_cc_all.<br/>\n";
|
||||
}
|
Reference in a new issue