万源之源之drupal 之 drupal_flush_all_caches
(注:学习笔记,仅学习交流用,如果有错误的地方,在您方便的情况下指正一下,万分感激!)
<?php function drupal_flush_all_caches(){ // Change query-strings on css/js files to enforce reload for all users. _drupal_flush_css_js(); /** |->variable_set('css_js_query_string', base_convert(REQUEST_TIME, 10, 36)); */ //重新构建所有的注册信息。 registry_rebuild(); /** 重新构建所有的modules数据,并且缓存 |->system_rebuild_module_data(); 在网站的目录(module, sites/all/module,还有系统自定义的profile下的modules)下找到所有的module |->$modules = _system_rebuild_module_data(); 通过数据库system表,把$modules 中不存在的信息放到这里(以为上面得到的仅仅是通过文件(比如module.info) 得到的信息,这里把数据库里相应的module信息放到这里缓存) |->system_get_files_database($modules, 'module') 更新数据库system表中$modules的信息, 把 不存数据库中的 或者 改变的 或者 有数据但是没相应module文件 的 信息的值做相应修改(insert,update,delete) |->system_update_files_database($modules, 'module'); Updates the registry based on the latest files listed in the database. 作用是更新注册表(registry(网站内所有的class,interface), registry_file(网站内所有的module files,和 include文件夹里面的所有的.inc文件,和他们的hash_file))的信息, 清空一些静态变量 |->registry_update(); //得到当前运行模式是不是安装的模式 |->$in_installer = drupal_installation_attempted(); //如果不是 installer模式,验证是否正在被重新构建,如果正在被重新构建,则延时锁并且返回false,保证同一时间 只有一个重建的进程。 |->if (!$in_installer && !lock_acquire(__FUNCTION__)) //更新注册表 |->_registry_update(); 在68行:找到网站内所有的文件后,并且在system表里得到了所有的modules,触发了registry_files(alter) 然后再更新的注册表信息 |-> drupal_alter('registry_files', $files, $modules); ////最后在清空一些静态变量 Determines(确认) which modules are implementing(实现) a hook. //在这里调用这个函数,仅仅是清除 module 的 implements,如代码 |->module_implements('', FALSE, TRUE);//module_implements($hook, $sort = FALSE, $reset = FALSE) |-> static $drupal_static_fast; if (!isset($drupal_static_fast)) { $drupal_static_fast['implementations'] = &drupal_static(__FUNCTION__); } $implementations = &$drupal_static_fast['implementations']; if ($reset) { $implementations = array(); cache_set('module_implements', array(), 'cache_bootstrap'); drupal_static_reset('module_hook_info'); drupal_static_reset('drupal_alter'); cache_clear_all('hook_info', 'cache_bootstrap'); return; } Checks for a resource in the registry.(检查注册表中的资源) //在这里调用,仅仅是清除 函数中的静态变量 $lookup_cache和$cache_update_needed |->_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE); -> static $lookup_cache, $cache_update_needed; if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name)) { return TRUE; } if (!isset($lookup_cache)) { $lookup_cache = array(); if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) { $lookup_cache = $cache->data; } } // When we rebuild the registry, we need to reset this cache so // we don't keep lookups for resources that changed during the rebuild. if ($type == REGISTRY_RESET_LOOKUP_CACHE) { $cache_update_needed = TRUE; $lookup_cache = NULL; return; } //如果不是 installer 模式, 则解锁本函数。代表本次重构成功。 |-> lock_release(__FUNCTION__); */ drupal_clear_css_cache(); // |-> // variable_del('drupal_css_cache_files'); // file_scan_directory('public://css', '/.*/', array('callback' => 'drupal_delete_file_if_stale')); //*/ drupal_clear_js_cache(); // |-> // variable_del('javascript_parsed'); // variable_del('drupal_js_cache_files'); // file_scan_directory('public://js', '/.*/', array('callback' => 'drupal_delete_file_if_stale')); //*/ // Rebuild the theme data. Note that the module data is rebuilt above, as // part of registry_rebuild(). system_rebuild_theme_data(); /** 根据文件(.info),整理并且得到所有的themes 信息 |->$themes = _system_rebuild_theme_data(); //在 themes 下找到所有的 .info 文件,每个info文件代表一个theme |->$themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'themes'); |-> 这里触发了 system_theme_info hook,允许module修改主题信息。 // Allow modules to add further themes. if ($module_themes = module_invoke_all('system_theme_info')) { foreach ($module_themes as $name => $uri) { // @see file_scan_directory() $themes[$name] = (object) array( 'uri' => $uri, 'filename' => pathinfo($uri, PATHINFO_FILENAME), 'name' => $name, ); } } |->// Find theme engines $engines = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines'); |->在这设置了 theme 默认的 info信息 $defaults = array( 'engine' => 'phptemplate', 'regions' => array( 'sidebar_first' => 'Left sidebar', 'sidebar_second' => 'Right sidebar', 'content' => 'Content', 'header' => 'Header', 'footer' => 'Footer', 'highlighted' => 'Highlighted', 'help' => 'Help', 'page_top' => 'Page top', 'page_bottom' => 'Page bottom', ), 'description' => '', 'features' => _system_default_theme_features(), 'screenshot' => 'screenshot.png', 'php' => DRUPAL_MINIMUM_PHP, 'stylesheets' => array(), 'scripts' => array(), ); |-> 在整理 themes 循环中,触发了 system_info_alter hook ,可以修改相应的主题信息 $type = 'theme'; drupal_alter('system_info', $themes[$key]->info, $themes[$key], $type); |-> 剩下的就是整理base theme 和 其他的一些theme信息 通过数据库system表,把$themes 中不存在的信息放到这里(以为上面得到的仅仅是通过文件(比如theme.info) 得到的信息,这里把数据库里相应的module信息放到这里缓存) |->system_get_files_database($themes, 'theme') 更新数据库system表中$themes的信息, 把 不存数据库中的 或者 改变的 或者 有数据但是没相应theme文件 的 信息的值做相应修改(insert,update,delete) |->system_update_files_database($themes, 'theme'); */ drupal_theme_rebuild(); /** |->drupal_static_reset('theme_get_registry'); |->cache_clear_all('theme_registry', 'cache', TRUE); */ entity_info_cache_clear(); /** |->drupal_static_reset('entity_get_info'); // Clear all languages. |->cache_clear_all('entity_info:', 'cache', TRUE); */ //重新整理所有的 node type, 并且按需修改 field bundle node_types_rebuild(); /** 根据 node_info hook 的到module 中的 node type,然后在数据库 node_type 表中得到所有的node type, 通过判断其中的属性,得到最新的node type并且保存到 node_type 表中 |->_node_types_build(TRUE); |->触发 node_info hook, 得到模块中注册的 node_type foreach (module_implements('node_info') as $module) { $info_array = module_invoke($module, 'node_info'); foreach ($info_array as $type => $info) { $info['type'] = $type; $_node_types->types[$type] = node_type_set_defaults($info); |->node type 的默认值 $info = (array) $info; $new_type = $info + array( 'type' => '', 'name' => '', 'base' => '', 'description' => '', 'help' => '', 'custom' => 0, 'modified' => 0, 'locked' => 1, 'disabled' => 0, 'is_new' => 1, 'has_title' => 1, 'title_label' => 'Title', ); $new_type = (object) $new_type; // If the type has no title, set an empty label. if (!$new_type->has_title) { $new_type->title_label = ''; } if (empty($new_type->module)) { $new_type->module = $new_type->base == 'node_content' ? 'node' : ''; } $new_type->orig_type = isset($info['type']) ? $info['type'] : ''; return $new_type; $_node_types->types[$type]->module = $module; $_node_types->names[$type] = $info['name']; } } ... |-> 在重建过程中,如果某个node_type 是新的 或者 状态被改变过,则更新这个 node type node_type_save($type_object); |->在更新note type之后 触发了filed api 和 两个 hook //更新时触发 if (!empty($type->old_type) && $type->old_type != $type->type) { field_attach_rename_bundle('node', $type->old_type, $type->type); } module_invoke_all('node_type_update', $type); //插入时触发 field_attach_create_bundle('node', $type->type); module_invoke_all('node_type_insert', $type); */ //重新组织menu结构。这个函数在同一时间,只能有一个程序运行它,直至程序结束或超过运行时间。 menu_rebuild(); /** |->menu_router_build(); |->触发了 menu hook, $callbacks = array(); foreach (module_implements('menu') as $module) { $router_items = call_user_func($module . '_menu'); if (isset($router_items) && is_array($router_items)) { foreach (array_keys($router_items) as $path) { $router_items[$path]['module'] = $module; } $callbacks = array_merge($callbacks, $router_items); } } |-> 在得到所有的 items 之后, 触发了 menu_alter hook, 允许在module里修改menu信息 // Alter the menu as defined in modules, keys are like user/%user. drupal_alter('menu', $callbacks); |->重新组织menus 和 links 把他们更新到数据库(menu_router, menu_links) list($menu, $masks) = _menu_router_build($callbacks); _menu_router_cache($menu); return array($menu, $masks); */ // Synchronize to catch any actions that were added or removed. //Synchronizes actions that are provided by modules in hook_action_info(). actions_synchronize(); /** 触发action_info hook 得到所有的action, 之后触发 action_info_alter 允许module修改已经定义的action |-> actions_list(TRUE); |->$actions = module_invoke_all('action_info'); |->drupal_alter('action_info', $actions); */ // Don't clear cache_form - in-progress form submissions may break. // Ordered so clearing the page cache will always be the last action. $core = array('cache', 'cache_path', 'cache_filter', 'cache_bootstrap', 'cache_page'); $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); foreach ($cache_tables as $table) { cache_clear_all('*', $table, TRUE); } // Rebuild the bootstrap module list. We do this here so that developers // can get new hook_boot() implementations registered without having to // write a hook_update_N() function. //重新定义系统加载模块 _system_update_bootstrap_status(); }