/** * Validates the configuration data. * * We need to check that prefix is unique. * * @param array $data * @param array $files * @param array $errors * @return array * @throws coding_exception */ public function configuration_validation($data, $files, array $errors) { if (empty($errors['prefix'])) { $factory = cache_factory::instance(); $config = $factory->create_config_instance(); foreach ($config->get_all_stores() as $store) { if ($store['plugin'] === 'apcu') { if (isset($store['configuration']['prefix'])) { if ($data['prefix'] === $store['configuration']['prefix']) { // The new store has the same prefix as an existing store, thats a problem. $errors['prefix'] = get_string('prefixnotunique', 'cachestore_apcu'); break; } } else { if (empty($data['prefix'])) { // The existing store hasn't got a prefix and neither does the new store, that's a problem. $errors['prefix'] = get_string('prefixnotunique', 'cachestore_apcu'); break; } } } } } return $errors; }
/** * Performs custom validation for us. * * @param array $data An array of data sent to the form. * @param array $files An array of files sent to the form. * @return array An array of errors. */ protected function configuration_validation($data, $files) { $errors = array(); if (!array_key_exists('prefix', $data)) { $prefix = ''; } else { $prefix = clean_param($data['prefix'], PARAM_ALPHANUM); } $factory = cache_factory::instance(); $config = $factory->create_config_instance(); foreach ($config->get_all_stores() as $store) { if ($store['plugin'] !== 'xcache') { continue; } if (empty($store['configuration']['prefix'])) { $storeprefix = ''; } else { $storeprefix = $store['configuration']['prefix']; } if ($storeprefix === $prefix) { $errors['prefix'] = get_string('erroruniqueprefix'); } } return $errors; }
/** * Returns an instance of the cache_factor method. * * @param bool $forcereload If set to true a new cache_factory instance will be created and used. * @return cache_factory */ public static function instance($forcereload = false) { if ($forcereload || self::$instance === null) { self::$instance = new cache_factory(); } return self::$instance; }
/** * 返回当前终级类对象的实例 * @param $cache_config 缓存配置 * @return object */ public static function get_instance($cache_config = '') { if (cache_factory::$cache_factory == '') { cache_factory::$cache_factory = new cache_factory(); if (!empty($cache_config)) { cache_factory::$cache_factory->cache_config = $cache_config; } } return cache_factory::$cache_factory; }
/** * 返回当前缓存工厂类实例 * @param array $cache_config */ public static function get_instance($cache_config = array()) { //当前工厂类实例为空时初始化该对象 if (cache_factory::$cache_factory == '' || !empty($cache_config)) { cache_factory::$cache_factory = new cache_factory(); if (!empty($cache_config)) { cache_factory::$cache_factory->cache_config = $cache_config; } } return cache_factory::$cache_factory; }
/** * 返回当前终级类对象的实例 * @param $cache_config 缓存配置 * @return object */ public static function get_instance($cache_config = '') { if (!$cache_config) { $cache_config = array('type' => 'zendfile'); } if (cache_factory::$cache_factory == '') { cache_factory::$cache_factory = new cache_factory(); if (!empty($cache_config)) { cache_factory::$cache_factory->cache_config = $cache_config; } } return cache_factory::$cache_factory; }
/** * Exposes the cache_factory's disable method. * * Perhaps one day that method will be made public, for the time being it is protected. */ public static function phpunit_disable() { parent::disable(); }
/** * Returns stores suitable for use with a given definition. * * @param cache_definition $definition * @return cache_store[] */ public static function get_stores_suitable_for_definition(cache_definition $definition) { $factory = cache_factory::instance(); $stores = array(); if ($factory->is_initialising() || $factory->stores_disabled()) { // No suitable stores here. return $stores; } else { $stores = self::get_cache_stores($definition); // If mappingsonly is set, having 0 stores is ok. if (count($stores) === 0 && !$definition->is_for_mappings_only()) { // No suitable stores we found for the definition. We need to come up with a sensible default. // If this has happened we can be sure that the user has mapped custom stores to either the // mode of the definition. The first alternative to try is the system default for the mode. // e.g. the default file store instance for application definitions. $config = $factory->create_config_instance(); foreach ($config->get_stores($definition->get_mode()) as $name => $details) { if (!empty($details['default'])) { $stores[] = $factory->create_store_from_config($name, $details, $definition); break; } } } } return $stores; }
/** * Purge dataroot directory * @static * @return void */ public static function reset_dataroot() { global $CFG; $childclassname = self::get_framework() . '_util'; // Do not delete automatically installed files. self::skip_original_data_files($childclassname); // Clear file status cache, before checking file_exists. clearstatcache(); // Clean up the dataroot folder. $handle = opendir(self::get_dataroot()); while (false !== ($item = readdir($handle))) { if (in_array($item, $childclassname::$datarootskiponreset)) { continue; } if (is_dir(self::get_dataroot() . "/{$item}")) { remove_dir(self::get_dataroot() . "/{$item}", false); } else { unlink(self::get_dataroot() . "/{$item}"); } } closedir($handle); // Clean up the dataroot/filedir folder. if (file_exists(self::get_dataroot() . '/filedir')) { $handle = opendir(self::get_dataroot() . '/filedir'); while (false !== ($item = readdir($handle))) { if (in_array('filedir/' . $item, $childclassname::$datarootskiponreset)) { continue; } if (is_dir(self::get_dataroot() . "/filedir/{$item}")) { remove_dir(self::get_dataroot() . "/filedir/{$item}", false); } else { unlink(self::get_dataroot() . "/filedir/{$item}"); } } closedir($handle); } make_temp_directory(''); make_cache_directory(''); make_localcache_directory(''); // Reset the cache API so that it recreates it's required directories as well. cache_factory::reset(); // Purge all data from the caches. This is required for consistency. // Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache) // and now we will purge any other caches as well. cache_helper::purge_all(); }
/** * Cleans old session data from cache stores used for session based definitions. * * @param bool $output If set to true output will be given. */ public static function clean_old_session_data($output = false) { global $CFG; if ($output) { mtrace('Cleaning up stale session data from cache stores.'); } $factory = cache_factory::instance(); $config = $factory->create_config_instance(); $definitions = $config->get_definitions(); $purgetime = time() - $CFG->sessiontimeout; foreach ($definitions as $definitionarray) { // We are only interested in session caches. if (!($definitionarray['mode'] & cache_store::MODE_SESSION)) { continue; } $definition = $factory->create_definition($definitionarray['component'], $definitionarray['area']); $stores = $config->get_stores_for_definition($definition); // Turn them into store instances. $stores = self::initialise_cachestore_instances($stores, $definition); // Initialise all of the stores used for that definition. foreach ($stores as $store) { // If the store doesn't support searching we can skip it. if (!$store instanceof cache_is_searchable) { debugging('Cache stores used for session definitions should ideally be searchable.', DEBUG_DEVELOPER); continue; } // Get all of the keys. $keys = $store->find_by_prefix(cache_session::KEY_PREFIX); $todelete = array(); foreach ($store->get_many($keys) as $key => $value) { if (strpos($key, cache_session::KEY_PREFIX) !== 0 || !is_array($value) || !isset($value['lastaccess'])) { continue; } if ((int) $value['lastaccess'] < $purgetime || true) { $todelete[] = $key; } } if (count($todelete)) { $outcome = (int) $store->delete_many($todelete); if ($output) { $strdef = s($definition->get_id()); $strstore = s($store->my_name()); mtrace("- Removed {$outcome} old {$strdef} sessions from the '{$strstore}' cache store."); } } } } }
/** * Creates a store instance given its name and configuration. * * If the store has already been instantiated then the original object will be returned. (reused) * * @param string $name The name of the store (must be unique remember) * @param array $details * @param cache_definition $definition The definition to instantiate it for. * @return boolean|cache_store */ public function create_store_from_config($name, array $details, cache_definition $definition) { if (isset($details['use_test_store'])) { // name, plugin, alt $class = 'cachestore_' . $details['plugin']; $method = 'initialise_unit_test_instance'; if (class_exists($class) && method_exists($class, $method)) { $instance = $class::$method($definition); if ($instance) { return $instance; } } $details = $details['alt']; $name = $details['name']; } return parent::create_store_from_config($name, $details, $definition); }
case 'purgestore': case 'purge': // Purge a store cache. $store = required_param('store', PARAM_TEXT); cache_helper::purge_store($store); redirect($PAGE->url, get_string('purgestoresuccess', 'cache'), 5); break; case 'newlockinstance': // Adds a new lock instance. $lock = required_param('lock', PARAM_ALPHANUMEXT); $mform = cache_administration_helper::get_add_lock_form($lock); if ($mform->is_cancelled()) { redirect($PAGE->url); } else { if ($data = $mform->get_data()) { $factory = cache_factory::instance(); $config = $factory->create_config_instance(true); $name = $data->name; $data = cache_administration_helper::get_lock_configuration_from_data($lock, $data); $config->add_lock_instance($name, $lock, $data); redirect($PAGE->url, get_string('addlocksuccess', 'cache', $name), 5); } } break; case 'deletelock': // Deletes a lock instance. $lock = required_param('lock', PARAM_ALPHANUMEXT); $confirm = optional_param('confirm', false, PARAM_BOOL); if (!array_key_exists($lock, $locks)) { $notifysuccess = false; $notification = get_string('invalidlock', 'cache');
/** * Disables as much of the cache API as possible. * * All of the magic associated with the disabled cache is wrapped into this function. * In switching out the factory for the disabled factory it gains full control over the initialisation of objects * and can use all of the disabled alternatives. * Simple! * * This function has been marked as protected so that it cannot be abused through the public API presently. * Perhaps in the future we will allow this, however as per the build up to the first release containing * MUC it was decided that this was just to risky and abusable. */ protected static function disable() { global $CFG; require_once $CFG->dirroot . '/cache/disabledlib.php'; self::$instance = new cache_factory_disabled(); }
/** * Finds all definitions and updates them within the cache config file. * * @param bool $coreonly If set to true only core definitions will be updated. */ public static function update_definitions($coreonly = false) { global $CFG; // Include locallib require_once $CFG->dirroot . '/cache/locallib.php'; // First update definitions cache_config_writer::update_definitions($coreonly); // Second reset anything we have already initialised to ensure we're all up to date. cache_factory::reset(); }
/** * 读取缓存,默认为文件缓存,不加载缓存配置。 * @param string $name 缓存名称 * @param $filepath 数据路径(模块名称) caches/cache_$filepath/ * @param string $config 配置名称 */ function getcacheinfo($name, $filepath = '', $type = 'file', $config = '') { pc_base::load_sys_class('cache_factory'); if ($config) { $cacheconfig = pc_base::load_config('cache'); $cache = cache_factory::get_instance($cacheconfig)->get_cache($config); } else { $cache = cache_factory::get_instance()->get_cache($type); } return $cache->cacheinfo($name, '', '', $filepath); }
/** * Test disabling the cache. */ public function test_disable() { global $CFG; $configfile = $CFG->dataroot . '/muc/config.php'; // That's right, we're deleting the config file. $this->assertTrue(@unlink($configfile)); // Disable the cache cache_phpunit_factory::phpunit_disable(); // Check we get the expected disabled factory. $factory = cache_factory::instance(); $this->assertInstanceOf('cache_factory_disabled', $factory); // Check we get the expected disabled config. $config = $factory->create_config_instance(); $this->assertInstanceOf('cache_config_disabled', $config); // Check we get the expected disabled caches. $cache = cache::make('phpunit', 'disable'); $this->assertInstanceOf('cache_disabled', $cache); $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'phpunit', 'disable'); $this->assertInstanceOf('cache_disabled', $cache); $this->assertFalse(file_exists($configfile)); $this->assertFalse($cache->get('test')); $this->assertFalse($cache->set('test', 'test')); $this->assertFalse($cache->delete('test')); $this->assertTrue($cache->purge()); cache_factory::reset(); $factory = cache_factory::instance(true); $config = $factory->create_config_instance(); $this->assertEquals('cache_config_phpunittest', get_class($config)); }
/** * 读取缓存,默认为文件缓存,不加载缓存配置。 * @param string $name 缓存名称 * @param $filepath 数据路径(模块名称) caches/cache_$filepath/ * @param string $config 配置名称 */ function getcacheinfo($name, $filepath = '', $type = 'file', $config = '') { if (!preg_match("/^[a-zA-Z0-9_-]+\$/", $name)) { return false; } if ($filepath != "" && !preg_match("/^[a-zA-Z0-9_-]+\$/", $filepath)) { return false; } pc_base::load_sys_class('cache_factory'); if ($config) { $cacheconfig = pc_base::load_config('cache'); $cache = cache_factory::get_instance($cacheconfig)->get_cache($config); } else { $cache = cache_factory::get_instance()->get_cache($type); } return $cache->cacheinfo($name, '', '', $filepath); }
function get_content() { if ($this->settings['cache_expire_time']) { /**先从缓存读取数据 缓存不存在或过期时再从表中查询*/ include_once ROOT_PATH . 'lib/class/cache/cache.class.php'; $cache_factory = cache_factory::get_instance(); $cache_type = $this->settings['cache_type'] ? $this->settings['cache_type'] : 'file'; $cache_driver = $cache_factory->get_cache_driver($cache_type); $input = $this->input; unset($input['access_token'], $input['lpip']); $cache_id = md5(serialize($input)); $data = $cache_driver->get($cache_id); if ($data) { $this->addItem($data); $this->output(); } /**先从缓存读取数据 缓存不存在或过期时再从表中查询*/ } //$condition = $this->get_condition(); $offset = $this->input['page'] ? $this->input['page_num'] * ($this->input['page'] - 1) : 0; $count = $this->input['page_num'] ? intval($this->input['page_num']) : 20; $con = $con_count = $this->con_process(); $con['offset'] = $offset; $con['count'] = $count; $content = $this->obj->get_content($con); include_once ROOT_PATH . 'lib/class/publishcontent.class.php'; $this->publishcontent = new publishcontent(); $content_type = $this->publishcontent->get_all_content_type(); $pub_content_bundle = array(); foreach ((array) $content_type as $k => $v) { $pub_content_bundle[] = $v['bundle_id']; } include_once ROOT_PATH . 'lib/class/auth.class.php'; $this->auth = new Auth(); $app_info = $this->auth->get_app(); $module = array(); foreach ((array) $app_info as $k => $v) { if (!empty($v)) { $module[$v['bundle']] = $v['name']; } } $cidArr = array(); $conArr = array(); $other_content = array(); foreach ((array) $content as $row) { if (!in_array($row['app_bundle'], $pub_content_bundle)) { $row['bundle_name'] = $module[$row['app_bundle']]; if (!$row['bundle_name']) { $row['bundle_name'] = $this->settings["App_{$row['app_bundle']}"]['name']; } if (!$row['bundle_name']) { $row['bundle_name'] = $row['app_bundle']; } $row['content_url'] = $row['url']; $row['access_nums'] = $row['num']; $other_content[] = $row; } else { $cidArr[] = $row['cid']; $conArr[$row['cid']] = array('access_nums' => $row['num']); } } $cidStr = implode(',', $cidArr); $ret = $this->publishcontent->get_content_by_cid($cidStr); if (!is_array($ret)) { //return array(); } $ret = (array) $ret; $arExistIds = array(); foreach ($ret as $k => $v) { $arExistIds[] = $v['cid']; $ret[$k]['bundle_name'] = $module[$v['bundle_id']]; if (!$ret[$k]['bundle_name']) { $ret[$k]['bundle_name'] = $this->settings["App_{$v['bundle_id']}"]['name']; } if (!$ret[$k]['bundle_name']) { $ret[$k]['bundle_name'] = $v['bundle_id']; } $ret[$k] = array_merge($ret[$k], $conArr[$k]); } $ret = array_merge($ret, $other_content); //发布库删除没有更新统计时条数不准确 下面代码为解决此bug //对比cid差集 $delCid = array_diff($cidArr, $arExistIds); //更新已经不存在的内容 if (!empty($delCid)) { $cid = implode(',', $delCid); $sql = "UPDATE " . DB_PREFIX . "nums SET del = 1 WHERE cid IN(" . $cid . ")"; $this->db->query($sql); include_once CUR_CONF_PATH . 'lib/cache.class.php'; $cache = new CacheFile(); $table = $cache->get_cache('access_table_name'); $table = convert_table_name($table); if ($table) { $table_str = implode(',', $table); } $sql = "ALTER TABLE " . DB_PREFIX . "merge UNION(" . $table_str . ")"; $this->db->query($sql); $sql = "UPDATE " . DB_PREFIX . "merge SET del = 1 WHERE cid IN(" . $cid . ")"; $this->db->query($sql); } $ret = hg_array_sort($ret, 'access_nums', 'DESC'); $pagearr = $this->obj->get_content($con_count, 1); $pagearr['page_num'] = $count; $pagearr['total_num'] = $pagearr['total']; $pagearr['total_page'] = ceil($pagearr['total'] / $count); $pagearr['current_page'] = floor($offset / $count) + 1; $ret = array('content' => array_values($ret), 'page' => $pagearr); if ($this->settings['cache_expire_time']) { /*将数据写入缓存*/ $cache_driver->set($cache_id, $ret, $this->settings['cache_expire_time']); /*将数据写入缓存*/ } $this->addItem($ret); $this->output(); }
/** * Test that the default stores all support searching. */ public function test_defaults_support_searching() { $instance = cache_config_testing::instance(true); $instance->phpunit_add_definition('phpunit/search1', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'search1', 'requiresearchable' => true)); $instance->phpunit_add_definition('phpunit/search2', array('mode' => cache_store::MODE_SESSION, 'component' => 'phpunit', 'area' => 'search2', 'requiresearchable' => true)); $instance->phpunit_add_definition('phpunit/search3', array('mode' => cache_store::MODE_REQUEST, 'component' => 'phpunit', 'area' => 'search3', 'requiresearchable' => true)); $factory = cache_factory::instance(); // Test application cache is searchable. $definition = $factory->create_definition('phpunit', 'search1'); $this->assertInstanceOf('cache_definition', $definition); $this->assertEquals(cache_store::IS_SEARCHABLE, $definition->get_requirements_bin() & cache_store::IS_SEARCHABLE); $cache = $factory->create_cache($definition); $this->assertInstanceOf('cache_application', $cache); $this->assertArrayHasKey('cache_is_searchable', $cache->phpunit_get_store_implements()); // Test session cache is searchable. $definition = $factory->create_definition('phpunit', 'search2'); $this->assertInstanceOf('cache_definition', $definition); $this->assertEquals(cache_store::IS_SEARCHABLE, $definition->get_requirements_bin() & cache_store::IS_SEARCHABLE); $cache = $factory->create_cache($definition); $this->assertInstanceOf('cache_session', $cache); $this->assertArrayHasKey('cache_is_searchable', $cache->phpunit_get_store_implements()); // Test request cache is searchable. $definition = $factory->create_definition('phpunit', 'search3'); $this->assertInstanceOf('cache_definition', $definition); $this->assertEquals(cache_store::IS_SEARCHABLE, $definition->get_requirements_bin() & cache_store::IS_SEARCHABLE); $cache = $factory->create_cache($definition); $this->assertInstanceOf('cache_request', $cache); $this->assertArrayHasKey('cache_is_searchable', $cache->phpunit_get_store_implements()); }
/** * Purge dataroot directory * @static * @return void */ public static function reset_dataroot() { global $CFG; $handle = opendir($CFG->dataroot); $skip = array('.', '..', 'phpunittestdir.txt', 'phpunit', '.htaccess'); while (false !== ($item = readdir($handle))) { if (in_array($item, $skip)) { continue; } if (is_dir("{$CFG->dataroot}/{$item}")) { remove_dir("{$CFG->dataroot}/{$item}", false); } else { unlink("{$CFG->dataroot}/{$item}"); } } closedir($handle); make_temp_directory(''); make_cache_directory(''); make_cache_directory('htmlpurifier'); // Reset the cache API so that it recreates it's required directories as well. cache_factory::reset(); // Purge all data from the caches. This is required for consistency. // Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache) // and now we will purge any other caches as well. cache_helper::purge_all(); }
/** * Get an array of stores that are suitable to be used for a given definition. * * @param string $component * @param string $area * @return array Array containing 3 elements * 1. An array of currently used stores * 2. An array of suitable stores * 3. An array of default stores */ public static function get_definition_store_options($component, $area) { $factory = cache_factory::instance(); $definition = $factory->create_definition($component, $area); $config = cache_config::instance(); $currentstores = $config->get_stores_for_definition($definition); $possiblestores = $config->get_stores($definition->get_mode(), $definition->get_requirements_bin()); $defaults = array(); foreach ($currentstores as $key => $store) { if (!empty($store['default'])) { $defaults[] = $key; unset($currentstores[$key]); } } foreach ($possiblestores as $key => $store) { if ($store['default']) { unset($possiblestores[$key]); $possiblestores[$key] = $store; } } return array($currentstores, $possiblestores, $defaults); }
/** * Creates a store instance given its name and configuration. * * If the store has already been instantiated then the original object will be returned. (reused) * * @param string $name The name of the store (must be unique remember) * @param array $details * @param cache_definition $definition The definition to instantiate it for. * @return boolean|cache_store */ public function create_store_from_config($name, array $details, cache_definition $definition) { if (isset($details['use_test_store'])) { // name, plugin, alt $class = 'cachestore_' . $details['plugin']; $method = 'initialise_unit_test_instance'; if (class_exists($class) && method_exists($class, $method)) { $instance = $class::$method($definition); if ($instance) { return $instance; } } // Notify user that alternative store is being used, so action can be taken. if (!$this->altcachestorenotice) { echo PHP_EOL . "++ WARNING: " . 'Failed to use "' . $details['plugin'] . '" cache store, alt "' . $details['alt']['plugin'] . '" cache store is used.' . PHP_EOL . PHP_EOL; $this->altcachestorenotice = true; } $details = $details['alt']; $details['class'] = 'cachestore_' . $details['plugin']; $name = $details['name']; } return parent::create_store_from_config($name, $details, $definition); }
/** * Gets all of the stores that are to be used for the given definition. * * @param cache_definition $definition * @return array */ public function get_stores_for_definition(cache_definition $definition) { // Check if MUC has been disabled. $factory = cache_factory::instance(); if ($factory->stores_disabled()) { // Yip its been disabled. // To facilitate this we are going to always return an empty array of stores to use. // This will force all cache instances to use the cachestore_dummy. // MUC will still be used essentially so that code using it will still continue to function but because no cache stores // are being used interaction with MUC will be purely based around a static var. return array(); } $availablestores = $this->get_stores($definition->get_mode(), $definition->get_requirements_bin()); $stores = array(); $id = $definition->get_id(); // Now get any mappings and give them priority. foreach ($this->configdefinitionmappings as $mapping) { if ($mapping['definition'] !== $id) { continue; } $storename = $mapping['store']; if (!array_key_exists($storename, $availablestores)) { continue; } if (array_key_exists($storename, $stores)) { $store = $stores[$storename]; unset($stores[$storename]); $stores[$storename] = $store; } else { $stores[$storename] = $availablestores[$storename]; } } if (empty($stores) && !$definition->is_for_mappings_only()) { $mode = $definition->get_mode(); // Load the default stores. foreach ($this->configmodemappings as $mapping) { if ($mapping['mode'] === $mode && array_key_exists($mapping['store'], $availablestores)) { $store = $availablestores[$mapping['store']]; if (empty($store['mappingsonly'])) { $stores[$mapping['store']] = $store; } } } } return $stores; }
/** * Gets an instance of the cache_configuration class. * * @return cache_config */ public static function instance() { $factory = cache_factory::instance(); return $factory->create_config_instance(); }
/** * Purge dataroot directory * @static * @return void */ public static function reset_dataroot() { global $CFG; $childclassname = self::get_framework() . '_util'; $handle = opendir($CFG->dataroot); while (false !== ($item = readdir($handle))) { if (in_array($item, $childclassname::$datarootskiponreset)) { continue; } if (is_dir("$CFG->dataroot/$item")) { remove_dir("$CFG->dataroot/$item", false); } else { unlink("$CFG->dataroot/$item"); } } closedir($handle); make_temp_directory(''); make_cache_directory(''); make_cache_directory('htmlpurifier'); // Reset the cache API so that it recreates it's required directories as well. cache_factory::reset(); // Purge all data from the caches. This is required for consistency. // Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache) // and now we will purge any other caches as well. cache_helper::purge_all(); }
/** * Tests application cache event invalidation over a distributed setup. */ public function test_distributed_application_event_invalidation() { global $CFG; // This is going to be an intense wee test. // We need to add data the to cache, invalidate it by event, manually force it back without MUC knowing to simulate a // disconnected/distributed setup (think load balanced server using local cache), instantiate the cache again and finally // check that it is not picked up. $instance = cache_config_phpunittest::instance(); $instance->phpunit_add_definition('phpunit/eventinvalidationtest', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'eventinvalidationtest', 'invalidationevents' => array('crazyevent'))); $cache = cache::make('phpunit', 'eventinvalidationtest'); $this->assertTrue($cache->set('testkey1', 'test data 1')); $this->assertEquals('test data 1', $cache->get('testkey1')); cache_helper::invalidate_by_event('crazyevent', array('testkey1')); $this->assertFalse($cache->get('testkey1')); // OK data added, data invalidated, and invalidation time has been set. // Now we need to manually add back the data and adjust the invalidation time. $timefile = $CFG->dataroot . '/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/a65/a65b1dc524cf6e03c1795197c84d5231eb229b86.cache'; $timecont = serialize(cache::now() - 60); // Back 60sec in the past to force it to re-invalidate. make_writable_directory(dirname($timefile)); file_put_contents($timefile, $timecont); $this->assertTrue(file_exists($timefile)); $datafile = $CFG->dataroot . '/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/626/626e9c7a45febd98f064c2b383de8d9d4ebbde7b.cache'; $datacont = serialize("test data 1"); make_writable_directory(dirname($datafile)); file_put_contents($datafile, $datacont); $this->assertTrue(file_exists($datafile)); // Test 1: Rebuild without the event and test its there. cache_factory::reset(); $instance = cache_config_phpunittest::instance(); $instance->phpunit_add_definition('phpunit/eventinvalidationtest', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'eventinvalidationtest')); $cache = cache::make('phpunit', 'eventinvalidationtest'); $this->assertEquals('test data 1', $cache->get('testkey1')); // Test 2: Rebuild and test the invalidation of the event via the invalidation cache. cache_factory::reset(); $instance = cache_config_phpunittest::instance(); $instance->phpunit_add_definition('phpunit/eventinvalidationtest', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'eventinvalidationtest', 'invalidationevents' => array('crazyevent'))); $cache = cache::make('phpunit', 'eventinvalidationtest'); $this->assertFalse($cache->get('testkey1')); }
/** * Returns the site identifier. * * @return string */ public static function get_site_identifier() { if (is_null(self::$siteidentifier)) { $factory = cache_factory::instance(); $config = $factory->create_config_instance(); self::$siteidentifier = $config->get_site_identifier(); } return self::$siteidentifier; }
/** * Get configuration values from the global config table * or the config_plugins table. * * If called with one parameter, it will load all the config * variables for one plugin, and return them as an object. * * If called with 2 parameters it will return a string single * value or false if the value is not found. * * @static $siteidentifier The site identifier is not cached. We use this static cache so * that we need only fetch it once per request. * @param string $plugin full component name * @param string $name default NULL * @return mixed hash-like object or single value, return false no config found */ function get_config($plugin, $name = NULL) { global $CFG, $DB; static $siteidentifier = null; if ($plugin === 'moodle' || $plugin === 'core' || empty($plugin)) { $forced =& $CFG->config_php_settings; $iscore = true; $plugin = 'core'; } else { if (array_key_exists($plugin, $CFG->forced_plugin_settings)) { $forced =& $CFG->forced_plugin_settings[$plugin]; } else { $forced = array(); } $iscore = false; } if ($siteidentifier === null) { try { // This may fail during installation. // If you have a look at {@link initialise_cfg()} you will see that this is how we detect the need to // install the database. $siteidentifier = $DB->get_field('config', 'value', array('name' => 'siteidentifier')); } catch (dml_exception $ex) { // It's failed. We'll use this opportunity to disable cache stores so that we don't inadvertingly start using // old caches. People should delete their moodledata dirs when reinstalling the database... but they don't. cache_factory::disable_stores(); // Set siteidentifier to false. We don't want to trip this continually. $siteidentifier = false; throw $ex; } } if (!empty($name)) { if (array_key_exists($name, $forced)) { return (string) $forced[$name]; } else { if ($name === 'siteidentifier' && $plugin == 'core') { return $siteidentifier; } } } $cache = cache::make('core', 'config'); $result = $cache->get($plugin); if (!$result) { // the user is after a recordset $result = new stdClass(); if (!$iscore) { $result = $DB->get_records_menu('config_plugins', array('plugin' => $plugin), '', 'name,value'); } else { // this part is not really used any more, but anyway... $result = $DB->get_records_menu('config', array(), '', 'name,value'); } $cache->set($plugin, $result); } if (!empty($name)) { if (array_key_exists($name, $result)) { return $result[$name]; } return false; } if ($plugin === 'core') { $result['siteidentifier'] = $siteidentifier; } foreach ($forced as $key => $value) { if (is_null($value) or is_array($value) or is_object($value)) { // we do not want any extra mess here, just real settings that could be saved in db unset($result[$key]); } else { //convert to string as if it went through the DB $result[$key] = (string) $value; } } return (object) $result; }
/** * Creates a new cache instance based upon the given params. * * @param int $mode One of cache_store::MODE_* * @param string $component The component this cache relates to. * @param string $area The area this cache relates to. * @param array $identifiers Any additional identifiers that should be provided to the definition. * @param array $options An array of options, available options are: * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_ * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars * - staticacceleration : If set to true the cache will hold onto data passing through it. * - staticaccelerationsize : The max size for the static acceleration array. * @return cache_application|cache_session|cache_store */ public static function make_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { $factory = cache_factory::instance(); return $factory->create_cache_from_params($mode, $component, $area, $identifiers, $options); }
/** * Test the hash_key functionality. */ public function test_hash_key() { global $CFG; $currentdebugging = $CFG->debug; $CFG->debug = E_ALL; // First with simplekeys $instance = cache_config_phpunittest::instance(true); $instance->phpunit_add_definition('phpunit/hashtest', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'hashtest', 'simplekeys' => true)); $factory = cache_factory::instance(); $definition = $factory->create_definition('phpunit', 'hashtest'); $result = cache_helper::hash_key('test', $definition); $this->assertEquals('test-' . $definition->generate_single_key_prefix(), $result); try { cache_helper::hash_key('test/test', $definition); $this->fail('Invalid key was allowed, you should see this.'); } catch (coding_exception $e) { $this->assertEquals('test/test', $e->debuginfo); } // Second without simple keys $instance->phpunit_add_definition('phpunit/hashtest2', array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'hashtest2', 'simplekeys' => false)); $definition = $factory->create_definition('phpunit', 'hashtest2'); $result = cache_helper::hash_key('test', $definition); $this->assertEquals(sha1($definition->generate_single_key_prefix() . '-test'), $result); $result = cache_helper::hash_key('test/test', $definition); $this->assertEquals(sha1($definition->generate_single_key_prefix() . '-test/test'), $result); $CFG->debug = $currentdebugging; }