199 lines
6.5 KiB
Plaintext
199 lines
6.5 KiB
Plaintext
<?php
|
|
|
|
use Drupal\xautoload\ClassLoader\ApcClassLoader;
|
|
use Drupal\xautoload\ClassLoader\ApcuClassLoader;
|
|
use Drupal\xautoload\ClassLoader\ApcuQueuedCachedClassLoader;
|
|
use Drupal\xautoload\ClassLoader\DbCacheClassLoader;
|
|
use Drupal\xautoload\ClassLoader\WinCacheClassLoader;
|
|
use Drupal\xautoload\ClassLoader\XCacheClassLoader;
|
|
use Drupal\xautoload\CacheMissObserver\CacheMissLoaderSetFinder;
|
|
|
|
/*
|
|
* When the module has just been installed,
|
|
* Drupal does not know yet this is a boot-level module.
|
|
*
|
|
* We can not rely on hook_boot() to fire, and instead register the autoloader
|
|
* on inclusion of this *.module file.
|
|
*/
|
|
_xautoload_register_drupal();
|
|
|
|
|
|
// Hook implementations
|
|
// -----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Implements hook_boot()
|
|
*
|
|
* This is only to let Drupal know we want this module to load in bootstrap.
|
|
*/
|
|
function xautoload_boot() {}
|
|
|
|
/**
|
|
* Implements hook_custom_theme()
|
|
*
|
|
* We only do this because that's the first hook to fire after bootstrap.
|
|
*/
|
|
function xautoload_custom_theme() {
|
|
xautoload()->phaseControl->enterMainPhase();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_init()
|
|
*
|
|
* Note:
|
|
* This is a first step to allow modules to register foreign namespaces.
|
|
* We will probably change this, to allow bootstrap modules to register their
|
|
* namespaces earlier in the request.
|
|
* We might also find a solution to cache the result of this hook between
|
|
* requests. This would require a different implementation of the InjectedAPI,
|
|
* which would no longer have a direct reference to the finder object.
|
|
*/
|
|
function xautoload_init() {
|
|
xautoload()->phaseControl->enterMainPhase();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_system_theme_info().
|
|
*
|
|
* This is the first hook to fire on update.php.
|
|
*
|
|
* Unfortunately, hook_custom_theme() and hook_init() are not called on
|
|
* update.php in _drupal_bootstrap_full().
|
|
*
|
|
* But in list_themes(), _system_rebuild_theme_data() is always called in
|
|
* maintenance mode. And from there, hook_system_theme_info().
|
|
*
|
|
* @see _drupal_bootstrap_full()
|
|
* @see list_themes()
|
|
*/
|
|
function xautoload_system_theme_info() {
|
|
xautoload()->phaseControl->enterMainPhase();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_module_implements_alter()
|
|
*
|
|
* @param array &$implementations
|
|
* @param string $hook
|
|
*/
|
|
function xautoload_module_implements_alter(&$implementations, $hook) {
|
|
|
|
// Check if new modules have been enabled.
|
|
if ('boot' === $hook) {
|
|
|
|
# \Drupal\xautoload\Tests\HackyLog::log($hook);
|
|
// hook_module_implements_alter('boot') gets called (indirectly) from
|
|
// _system_update_bootstrap_status(), which happens each time a new module
|
|
// is enabled.
|
|
xautoload()->phaseControl->checkNewExtensions();
|
|
}
|
|
|
|
// Most hook implementations are in dedicated files.
|
|
switch ($hook) {
|
|
case 'init':
|
|
case 'custom_theme':
|
|
case 'system_theme_info':
|
|
// Move xautoload_$hook() to the start.
|
|
$implementations = array('xautoload' => FALSE) + $implementations;
|
|
break;
|
|
case 'form_system_performance_settings_alter':
|
|
// Specify that the implementation lives in xautoload.ui.inc.
|
|
$implementations['xautoload'] = 'ui';
|
|
require_once __DIR__ . '/xautoload.ui.inc';
|
|
break;
|
|
case 'modules_enabled':
|
|
case 'registry_files_alter':
|
|
// Move xautoload_$hook() to the start, and specify that the
|
|
// implementation lives in xautoload.system.inc.
|
|
$implementations = array('xautoload' => 'system') + $implementations;
|
|
require_once __DIR__ . '/xautoload.system.inc';
|
|
break;
|
|
case 'libraries_info_alter':
|
|
$implementations['xautoload'] = 'libraries';
|
|
require_once __DIR__ . '/xautoload.libraries.inc';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// "Private" functions.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Registers Drupal-related namespaces and prefixes in the xautoload loader, and
|
|
* activates the APC (or similar) cache, if enabled.
|
|
*/
|
|
function _xautoload_register_drupal() {
|
|
|
|
// Check that this runs only once.
|
|
static $_first_run = TRUE;
|
|
if (!$_first_run) {
|
|
return;
|
|
}
|
|
$_first_run = FALSE;
|
|
|
|
// Register the class loader itself.
|
|
require_once __DIR__ . '/xautoload.early.lib.inc';
|
|
_xautoload_register();
|
|
|
|
$services = xautoload()->getServiceContainer();
|
|
|
|
if ($services->system->variableGet(XAUTOLOAD_VARNAME_REPLACE_CORE)) {
|
|
/**
|
|
* Completely take over.
|
|
*
|
|
* @see _drupal_bootstrap_database()
|
|
* @see drupal_autoload_class()
|
|
* @see drupal_autoload_interface()
|
|
*/
|
|
spl_autoload_unregister('drupal_autoload_class');
|
|
spl_autoload_unregister('drupal_autoload_interface');
|
|
}
|
|
|
|
$lazy = $services->system->variableGet(XAUTOLOAD_VARNAME_CACHE_LAZY, FALSE);
|
|
$decorated = $lazy
|
|
? $services->proxyFinder
|
|
: $services->proxyFinder->getFinder()
|
|
;
|
|
|
|
// Activate a cache, if available and enabled.
|
|
$cache_types = $services->system->variableGet(XAUTOLOAD_VARNAME_CACHE_TYPES, array());
|
|
if (!empty($cache_types['apcu_q']) && extension_loaded('apcu') && function_exists('apcu_store')) {
|
|
$cached_loader = ApcuQueuedCachedClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
elseif (!empty($cache_types['apc']) && extension_loaded('apc') && function_exists('apc_store')) {
|
|
$cached_loader = ApcClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
/** @noinspection NotOptimalIfConditionsInspection */
|
|
elseif (!empty($cache_types['apcu']) && extension_loaded('apcu') && function_exists('apcu_store')) {
|
|
$cached_loader = ApcuClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
elseif (!empty($cache_types['wincache']) && extension_loaded('wincache') && function_exists('wincache_ucache_get')) {
|
|
$cached_loader = WinCacheClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
elseif (!empty($cache_types['xcache']) && extension_loaded('Xcache') && function_exists('xcache_get')) {
|
|
$cached_loader = XCacheClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
elseif (!empty($cache_types['dbcache'])) {
|
|
$cached_loader = DbCacheClassLoader::create($decorated, $services->cacheManager);
|
|
}
|
|
|
|
if (isset($cached_loader)) {
|
|
if ($lazy) {
|
|
$decorated->observeFirstCacheMiss(new CacheMissLoaderSetFinder($cached_loader));
|
|
}
|
|
$cached_loader->register();
|
|
$services->finder->unregister();
|
|
}
|
|
else {
|
|
// No cache is active.
|
|
// Initialize the finder, to fire scheduled operations.
|
|
$services->proxyFinder->getFinder();
|
|
}
|
|
|
|
// Register prefixes and namespaces for enabled extensions.
|
|
$services->proxyFinder->observeFirstCacheMiss($services->phaseControl);
|
|
}
|