Ejemplo n.º 1
0
 /**
  * Initialise caches, always call before accessing self:: caches.
  */
 protected static function init()
 {
     global $CFG;
     // Init only once per request/CLI execution, we ignore changes done afterwards.
     if (isset(self::$plugintypes)) {
         return;
     }
     if (defined('IGNORE_COMPONENT_CACHE') and IGNORE_COMPONENT_CACHE) {
         self::fill_all_caches();
         return;
     }
     if (!empty($CFG->alternative_component_cache)) {
         // Hack for heavily clustered sites that want to manage component cache invalidation manually.
         $cachefile = $CFG->alternative_component_cache;
         if (file_exists($cachefile)) {
             if (CACHE_DISABLE_ALL) {
                 // Verify the cache state only on upgrade pages.
                 $content = self::get_cache_content();
                 if (sha1_file($cachefile) !== sha1($content)) {
                     die('Outdated component cache file defined in $CFG->alternative_component_cache, can not continue');
                 }
                 return;
             }
             $cache = array();
             include $cachefile;
             self::$plugintypes = $cache['plugintypes'];
             self::$plugins = $cache['plugins'];
             self::$subsystems = $cache['subsystems'];
             self::$parents = $cache['parents'];
             self::$subplugins = $cache['subplugins'];
             self::$classmap = $cache['classmap'];
             self::$filemap = $cache['filemap'];
             return;
         }
         if (!is_writable(dirname($cachefile))) {
             die('Can not create alternative component cache file defined in $CFG->alternative_component_cache, can not continue');
         }
         // Lets try to create the file, it might be in some writable directory or a local cache dir.
     } else {
         // Note: $CFG->cachedir MUST be shared by all servers in a cluster,
         //       use $CFG->alternative_component_cache if you do not like it.
         $cachefile = "{$CFG->cachedir}/core_component.php";
     }
     if (!CACHE_DISABLE_ALL and !self::is_developer()) {
         // 1/ Use the cache only outside of install and upgrade.
         // 2/ Let developers add/remove classes in developer mode.
         if (is_readable($cachefile)) {
             $cache = false;
             include $cachefile;
             if (!is_array($cache)) {
                 // Something is very wrong.
             } else {
                 if (!isset($cache['version'])) {
                     // Something is very wrong.
                 } else {
                     if ((double) $cache['version'] !== (double) self::fetch_core_version()) {
                         // Outdated cache. We trigger an error log to track an eventual repetitive failure of float comparison.
                         error_log('Resetting core_component cache after core upgrade to version ' . self::fetch_core_version());
                     } else {
                         if ($cache['plugintypes']['mod'] !== "{$CFG->dirroot}/mod") {
                             // $CFG->dirroot was changed.
                         } else {
                             // The cache looks ok, let's use it.
                             self::$plugintypes = $cache['plugintypes'];
                             self::$plugins = $cache['plugins'];
                             self::$subsystems = $cache['subsystems'];
                             self::$parents = $cache['parents'];
                             self::$subplugins = $cache['subplugins'];
                             self::$classmap = $cache['classmap'];
                             self::$filemap = $cache['filemap'];
                             return;
                         }
                     }
                 }
             }
             // Note: we do not verify $CFG->admin here intentionally,
             //       they must visit admin/index.php after any change.
         }
     }
     if (!isset(self::$plugintypes)) {
         // This needs to be atomic and self-fixing as much as possible.
         $content = self::get_cache_content();
         if (file_exists($cachefile)) {
             if (sha1_file($cachefile) === sha1($content)) {
                 return;
             }
             // Stale cache detected!
             unlink($cachefile);
         }
         // Permissions might not be setup properly in installers.
         $dirpermissions = !isset($CFG->directorypermissions) ? 02777 : $CFG->directorypermissions;
         $filepermissions = !isset($CFG->filepermissions) ? $dirpermissions & 0666 : $CFG->filepermissions;
         clearstatcache();
         $cachedir = dirname($cachefile);
         if (!is_dir($cachedir)) {
             mkdir($cachedir, $dirpermissions, true);
         }
         if ($fp = @fopen($cachefile . '.tmp', 'xb')) {
             fwrite($fp, $content);
             fclose($fp);
             @rename($cachefile . '.tmp', $cachefile);
             @chmod($cachefile, $filepermissions);
         }
         @unlink($cachefile . '.tmp');
         // Just in case anything fails (race condition).
         self::invalidate_opcode_php_cache($cachefile);
     }
 }