From 7129531bc0884a710e5d61ced2e0a54538f64266 Mon Sep 17 00:00:00 2001 From: Igor Wiedler Date: Fri, 7 Jan 2011 22:45:39 +0100 Subject: [ticket/9981] Fix unit test dependencies PHPBB3-9981 --- tests/request/request_var.php | 1 + tests/template/template.php | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/request/request_var.php b/tests/request/request_var.php index 64cdd9bc75..e452aefea9 100644 --- a/tests/request/request_var.php +++ b/tests/request/request_var.php @@ -13,6 +13,7 @@ require_once __DIR__ . '/../../phpBB/includes/request/deactivated_super_global.p require_once __DIR__ . '/../../phpBB/includes/request/interface.php'; require_once __DIR__ . '/../../phpBB/includes/request/request.php'; require_once __DIR__ . '/../../phpBB/includes/functions.php'; +require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; class phpbb_request_var_test extends phpbb_test_case { diff --git a/tests/template/template.php b/tests/template/template.php index a58a0a4e0f..14a5a3c752 100644 --- a/tests/template/template.php +++ b/tests/template/template.php @@ -7,6 +7,7 @@ * */ +require_once __DIR__ . '/../../phpBB/includes/functions.php'; require_once __DIR__ . '/../../phpBB/includes/template.php'; class phpbb_template_template_test extends phpbb_test_case -- cgit v1.2.1 From 36e95f939db9b88b8519d956120d161102184ccb Mon Sep 17 00:00:00 2001 From: Igor Wiedler Date: Fri, 7 Jan 2011 18:03:00 +0100 Subject: [ticket/9979] Support autoloading in unit tests PHPBB-9979 --- tests/bootstrap.php | 4 ++++ tests/class_loader/class_loader_test.php | 12 ++++++++++++ tests/request/deactivated_super_global.php | 3 --- tests/request/request.php | 5 ----- tests/request/request_var.php | 5 ----- tests/request/type_cast_helper.php | 2 -- tests/security/redirect.php | 1 - 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 99f145e427..161bd83a3d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -26,6 +26,10 @@ else } require_once $phpbb_root_path . 'includes/constants.php'; +require_once $phpbb_root_path . 'includes/class_loader.' . $phpEx; + +$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); +$class_loader->register(); require_once 'test_framework/phpbb_test_case_helpers.php'; require_once 'test_framework/phpbb_test_case.php'; diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php index aef4f1de07..3eb3c915a1 100644 --- a/tests/class_loader/class_loader_test.php +++ b/tests/class_loader/class_loader_test.php @@ -14,6 +14,18 @@ require_once __DIR__ . '/../../phpBB/includes/class_loader.php'; class phpbb_class_loader_test extends PHPUnit_Framework_TestCase { + public function setUp() + { + global $class_loader; + $class_loader->unregister(); + } + + public function tearDown() + { + global $class_loader; + $class_loader->register(); + } + public function test_resolve_path() { $prefix = __DIR__ . '/'; diff --git a/tests/request/deactivated_super_global.php b/tests/request/deactivated_super_global.php index ea385831c9..995f93443d 100644 --- a/tests/request/deactivated_super_global.php +++ b/tests/request/deactivated_super_global.php @@ -8,9 +8,6 @@ * */ -require_once __DIR__ . '/../../phpBB/includes/request/interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/deactivated_super_global.php'; - class phpbb_deactivated_super_global_test extends phpbb_test_case { /** diff --git a/tests/request/request.php b/tests/request/request.php index 7cec70b0d4..203c9fd880 100644 --- a/tests/request/request.php +++ b/tests/request/request.php @@ -8,11 +8,6 @@ * */ -require_once __DIR__ . '/../../phpBB/includes/request/type_cast_helper_interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/deactivated_super_global.php'; -require_once __DIR__ . '/../../phpBB/includes/request/request.php'; - class phpbb_request_test extends phpbb_test_case { private $type_cast_helper; diff --git a/tests/request/request_var.php b/tests/request/request_var.php index e452aefea9..8848e388bf 100644 --- a/tests/request/request_var.php +++ b/tests/request/request_var.php @@ -7,11 +7,6 @@ * */ -require_once __DIR__ . '/../../phpBB/includes/request/type_cast_helper_interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/type_cast_helper.php'; -require_once __DIR__ . '/../../phpBB/includes/request/deactivated_super_global.php'; -require_once __DIR__ . '/../../phpBB/includes/request/interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/request.php'; require_once __DIR__ . '/../../phpBB/includes/functions.php'; require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; diff --git a/tests/request/type_cast_helper.php b/tests/request/type_cast_helper.php index 3f27269acb..6d4e7055d5 100644 --- a/tests/request/type_cast_helper.php +++ b/tests/request/type_cast_helper.php @@ -9,8 +9,6 @@ */ require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; -require_once __DIR__ . '/../../phpBB/includes/request/type_cast_helper_interface.php'; -require_once __DIR__ . '/../../phpBB/includes/request/type_cast_helper.php'; class phpbb_type_cast_helper_test extends phpbb_test_case { diff --git a/tests/security/redirect.php b/tests/security/redirect.php index c53414e7df..1557384507 100644 --- a/tests/security/redirect.php +++ b/tests/security/redirect.php @@ -8,7 +8,6 @@ */ require_once __DIR__ . '/base.php'; - require_once __DIR__ . '/../../phpBB/includes/functions.php'; require_once __DIR__ . '/../../phpBB/includes/session.php'; -- cgit v1.2.1 From 9329b16ab13f3a4caf107df358c3c58bda2dcd8a Mon Sep 17 00:00:00 2001 From: Igor Wiedler Date: Wed, 3 Nov 2010 18:35:31 +0100 Subject: [task/acm-refactor] Refactor the ACM classes to have a common interface. They are now refered to as cache drivers rather than ACM classes. The additional utility functions from the original cache class have been moved to the cache_service. The class loader is now instantiated without a cache instance and passed one as soon as it is constructed to allow autoloading the cache classes. PHPBB3-9983 --- phpBB/common.php | 12 +- phpBB/docs/coding-guidelines.html | 2 +- phpBB/download/file.php | 12 +- phpBB/includes/acm/acm_apc.php | 82 --- phpBB/includes/acm/acm_eaccelerator.php | 119 ----- phpBB/includes/acm/acm_file.php | 730 --------------------------- phpBB/includes/acm/acm_memcache.php | 136 ----- phpBB/includes/acm/acm_memory.php | 437 ---------------- phpBB/includes/acm/acm_null.php | 154 ------ phpBB/includes/acm/acm_xcache.php | 119 ----- phpBB/includes/cache.php | 435 ---------------- phpBB/includes/cache/driver/apc.php | 76 +++ phpBB/includes/cache/driver/base.php | 24 + phpBB/includes/cache/driver/eaccelerator.php | 113 +++++ phpBB/includes/cache/driver/file.php | 730 +++++++++++++++++++++++++++ phpBB/includes/cache/driver/interface.php | 104 ++++ phpBB/includes/cache/driver/memcache.php | 130 +++++ phpBB/includes/cache/driver/memory.php | 437 ++++++++++++++++ phpBB/includes/cache/driver/null.php | 154 ++++++ phpBB/includes/cache/driver/xcache.php | 113 +++++ phpBB/includes/cache/factory.php | 52 ++ phpBB/includes/cache/service.php | 452 +++++++++++++++++ phpBB/includes/class_loader.php | 21 +- phpBB/install/database_update.php | 11 +- phpBB/install/index.php | 7 +- phpBB/style.php | 15 +- tests/bootstrap.php | 2 +- tests/cache/all_tests.php | 40 ++ tests/cache/cache_test.php | 39 ++ tests/class_loader/cache_mock.php | 49 +- tests/class_loader/class_loader_test.php | 14 +- 31 files changed, 2567 insertions(+), 2254 deletions(-) delete mode 100644 phpBB/includes/acm/acm_apc.php delete mode 100644 phpBB/includes/acm/acm_eaccelerator.php delete mode 100644 phpBB/includes/acm/acm_file.php delete mode 100644 phpBB/includes/acm/acm_memcache.php delete mode 100644 phpBB/includes/acm/acm_memory.php delete mode 100644 phpBB/includes/acm/acm_null.php delete mode 100644 phpBB/includes/acm/acm_xcache.php delete mode 100644 phpBB/includes/cache.php create mode 100644 phpBB/includes/cache/driver/apc.php create mode 100644 phpBB/includes/cache/driver/base.php create mode 100644 phpBB/includes/cache/driver/eaccelerator.php create mode 100644 phpBB/includes/cache/driver/file.php create mode 100644 phpBB/includes/cache/driver/interface.php create mode 100644 phpBB/includes/cache/driver/memcache.php create mode 100644 phpBB/includes/cache/driver/memory.php create mode 100644 phpBB/includes/cache/driver/null.php create mode 100644 phpBB/includes/cache/driver/xcache.php create mode 100644 phpBB/includes/cache/factory.php create mode 100644 phpBB/includes/cache/service.php create mode 100644 tests/cache/all_tests.php create mode 100644 tests/cache/cache_test.php diff --git a/phpBB/common.php b/phpBB/common.php index 96b782a229..fc6009eb21 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -187,8 +187,6 @@ if (!empty($load_extensions) && function_exists('dl')) // Include files require($phpbb_root_path . 'includes/class_loader.' . $phpEx); -require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx); -require($phpbb_root_path . 'includes/cache.' . $phpEx); require($phpbb_root_path . 'includes/template.' . $phpEx); require($phpbb_root_path . 'includes/session.' . $phpEx); require($phpbb_root_path . 'includes/auth.' . $phpEx); @@ -203,13 +201,15 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); // Set PHP error handler to ours set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); -// Cache must be loaded before class loader -$cache = new cache(); - // Setup class loader first -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx, $cache); +$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); +// set up caching +$acm = phpbb_cache_factory::create($acm_type)->get_acm(); +$class_loader->set_acm($acm); +$cache = new phpbb_cache_service($acm); + // Instantiate some basic classes $request = new phpbb_request(); $user = new user(); diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 766242ab83..c0ebb7450e 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -203,7 +203,7 @@ class ...
  • phpBB3
    Core files and all files not assigned to a separate package
  • -
  • acm
    /includes/acm, /includes/cache.php
    Cache System
  • +
  • acm
    /includes/cache, /includes/cache.php
    Cache System
  • acp
    /adm, /includes/acp, /includes/functions_admin.php
    Administration Control Panel
  • dbal
    /includes/db
    Database Abstraction Layer.
    Base class is dbal
      diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 46ddbb9916..74925fb447 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -44,15 +44,21 @@ if (isset($_GET['avatar'])) exit; } - require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx); - require($phpbb_root_path . 'includes/cache.' . $phpEx); + require($phpbb_root_path . 'includes/class_loader.' . $phpEx); require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); require($phpbb_root_path . 'includes/functions.' . $phpEx); require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); + $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); + $class_loader->register(); + + // set up caching + $acm = phpbb_cache_factory::create($acm_type)->get_acm(); + $class_loader->set_acm($acm); + $cache = new phpbb_cache_service($acm); + $db = new $sql_db(); - $cache = new cache(); // Connect to DB if (!@$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false)) diff --git a/phpBB/includes/acm/acm_apc.php b/phpBB/includes/acm/acm_apc.php deleted file mode 100644 index ab00b43e60..0000000000 --- a/phpBB/includes/acm/acm_apc.php +++ /dev/null @@ -1,82 +0,0 @@ -key_prefix . $var); - } - - /** - * Store data in the cache - * - * @access protected - * @param string $var Cache key - * @param mixed $data Data to store - * @param int $ttl Time-to-live of cached data - * @return bool True if the operation succeeded - */ - function _write($var, $data, $ttl = 2592000) - { - return apc_store($this->key_prefix . $var, $data, $ttl); - } - - /** - * Remove an item from the cache - * - * @access protected - * @param string $var Cache key - * @return bool True if the operation succeeded - */ - function _delete($var) - { - return apc_delete($this->key_prefix . $var); - } -} diff --git a/phpBB/includes/acm/acm_eaccelerator.php b/phpBB/includes/acm/acm_eaccelerator.php deleted file mode 100644 index 7ae1557beb..0000000000 --- a/phpBB/includes/acm/acm_eaccelerator.php +++ /dev/null @@ -1,119 +0,0 @@ -key_prefix - eaccelerator_rm(substr($var['name'], 1)); - } - - parent::purge(); - } - - /** - * Perform cache garbage collection - * - * @return void - */ - function tidy() - { - eaccelerator_gc(); - - set_config('cache_last_gc', time(), true); - } - - /** - * Fetch an item from the cache - * - * @access protected - * @param string $var Cache key - * @return mixed Cached data - */ - function _read($var) - { - $result = eaccelerator_get($this->key_prefix . $var); - - if ($result === null) - { - return false; - } - - // Handle serialized objects - if (is_string($result) && strpos($result, $this->serialize_header . 'O:') === 0) - { - $result = unserialize(substr($result, strlen($this->serialize_header))); - } - - return $result; - } - - /** - * Store data in the cache - * - * @access protected - * @param string $var Cache key - * @param mixed $data Data to store - * @param int $ttl Time-to-live of cached data - * @return bool True if the operation succeeded - */ - function _write($var, $data, $ttl = 2592000) - { - // Serialize objects and make them easy to detect - $data = (is_object($data)) ? $this->serialize_header . serialize($data) : $data; - - return eaccelerator_put($this->key_prefix . $var, $data, $ttl); - } - - /** - * Remove an item from the cache - * - * @access protected - * @param string $var Cache key - * @return bool True if the operation succeeded - */ - function _delete($var) - { - return eaccelerator_rm($this->key_prefix . $var); - } -} diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php deleted file mode 100644 index 0e60cd6940..0000000000 --- a/phpBB/includes/acm/acm_file.php +++ /dev/null @@ -1,730 +0,0 @@ -cache_dir = $phpbb_root_path . 'cache/'; - } - - /** - * Load global cache - */ - function load() - { - return $this->_read('data_global'); - } - - /** - * Unload cache object - */ - function unload() - { - $this->save(); - unset($this->vars); - unset($this->var_expires); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->var_expires = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - } - - /** - * Save modified objects - */ - function save() - { - if (!$this->is_modified) - { - return; - } - - global $phpEx; - - if (!$this->_write('data_global')) - { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - // Now, this occurred how often? ... phew, just tell the user then... - if (!phpbb_is_writable($this->cache_dir)) - { - // We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload()) - die($this->cache_dir . ' is NOT writable.'); - exit; - } - - die('Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx); - exit; - } - - $this->is_modified = false; - } - - /** - * Tidy cache - */ - function tidy() - { - global $phpEx; - - $dir = @opendir($this->cache_dir); - - if (!$dir) - { - return; - } - - $time = time(); - - while (($entry = readdir($dir)) !== false) - { - if (!preg_match('/^(sql_|data_(?!global))/', $entry)) - { - continue; - } - - if (!($handle = @fopen($this->cache_dir . $entry, 'rb'))) - { - continue; - } - - // Skip the PHP header - fgets($handle); - - // Skip expiration - $expires = (int) fgets($handle); - - fclose($handle); - - if ($time >= $expires) - { - $this->remove_file($this->cache_dir . $entry); - } - } - closedir($dir); - - if (file_exists($this->cache_dir . 'data_global.' . $phpEx)) - { - if (!sizeof($this->vars)) - { - $this->load(); - } - - foreach ($this->var_expires as $var_name => $expires) - { - if ($time >= $expires) - { - $this->destroy($var_name); - } - } - } - - set_config('cache_last_gc', time(), true); - } - - /** - * Get saved cache object - */ - function get($var_name) - { - if ($var_name[0] == '_') - { - global $phpEx; - - if (!$this->_exists($var_name)) - { - return false; - } - - return $this->_read('data' . $var_name); - } - else - { - return ($this->_exists($var_name)) ? $this->vars[$var_name] : false; - } - } - - /** - * Put data into cache - */ - function put($var_name, $var, $ttl = 31536000) - { - if ($var_name[0] == '_') - { - $this->_write('data' . $var_name, $var, time() + $ttl); - } - else - { - $this->vars[$var_name] = $var; - $this->var_expires[$var_name] = time() + $ttl; - $this->is_modified = true; - } - } - - /** - * Purge cache data - */ - function purge() - { - // Purge all phpbb cache files - $dir = @opendir($this->cache_dir); - - if (!$dir) - { - return; - } - - while (($entry = readdir($dir)) !== false) - { - if (strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && strpos($entry, 'tpl_') !== 0) - { - continue; - } - - $this->remove_file($this->cache_dir . $entry); - } - closedir($dir); - - unset($this->vars); - unset($this->var_expires); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->var_expires = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - - $this->is_modified = false; - } - - /** - * Destroy cache data - */ - function destroy($var_name, $table = '') - { - global $phpEx; - - if ($var_name == 'sql' && !empty($table)) - { - if (!is_array($table)) - { - $table = array($table); - } - - $dir = @opendir($this->cache_dir); - - if (!$dir) - { - return; - } - - while (($entry = readdir($dir)) !== false) - { - if (strpos($entry, 'sql_') !== 0) - { - continue; - } - - if (!($handle = @fopen($this->cache_dir . $entry, 'rb'))) - { - continue; - } - - // Skip the PHP header - fgets($handle); - - // Skip expiration - fgets($handle); - - // Grab the query, remove the LF - $query = substr(fgets($handle), 0, -1); - - fclose($handle); - - foreach ($table as $check_table) - { - // Better catch partial table names than no table names. ;) - if (strpos($query, $check_table) !== false) - { - $this->remove_file($this->cache_dir . $entry); - break; - } - } - } - closedir($dir); - - return; - } - - if (!$this->_exists($var_name)) - { - return; - } - - if ($var_name[0] == '_') - { - $this->remove_file($this->cache_dir . 'data' . $var_name . ".$phpEx", true); - } - else if (isset($this->vars[$var_name])) - { - $this->is_modified = true; - unset($this->vars[$var_name]); - unset($this->var_expires[$var_name]); - - // We save here to let the following cache hits succeed - $this->save(); - } - } - - /** - * Check if a given cache entry exist - */ - function _exists($var_name) - { - if ($var_name[0] == '_') - { - global $phpEx; - return file_exists($this->cache_dir . 'data' . $var_name . ".$phpEx"); - } - else - { - if (!sizeof($this->vars)) - { - $this->load(); - } - - if (!isset($this->var_expires[$var_name])) - { - return false; - } - - return (time() > $this->var_expires[$var_name]) ? false : isset($this->vars[$var_name]); - } - } - - /** - * Load cached sql query - */ - function sql_load($query) - { - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - - if (($rowset = $this->_read('sql_' . md5($query))) === false) - { - return false; - } - - $query_id = sizeof($this->sql_rowset); - $this->sql_rowset[$query_id] = $rowset; - $this->sql_row_pointer[$query_id] = 0; - - return $query_id; - } - - /** - * Save sql query - */ - function sql_save($query, &$query_result, $ttl) - { - global $db; - - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - - $query_id = sizeof($this->sql_rowset); - $this->sql_rowset[$query_id] = array(); - $this->sql_row_pointer[$query_id] = 0; - - while ($row = $db->sql_fetchrow($query_result)) - { - $this->sql_rowset[$query_id][] = $row; - } - $db->sql_freeresult($query_result); - - if ($this->_write('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl + time(), $query)) - { - $query_result = $query_id; - } - } - - /** - * Ceck if a given sql query exist in cache - */ - function sql_exists($query_id) - { - return isset($this->sql_rowset[$query_id]); - } - - /** - * Fetch row from cache (database) - */ - function sql_fetchrow($query_id) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; - } - - return false; - } - - /** - * Fetch a field from the current row of a cached database result (database) - */ - function sql_fetchfield($query_id, $field) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; - } - - return false; - } - - /** - * Seek a specific row in an a cached database result (database) - */ - function sql_rowseek($rownum, $query_id) - { - if ($rownum >= sizeof($this->sql_rowset[$query_id])) - { - return false; - } - - $this->sql_row_pointer[$query_id] = $rownum; - return true; - } - - /** - * Free memory used for a cached database result (database) - */ - function sql_freeresult($query_id) - { - if (!isset($this->sql_rowset[$query_id])) - { - return false; - } - - unset($this->sql_rowset[$query_id]); - unset($this->sql_row_pointer[$query_id]); - - return true; - } - - /** - * Read cached data from a specified file - * - * @access private - * @param string $filename Filename to write - * @return mixed False if an error was encountered, otherwise the data type of the cached data - */ - function _read($filename) - { - global $phpEx; - - $file = "{$this->cache_dir}$filename.$phpEx"; - - $type = substr($filename, 0, strpos($filename, '_')); - - if (!file_exists($file)) - { - return false; - } - - if (!($handle = @fopen($file, 'rb'))) - { - return false; - } - - // Skip the PHP header - fgets($handle); - - if ($filename == 'data_global') - { - $this->vars = $this->var_expires = array(); - - $time = time(); - - while (($expires = (int) fgets($handle)) && !feof($handle)) - { - // Number of bytes of data - $bytes = substr(fgets($handle), 0, -1); - - if (!is_numeric($bytes) || ($bytes = (int) $bytes) === 0) - { - // We cannot process the file without a valid number of bytes - // so we discard it - fclose($handle); - - $this->vars = $this->var_expires = array(); - $this->is_modified = false; - - $this->remove_file($file); - - return false; - } - - if ($time >= $expires) - { - fseek($handle, $bytes, SEEK_CUR); - - continue; - } - - $var_name = substr(fgets($handle), 0, -1); - - // Read the length of bytes that consists of data. - $data = fread($handle, $bytes - strlen($var_name)); - $data = @unserialize($data); - - // Don't use the data if it was invalid - if ($data !== false) - { - $this->vars[$var_name] = $data; - $this->var_expires[$var_name] = $expires; - } - - // Absorb the LF - fgets($handle); - } - - fclose($handle); - - $this->is_modified = false; - - return true; - } - else - { - $data = false; - $line = 0; - - while (($buffer = fgets($handle)) && !feof($handle)) - { - $buffer = substr($buffer, 0, -1); // Remove the LF - - // $buffer is only used to read integers - // if it is non numeric we have an invalid - // cache file, which we will now remove. - if (!is_numeric($buffer)) - { - break; - } - - if ($line == 0) - { - $expires = (int) $buffer; - - if (time() >= $expires) - { - break; - } - - if ($type == 'sql') - { - // Skip the query - fgets($handle); - } - } - else if ($line == 1) - { - $bytes = (int) $buffer; - - // Never should have 0 bytes - if (!$bytes) - { - break; - } - - // Grab the serialized data - $data = fread($handle, $bytes); - - // Read 1 byte, to trigger EOF - fread($handle, 1); - - if (!feof($handle)) - { - // Somebody tampered with our data - $data = false; - } - break; - } - else - { - // Something went wrong - break; - } - $line++; - } - fclose($handle); - - // unserialize if we got some data - $data = ($data !== false) ? @unserialize($data) : $data; - - if ($data === false) - { - $this->remove_file($file); - return false; - } - - return $data; - } - } - - /** - * Write cache data to a specified file - * - * 'data_global' is a special case and the generated format is different for this file: - * - * - * (expiration) - * (length of var and serialised data) - * (var) - * (serialised data) - * ... (repeat) - * - * - * The other files have a similar format: - * - * - * (expiration) - * (query) [SQL files only] - * (length of serialised data) - * (serialised data) - * - * - * @access private - * @param string $filename Filename to write - * @param mixed $data Data to store - * @param int $expires Timestamp when the data expires - * @param string $query Query when caching SQL queries - * @return bool True if the file was successfully created, otherwise false - */ - function _write($filename, $data = null, $expires = 0, $query = '') - { - global $phpEx; - - $file = "{$this->cache_dir}$filename.$phpEx"; - - if ($handle = @fopen($file, 'wb')) - { - @flock($handle, LOCK_EX); - - // File header - fwrite($handle, '<' . '?php exit; ?' . '>'); - - if ($filename == 'data_global') - { - // Global data is a different format - foreach ($this->vars as $var => $data) - { - if (strpos($var, "\r") !== false || strpos($var, "\n") !== false) - { - // CR/LF would cause fgets() to read the cache file incorrectly - // do not cache test entries, they probably won't be read back - // the cache keys should really be alphanumeric with a few symbols. - continue; - } - $data = serialize($data); - - // Write out the expiration time - fwrite($handle, "\n" . $this->var_expires[$var] . "\n"); - - // Length of the remaining data for this var (ignoring two LF's) - fwrite($handle, strlen($data . $var) . "\n"); - fwrite($handle, $var . "\n"); - fwrite($handle, $data); - } - } - else - { - fwrite($handle, "\n" . $expires . "\n"); - - if (strpos($filename, 'sql_') === 0) - { - fwrite($handle, $query . "\n"); - } - $data = serialize($data); - - fwrite($handle, strlen($data) . "\n"); - fwrite($handle, $data); - } - - @flock($handle, LOCK_UN); - fclose($handle); - - if (!function_exists('phpbb_chmod')) - { - global $phpbb_root_path; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE); - - return true; - } - - return false; - } - - /** - * Removes/unlinks file - */ - function remove_file($filename, $check = false) - { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - if ($check && !phpbb_is_writable($this->cache_dir)) - { - // E_USER_ERROR - not using language entry - intended. - trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); - } - - return @unlink($filename); - } -} diff --git a/phpBB/includes/acm/acm_memcache.php b/phpBB/includes/acm/acm_memcache.php deleted file mode 100644 index 527db71f80..0000000000 --- a/phpBB/includes/acm/acm_memcache.php +++ /dev/null @@ -1,136 +0,0 @@ -memcache = new Memcache; - foreach(explode(',', PHPBB_ACM_MEMCACHE) as $u) - { - $parts = explode('/', $u); - $this->memcache->addServer(trim($parts[0]), trim($parts[1])); - } - $this->flags = (PHPBB_ACM_MEMCACHE_COMPRESS) ? MEMCACHE_COMPRESSED : 0; - } - - /** - * Unload the cache resources - * - * @return void - */ - function unload() - { - parent::unload(); - - $this->memcache->close(); - } - - /** - * Purge cache data - * - * @return void - */ - function purge() - { - $this->memcache->flush(); - - parent::purge(); - } - - /** - * Fetch an item from the cache - * - * @access protected - * @param string $var Cache key - * @return mixed Cached data - */ - function _read($var) - { - return $this->memcache->get($this->key_prefix . $var); - } - - /** - * Store data in the cache - * - * @access protected - * @param string $var Cache key - * @param mixed $data Data to store - * @param int $ttl Time-to-live of cached data - * @return bool True if the operation succeeded - */ - function _write($var, $data, $ttl = 2592000) - { - if (!$this->memcache->replace($this->key_prefix . $var, $data, $this->flags, $ttl)) - { - return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl); - } - return true; - } - - /** - * Remove an item from the cache - * - * @access protected - * @param string $var Cache key - * @return bool True if the operation succeeded - */ - function _delete($var) - { - return $this->memcache->delete($this->key_prefix . $var); - } -} diff --git a/phpBB/includes/acm/acm_memory.php b/phpBB/includes/acm/acm_memory.php deleted file mode 100644 index d248487846..0000000000 --- a/phpBB/includes/acm/acm_memory.php +++ /dev/null @@ -1,437 +0,0 @@ -cache_dir = $phpbb_root_path . 'cache/'; - $this->key_prefix = substr(md5($dbname . $table_prefix), 0, 8) . '_'; - - if (!isset($this->extension) || !extension_loaded($this->extension)) - { - global $acm_type; - - trigger_error("Could not find required extension [{$this->extension}] for the ACM module $acm_type.", E_USER_ERROR); - } - - if (isset($this->function) && !function_exists($this->function)) - { - global $acm_type; - - trigger_error("The required function [{$this->function}] is not available for the ACM module $acm_type.", E_USER_ERROR); - } - } - - /** - * Load global cache - */ - function load() - { - // grab the global cache - $this->vars = $this->_read('global'); - - if ($this->vars !== false) - { - return true; - } - - return false; - } - - /** - * Unload cache object - */ - function unload() - { - $this->save(); - unset($this->vars); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - } - - /** - * Save modified objects - */ - function save() - { - if (!$this->is_modified) - { - return; - } - - $this->_write('global', $this->vars, 2592000); - - $this->is_modified = false; - } - - /** - * Tidy cache - */ - function tidy() - { - // cache has auto GC, no need to have any code here :) - - set_config('cache_last_gc', time(), true); - } - - /** - * Get saved cache object - */ - function get($var_name) - { - if ($var_name[0] == '_') - { - if (!$this->_exists($var_name)) - { - return false; - } - - return $this->_read($var_name); - } - else - { - return ($this->_exists($var_name)) ? $this->vars[$var_name] : false; - } - } - - /** - * Put data into cache - */ - function put($var_name, $var, $ttl = 2592000) - { - if ($var_name[0] == '_') - { - $this->_write($var_name, $var, $ttl); - } - else - { - $this->vars[$var_name] = $var; - $this->is_modified = true; - } - } - - /** - * Purge cache data - */ - function purge() - { - // Purge all phpbb cache files - $dir = @opendir($this->cache_dir); - - if (!$dir) - { - return; - } - - while (($entry = readdir($dir)) !== false) - { - if (strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && strpos($entry, 'tpl_') !== 0) - { - continue; - } - - $this->remove_file($this->cache_dir . $entry); - } - closedir($dir); - - unset($this->vars); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - - $this->is_modified = false; - } - - - /** - * Destroy cache data - */ - function destroy($var_name, $table = '') - { - if ($var_name == 'sql' && !empty($table)) - { - if (!is_array($table)) - { - $table = array($table); - } - - foreach ($table as $table_name) - { - // gives us the md5s that we want - $temp = $this->_read('sql_' . $table_name); - - if ($temp === false) - { - continue; - } - - // delete each query ref - foreach ($temp as $md5_id => $void) - { - $this->_delete('sql_' . $md5_id); - } - - // delete the table ref - $this->_delete('sql_' . $table_name); - } - - return; - } - - if (!$this->_exists($var_name)) - { - return; - } - - if ($var_name[0] == '_') - { - $this->_delete($var_name); - } - else if (isset($this->vars[$var_name])) - { - $this->is_modified = true; - unset($this->vars[$var_name]); - - // We save here to let the following cache hits succeed - $this->save(); - } - } - - /** - * Check if a given cache entry exist - */ - function _exists($var_name) - { - if ($var_name[0] == '_') - { - return $this->_isset($var_name); - } - else - { - if (!sizeof($this->vars)) - { - $this->load(); - } - - return isset($this->vars[$var_name]); - } - } - - /** - * Load cached sql query - */ - function sql_load($query) - { - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $query_id = sizeof($this->sql_rowset); - - if (($result = $this->_read('sql_' . md5($query))) === false) - { - return false; - } - - $this->sql_rowset[$query_id] = $result; - $this->sql_row_pointer[$query_id] = 0; - - return $query_id; - } - - /** - * Save sql query - */ - function sql_save($query, &$query_result, $ttl) - { - global $db; - - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $hash = md5($query); - - // determine which tables this query belongs to - // Some queries use backticks, namely the get_database_size() query - // don't check for conformity, the SQL would error and not reach here. - if (!preg_match('/FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?/', $query, $regs)) - { - // Bail out if the match fails. - return; - } - $tables = array_map('trim', explode(',', $regs[1])); - - foreach ($tables as $table_name) - { - // Remove backticks - $table_name = ($table_name[0] == '`') ? substr($table_name, 1, -1) : $table_name; - - if (($pos = strpos($table_name, ' ')) !== false) - { - $table_name = substr($table_name, 0, $pos); - } - - $temp = $this->_read('sql_' . $table_name); - - if ($temp === false) - { - $temp = array(); - } - - $temp[$hash] = true; - - // This must never expire - $this->_write('sql_' . $table_name, $temp, 0); - } - - // store them in the right place - $query_id = sizeof($this->sql_rowset); - $this->sql_rowset[$query_id] = array(); - $this->sql_row_pointer[$query_id] = 0; - - while ($row = $db->sql_fetchrow($query_result)) - { - $this->sql_rowset[$query_id][] = $row; - } - $db->sql_freeresult($query_result); - - $this->_write('sql_' . $hash, $this->sql_rowset[$query_id], $ttl); - - $query_result = $query_id; - } - - /** - * Ceck if a given sql query exist in cache - */ - function sql_exists($query_id) - { - return isset($this->sql_rowset[$query_id]); - } - - /** - * Fetch row from cache (database) - */ - function sql_fetchrow($query_id) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; - } - - return false; - } - - /** - * Fetch a field from the current row of a cached database result (database) - */ - function sql_fetchfield($query_id, $field) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; - } - - return false; - } - - /** - * Seek a specific row in an a cached database result (database) - */ - function sql_rowseek($rownum, $query_id) - { - if ($rownum >= sizeof($this->sql_rowset[$query_id])) - { - return false; - } - - $this->sql_row_pointer[$query_id] = $rownum; - return true; - } - - /** - * Free memory used for a cached database result (database) - */ - function sql_freeresult($query_id) - { - if (!isset($this->sql_rowset[$query_id])) - { - return false; - } - - unset($this->sql_rowset[$query_id]); - unset($this->sql_row_pointer[$query_id]); - - return true; - } - - /** - * Removes/unlinks file - */ - function remove_file($filename, $check = false) - { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - if ($check && !phpbb_is_writable($this->cache_dir)) - { - // E_USER_ERROR - not using language entry - intended. - trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); - } - - return @unlink($filename); - } - - /** - * Check if a cache var exists - * - * @access protected - * @param string $var Cache key - * @return bool True if it exists, otherwise false - */ - function _isset($var) - { - // Most caches don't need to check - return true; - } -} diff --git a/phpBB/includes/acm/acm_null.php b/phpBB/includes/acm/acm_null.php deleted file mode 100644 index 79f2b59c0f..0000000000 --- a/phpBB/includes/acm/acm_null.php +++ /dev/null @@ -1,154 +0,0 @@ - 0 -* - xcache.admin.enable_auth = off (or xcache.admin.user and xcache.admin.password set) -* -*/ -class acm extends acm_memory -{ - var $extension = 'XCache'; - - function acm() - { - parent::acm_memory(); - - if (!function_exists('ini_get') || (int) ini_get('xcache.var_size') <= 0) - { - trigger_error('Increase xcache.var_size setting above 0 or enable ini_get() to use this ACM module.', E_USER_ERROR); - } - } - - /** - * Purge cache data - * - * @return void - */ - function purge() - { - // Run before for XCache, if admin functions are disabled it will terminate execution - parent::purge(); - - // If the admin authentication is enabled but not set up, this will cause a nasty error. - // Not much we can do about it though. - $n = xcache_count(XC_TYPE_VAR); - - for ($i = 0; $i < $n; $i++) - { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - } - - /** - * Fetch an item from the cache - * - * @access protected - * @param string $var Cache key - * @return mixed Cached data - */ - function _read($var) - { - $result = xcache_get($this->key_prefix . $var); - - return ($result !== null) ? $result : false; - } - - /** - * Store data in the cache - * - * @access protected - * @param string $var Cache key - * @param mixed $data Data to store - * @param int $ttl Time-to-live of cached data - * @return bool True if the operation succeeded - */ - function _write($var, $data, $ttl = 2592000) - { - return xcache_set($this->key_prefix . $var, $data, $ttl); - } - - /** - * Remove an item from the cache - * - * @access protected - * @param string $var Cache key - * @return bool True if the operation succeeded - */ - function _delete($var) - { - return xcache_unset($this->key_prefix . $var); - } - - /** - * Check if a cache var exists - * - * @access protected - * @param string $var Cache key - * @return bool True if it exists, otherwise false - */ - function _isset($var) - { - return xcache_isset($this->key_prefix . $var); - } -} diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php deleted file mode 100644 index 49b690f1a4..0000000000 --- a/phpBB/includes/cache.php +++ /dev/null @@ -1,435 +0,0 @@ -get('config')) !== false) - { - $sql = 'SELECT config_name, config_value - FROM ' . CONFIG_TABLE . ' - WHERE is_dynamic = 1'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $config[$row['config_name']] = $row['config_value']; - } - $db->sql_freeresult($result); - } - else - { - $config = $cached_config = array(); - - $sql = 'SELECT config_name, config_value, is_dynamic - FROM ' . CONFIG_TABLE; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - if (!$row['is_dynamic']) - { - $cached_config[$row['config_name']] = $row['config_value']; - } - - $config[$row['config_name']] = $row['config_value']; - } - $db->sql_freeresult($result); - - $this->put('config', $cached_config); - } - - return $config; - } - - /** - * Obtain list of naughty words and build preg style replacement arrays for use by the - * calling script - */ - function obtain_word_list() - { - global $db; - - if (($censors = $this->get('_word_censors')) === false) - { - $sql = 'SELECT word, replacement - FROM ' . WORDS_TABLE; - $result = $db->sql_query($sql); - - $censors = array(); - while ($row = $db->sql_fetchrow($result)) - { - $censors['match'][] = get_censor_preg_expression($row['word']); - $censors['replace'][] = $row['replacement']; - } - $db->sql_freeresult($result); - - $this->put('_word_censors', $censors); - } - - return $censors; - } - - /** - * Obtain currently listed icons - */ - function obtain_icons() - { - if (($icons = $this->get('_icons')) === false) - { - global $db; - - // Topic icons - $sql = 'SELECT * - FROM ' . ICONS_TABLE . ' - ORDER BY icons_order'; - $result = $db->sql_query($sql); - - $icons = array(); - while ($row = $db->sql_fetchrow($result)) - { - $icons[$row['icons_id']]['img'] = $row['icons_url']; - $icons[$row['icons_id']]['width'] = (int) $row['icons_width']; - $icons[$row['icons_id']]['height'] = (int) $row['icons_height']; - $icons[$row['icons_id']]['display'] = (bool) $row['display_on_posting']; - } - $db->sql_freeresult($result); - - $this->put('_icons', $icons); - } - - return $icons; - } - - /** - * Obtain ranks - */ - function obtain_ranks() - { - if (($ranks = $this->get('_ranks')) === false) - { - global $db; - - $sql = 'SELECT * - FROM ' . RANKS_TABLE . ' - ORDER BY rank_min DESC'; - $result = $db->sql_query($sql); - - $ranks = array(); - while ($row = $db->sql_fetchrow($result)) - { - if ($row['rank_special']) - { - $ranks['special'][$row['rank_id']] = array( - 'rank_title' => $row['rank_title'], - 'rank_image' => $row['rank_image'] - ); - } - else - { - $ranks['normal'][] = array( - 'rank_title' => $row['rank_title'], - 'rank_min' => $row['rank_min'], - 'rank_image' => $row['rank_image'] - ); - } - } - $db->sql_freeresult($result); - - $this->put('_ranks', $ranks); - } - - return $ranks; - } - - /** - * Obtain allowed extensions - * - * @param mixed $forum_id If false then check for private messaging, if int then check for forum id. If true, then only return extension informations. - * - * @return array allowed extensions array. - */ - function obtain_attach_extensions($forum_id) - { - if (($extensions = $this->get('_extensions')) === false) - { - global $db; - - $extensions = array( - '_allowed_post' => array(), - '_allowed_pm' => array(), - ); - - // The rule is to only allow those extensions defined. ;) - $sql = 'SELECT e.extension, g.* - FROM ' . EXTENSIONS_TABLE . ' e, ' . EXTENSION_GROUPS_TABLE . ' g - WHERE e.group_id = g.group_id - AND (g.allow_group = 1 OR g.allow_in_pm = 1)'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $extension = strtolower(trim($row['extension'])); - - $extensions[$extension] = array( - 'display_cat' => (int) $row['cat_id'], - 'download_mode' => (int) $row['download_mode'], - 'upload_icon' => trim($row['upload_icon']), - 'max_filesize' => (int) $row['max_filesize'], - 'allow_group' => $row['allow_group'], - 'allow_in_pm' => $row['allow_in_pm'], - ); - - $allowed_forums = ($row['allowed_forums']) ? unserialize(trim($row['allowed_forums'])) : array(); - - // Store allowed extensions forum wise - if ($row['allow_group']) - { - $extensions['_allowed_post'][$extension] = (!sizeof($allowed_forums)) ? 0 : $allowed_forums; - } - - if ($row['allow_in_pm']) - { - $extensions['_allowed_pm'][$extension] = 0; - } - } - $db->sql_freeresult($result); - - $this->put('_extensions', $extensions); - } - - // Forum post - if ($forum_id === false) - { - // We are checking for private messages, therefore we only need to get the pm extensions... - $return = array('_allowed_' => array()); - - foreach ($extensions['_allowed_pm'] as $extension => $check) - { - $return['_allowed_'][$extension] = 0; - $return[$extension] = $extensions[$extension]; - } - - $extensions = $return; - } - else if ($forum_id === true) - { - return $extensions; - } - else - { - $forum_id = (int) $forum_id; - $return = array('_allowed_' => array()); - - foreach ($extensions['_allowed_post'] as $extension => $check) - { - // Check for allowed forums - if (is_array($check)) - { - $allowed = (!in_array($forum_id, $check)) ? false : true; - } - else - { - $allowed = true; - } - - if ($allowed) - { - $return['_allowed_'][$extension] = 0; - $return[$extension] = $extensions[$extension]; - } - } - - $extensions = $return; - } - - if (!isset($extensions['_allowed_'])) - { - $extensions['_allowed_'] = array(); - } - - return $extensions; - } - - /** - * Obtain active bots - */ - function obtain_bots() - { - if (($bots = $this->get('_bots')) === false) - { - global $db; - - switch ($db->sql_layer) - { - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $sql = 'SELECT user_id, bot_agent, bot_ip - FROM ' . BOTS_TABLE . ' - WHERE bot_active = 1 - ORDER BY LEN(bot_agent) DESC'; - break; - - case 'firebird': - $sql = 'SELECT user_id, bot_agent, bot_ip - FROM ' . BOTS_TABLE . ' - WHERE bot_active = 1 - ORDER BY CHAR_LENGTH(bot_agent) DESC'; - break; - - // LENGTH supported by MySQL, IBM DB2 and Oracle for sure... - default: - $sql = 'SELECT user_id, bot_agent, bot_ip - FROM ' . BOTS_TABLE . ' - WHERE bot_active = 1 - ORDER BY LENGTH(bot_agent) DESC'; - break; - } - $result = $db->sql_query($sql); - - $bots = array(); - while ($row = $db->sql_fetchrow($result)) - { - $bots[] = $row; - } - $db->sql_freeresult($result); - - $this->put('_bots', $bots); - } - - return $bots; - } - - /** - * Obtain cfg file data - */ - function obtain_cfg_items($theme) - { - global $config, $phpbb_root_path; - - $parsed_items = array( - 'theme' => array(), - 'template' => array(), - 'imageset' => array() - ); - - foreach ($parsed_items as $key => $parsed_array) - { - $parsed_array = $this->get('_cfg_' . $key . '_' . $theme[$key . '_path']); - - if ($parsed_array === false) - { - $parsed_array = array(); - } - - $reparse = false; - $filename = $phpbb_root_path . 'styles/' . $theme[$key . '_path'] . '/' . $key . '/' . $key . '.cfg'; - - if (!file_exists($filename)) - { - continue; - } - - if (!isset($parsed_array['filetime']) || (($config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) - { - $reparse = true; - } - - // Re-parse cfg file - if ($reparse) - { - $parsed_array = parse_cfg_file($filename); - $parsed_array['filetime'] = @filemtime($filename); - - $this->put('_cfg_' . $key . '_' . $theme[$key . '_path'], $parsed_array); - } - $parsed_items[$key] = $parsed_array; - } - - return $parsed_items; - } - - /** - * Obtain disallowed usernames - */ - function obtain_disallowed_usernames() - { - if (($usernames = $this->get('_disallowed_usernames')) === false) - { - global $db; - - $sql = 'SELECT disallow_username - FROM ' . DISALLOW_TABLE; - $result = $db->sql_query($sql); - - $usernames = array(); - while ($row = $db->sql_fetchrow($result)) - { - $usernames[] = str_replace('%', '.*?', preg_quote(utf8_clean_string($row['disallow_username']), '#')); - } - $db->sql_freeresult($result); - - $this->put('_disallowed_usernames', $usernames); - } - - return $usernames; - } - - /** - * Obtain hooks... - */ - function obtain_hooks() - { - global $phpbb_root_path, $phpEx; - - if (($hook_files = $this->get('_hooks')) === false) - { - $hook_files = array(); - - // Now search for hooks... - $dh = @opendir($phpbb_root_path . 'includes/hooks/'); - - if ($dh) - { - while (($file = readdir($dh)) !== false) - { - if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) - { - $hook_files[] = substr($file, 0, -(strlen($phpEx) + 1)); - } - } - closedir($dh); - } - - $this->put('_hooks', $hook_files); - } - - return $hook_files; - } -} diff --git a/phpBB/includes/cache/driver/apc.php b/phpBB/includes/cache/driver/apc.php new file mode 100644 index 0000000000..a97cbe4dd1 --- /dev/null +++ b/phpBB/includes/cache/driver/apc.php @@ -0,0 +1,76 @@ +key_prefix . $var); + } + + /** + * Store data in the cache + * + * @access protected + * @param string $var Cache key + * @param mixed $data Data to store + * @param int $ttl Time-to-live of cached data + * @return bool True if the operation succeeded + */ + function _write($var, $data, $ttl = 2592000) + { + return apc_store($this->key_prefix . $var, $data, $ttl); + } + + /** + * Remove an item from the cache + * + * @access protected + * @param string $var Cache key + * @return bool True if the operation succeeded + */ + function _delete($var) + { + return apc_delete($this->key_prefix . $var); + } +} diff --git a/phpBB/includes/cache/driver/base.php b/phpBB/includes/cache/driver/base.php new file mode 100644 index 0000000000..a71eca45d7 --- /dev/null +++ b/phpBB/includes/cache/driver/base.php @@ -0,0 +1,24 @@ +key_prefix + eaccelerator_rm(substr($var['name'], 1)); + } + + parent::purge(); + } + + /** + * Perform cache garbage collection + * + * @return void + */ + function tidy() + { + eaccelerator_gc(); + + set_config('cache_last_gc', time(), true); + } + + /** + * Fetch an item from the cache + * + * @access protected + * @param string $var Cache key + * @return mixed Cached data + */ + function _read($var) + { + $result = eaccelerator_get($this->key_prefix . $var); + + if ($result === null) + { + return false; + } + + // Handle serialized objects + if (is_string($result) && strpos($result, $this->serialize_header . 'O:') === 0) + { + $result = unserialize(substr($result, strlen($this->serialize_header))); + } + + return $result; + } + + /** + * Store data in the cache + * + * @access protected + * @param string $var Cache key + * @param mixed $data Data to store + * @param int $ttl Time-to-live of cached data + * @return bool True if the operation succeeded + */ + function _write($var, $data, $ttl = 2592000) + { + // Serialize objects and make them easy to detect + $data = (is_object($data)) ? $this->serialize_header . serialize($data) : $data; + + return eaccelerator_put($this->key_prefix . $var, $data, $ttl); + } + + /** + * Remove an item from the cache + * + * @access protected + * @param string $var Cache key + * @return bool True if the operation succeeded + */ + function _delete($var) + { + return eaccelerator_rm($this->key_prefix . $var); + } +} diff --git a/phpBB/includes/cache/driver/file.php b/phpBB/includes/cache/driver/file.php new file mode 100644 index 0000000000..e26fecf534 --- /dev/null +++ b/phpBB/includes/cache/driver/file.php @@ -0,0 +1,730 @@ +cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/'; + } + + /** + * Load global cache + */ + function load() + { + return $this->_read('data_global'); + } + + /** + * Unload cache object + */ + function unload() + { + $this->save(); + unset($this->vars); + unset($this->var_expires); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->var_expires = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + } + + /** + * Save modified objects + */ + function save() + { + if (!$this->is_modified) + { + return; + } + + global $phpEx; + + if (!$this->_write('data_global')) + { + if (!function_exists('phpbb_is_writable')) + { + global $phpbb_root_path; + include($phpbb_root_path . 'includes/functions.' . $phpEx); + } + + // Now, this occurred how often? ... phew, just tell the user then... + if (!phpbb_is_writable($this->cache_dir)) + { + // We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload()) + die($this->cache_dir . ' is NOT writable.'); + exit; + } + + die('Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx); + exit; + } + + $this->is_modified = false; + } + + /** + * Tidy cache + */ + function tidy() + { + global $phpEx; + + $dir = @opendir($this->cache_dir); + + if (!$dir) + { + return; + } + + $time = time(); + + while (($entry = readdir($dir)) !== false) + { + if (!preg_match('/^(sql_|data_(?!global))/', $entry)) + { + continue; + } + + if (!($handle = @fopen($this->cache_dir . $entry, 'rb'))) + { + continue; + } + + // Skip the PHP header + fgets($handle); + + // Skip expiration + $expires = (int) fgets($handle); + + fclose($handle); + + if ($time >= $expires) + { + $this->remove_file($this->cache_dir . $entry); + } + } + closedir($dir); + + if (file_exists($this->cache_dir . 'data_global.' . $phpEx)) + { + if (!sizeof($this->vars)) + { + $this->load(); + } + + foreach ($this->var_expires as $var_name => $expires) + { + if ($time >= $expires) + { + $this->destroy($var_name); + } + } + } + + set_config('cache_last_gc', time(), true); + } + + /** + * Get saved cache object + */ + function get($var_name) + { + if ($var_name[0] == '_') + { + global $phpEx; + + if (!$this->_exists($var_name)) + { + return false; + } + + return $this->_read('data' . $var_name); + } + else + { + return ($this->_exists($var_name)) ? $this->vars[$var_name] : false; + } + } + + /** + * Put data into cache + */ + function put($var_name, $var, $ttl = 31536000) + { + if ($var_name[0] == '_') + { + $this->_write('data' . $var_name, $var, time() + $ttl); + } + else + { + $this->vars[$var_name] = $var; + $this->var_expires[$var_name] = time() + $ttl; + $this->is_modified = true; + } + } + + /** + * Purge cache data + */ + function purge() + { + // Purge all phpbb cache files + $dir = @opendir($this->cache_dir); + + if (!$dir) + { + return; + } + + while (($entry = readdir($dir)) !== false) + { + if (strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && strpos($entry, 'tpl_') !== 0) + { + continue; + } + + $this->remove_file($this->cache_dir . $entry); + } + closedir($dir); + + unset($this->vars); + unset($this->var_expires); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->var_expires = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + + $this->is_modified = false; + } + + /** + * Destroy cache data + */ + function destroy($var_name, $table = '') + { + global $phpEx; + + if ($var_name == 'sql' && !empty($table)) + { + if (!is_array($table)) + { + $table = array($table); + } + + $dir = @opendir($this->cache_dir); + + if (!$dir) + { + return; + } + + while (($entry = readdir($dir)) !== false) + { + if (strpos($entry, 'sql_') !== 0) + { + continue; + } + + if (!($handle = @fopen($this->cache_dir . $entry, 'rb'))) + { + continue; + } + + // Skip the PHP header + fgets($handle); + + // Skip expiration + fgets($handle); + + // Grab the query, remove the LF + $query = substr(fgets($handle), 0, -1); + + fclose($handle); + + foreach ($table as $check_table) + { + // Better catch partial table names than no table names. ;) + if (strpos($query, $check_table) !== false) + { + $this->remove_file($this->cache_dir . $entry); + break; + } + } + } + closedir($dir); + + return; + } + + if (!$this->_exists($var_name)) + { + return; + } + + if ($var_name[0] == '_') + { + $this->remove_file($this->cache_dir . 'data' . $var_name . ".$phpEx", true); + } + else if (isset($this->vars[$var_name])) + { + $this->is_modified = true; + unset($this->vars[$var_name]); + unset($this->var_expires[$var_name]); + + // We save here to let the following cache hits succeed + $this->save(); + } + } + + /** + * Check if a given cache entry exist + */ + function _exists($var_name) + { + if ($var_name[0] == '_') + { + global $phpEx; + return file_exists($this->cache_dir . 'data' . $var_name . ".$phpEx"); + } + else + { + if (!sizeof($this->vars)) + { + $this->load(); + } + + if (!isset($this->var_expires[$var_name])) + { + return false; + } + + return (time() > $this->var_expires[$var_name]) ? false : isset($this->vars[$var_name]); + } + } + + /** + * Load cached sql query + */ + function sql_load($query) + { + // Remove extra spaces and tabs + $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + + if (($rowset = $this->_read('sql_' . md5($query))) === false) + { + return false; + } + + $query_id = sizeof($this->sql_rowset); + $this->sql_rowset[$query_id] = $rowset; + $this->sql_row_pointer[$query_id] = 0; + + return $query_id; + } + + /** + * Save sql query + */ + function sql_save($query, &$query_result, $ttl) + { + global $db; + + // Remove extra spaces and tabs + $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + + $query_id = sizeof($this->sql_rowset); + $this->sql_rowset[$query_id] = array(); + $this->sql_row_pointer[$query_id] = 0; + + while ($row = $db->sql_fetchrow($query_result)) + { + $this->sql_rowset[$query_id][] = $row; + } + $db->sql_freeresult($query_result); + + if ($this->_write('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl + time(), $query)) + { + $query_result = $query_id; + } + } + + /** + * Ceck if a given sql query exist in cache + */ + function sql_exists($query_id) + { + return isset($this->sql_rowset[$query_id]); + } + + /** + * Fetch row from cache (database) + */ + function sql_fetchrow($query_id) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; + } + + return false; + } + + /** + * Fetch a field from the current row of a cached database result (database) + */ + function sql_fetchfield($query_id, $field) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; + } + + return false; + } + + /** + * Seek a specific row in an a cached database result (database) + */ + function sql_rowseek($rownum, $query_id) + { + if ($rownum >= sizeof($this->sql_rowset[$query_id])) + { + return false; + } + + $this->sql_row_pointer[$query_id] = $rownum; + return true; + } + + /** + * Free memory used for a cached database result (database) + */ + function sql_freeresult($query_id) + { + if (!isset($this->sql_rowset[$query_id])) + { + return false; + } + + unset($this->sql_rowset[$query_id]); + unset($this->sql_row_pointer[$query_id]); + + return true; + } + + /** + * Read cached data from a specified file + * + * @access private + * @param string $filename Filename to write + * @return mixed False if an error was encountered, otherwise the data type of the cached data + */ + function _read($filename) + { + global $phpEx; + + $file = "{$this->cache_dir}$filename.$phpEx"; + + $type = substr($filename, 0, strpos($filename, '_')); + + if (!file_exists($file)) + { + return false; + } + + if (!($handle = @fopen($file, 'rb'))) + { + return false; + } + + // Skip the PHP header + fgets($handle); + + if ($filename == 'data_global') + { + $this->vars = $this->var_expires = array(); + + $time = time(); + + while (($expires = (int) fgets($handle)) && !feof($handle)) + { + // Number of bytes of data + $bytes = substr(fgets($handle), 0, -1); + + if (!is_numeric($bytes) || ($bytes = (int) $bytes) === 0) + { + // We cannot process the file without a valid number of bytes + // so we discard it + fclose($handle); + + $this->vars = $this->var_expires = array(); + $this->is_modified = false; + + $this->remove_file($file); + + return false; + } + + if ($time >= $expires) + { + fseek($handle, $bytes, SEEK_CUR); + + continue; + } + + $var_name = substr(fgets($handle), 0, -1); + + // Read the length of bytes that consists of data. + $data = fread($handle, $bytes - strlen($var_name)); + $data = @unserialize($data); + + // Don't use the data if it was invalid + if ($data !== false) + { + $this->vars[$var_name] = $data; + $this->var_expires[$var_name] = $expires; + } + + // Absorb the LF + fgets($handle); + } + + fclose($handle); + + $this->is_modified = false; + + return true; + } + else + { + $data = false; + $line = 0; + + while (($buffer = fgets($handle)) && !feof($handle)) + { + $buffer = substr($buffer, 0, -1); // Remove the LF + + // $buffer is only used to read integers + // if it is non numeric we have an invalid + // cache file, which we will now remove. + if (!is_numeric($buffer)) + { + break; + } + + if ($line == 0) + { + $expires = (int) $buffer; + + if (time() >= $expires) + { + break; + } + + if ($type == 'sql') + { + // Skip the query + fgets($handle); + } + } + else if ($line == 1) + { + $bytes = (int) $buffer; + + // Never should have 0 bytes + if (!$bytes) + { + break; + } + + // Grab the serialized data + $data = fread($handle, $bytes); + + // Read 1 byte, to trigger EOF + fread($handle, 1); + + if (!feof($handle)) + { + // Somebody tampered with our data + $data = false; + } + break; + } + else + { + // Something went wrong + break; + } + $line++; + } + fclose($handle); + + // unserialize if we got some data + $data = ($data !== false) ? @unserialize($data) : $data; + + if ($data === false) + { + $this->remove_file($file); + return false; + } + + return $data; + } + } + + /** + * Write cache data to a specified file + * + * 'data_global' is a special case and the generated format is different for this file: + * + * + * (expiration) + * (length of var and serialised data) + * (var) + * (serialised data) + * ... (repeat) + * + * + * The other files have a similar format: + * + * + * (expiration) + * (query) [SQL files only] + * (length of serialised data) + * (serialised data) + * + * + * @access private + * @param string $filename Filename to write + * @param mixed $data Data to store + * @param int $expires Timestamp when the data expires + * @param string $query Query when caching SQL queries + * @return bool True if the file was successfully created, otherwise false + */ + function _write($filename, $data = null, $expires = 0, $query = '') + { + global $phpEx; + + $file = "{$this->cache_dir}$filename.$phpEx"; + + if ($handle = @fopen($file, 'wb')) + { + @flock($handle, LOCK_EX); + + // File header + fwrite($handle, '<' . '?php exit; ?' . '>'); + + if ($filename == 'data_global') + { + // Global data is a different format + foreach ($this->vars as $var => $data) + { + if (strpos($var, "\r") !== false || strpos($var, "\n") !== false) + { + // CR/LF would cause fgets() to read the cache file incorrectly + // do not cache test entries, they probably won't be read back + // the cache keys should really be alphanumeric with a few symbols. + continue; + } + $data = serialize($data); + + // Write out the expiration time + fwrite($handle, "\n" . $this->var_expires[$var] . "\n"); + + // Length of the remaining data for this var (ignoring two LF's) + fwrite($handle, strlen($data . $var) . "\n"); + fwrite($handle, $var . "\n"); + fwrite($handle, $data); + } + } + else + { + fwrite($handle, "\n" . $expires . "\n"); + + if (strpos($filename, 'sql_') === 0) + { + fwrite($handle, $query . "\n"); + } + $data = serialize($data); + + fwrite($handle, strlen($data) . "\n"); + fwrite($handle, $data); + } + + @flock($handle, LOCK_UN); + fclose($handle); + + if (!function_exists('phpbb_chmod')) + { + global $phpbb_root_path; + include($phpbb_root_path . 'includes/functions.' . $phpEx); + } + + phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE); + + return true; + } + + return false; + } + + /** + * Removes/unlinks file + */ + function remove_file($filename, $check = false) + { + if (!function_exists('phpbb_is_writable')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/functions.' . $phpEx); + } + + if ($check && !phpbb_is_writable($this->cache_dir)) + { + // E_USER_ERROR - not using language entry - intended. + trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); + } + + return @unlink($filename); + } +} diff --git a/phpBB/includes/cache/driver/interface.php b/phpBB/includes/cache/driver/interface.php new file mode 100644 index 0000000000..91d364abf6 --- /dev/null +++ b/phpBB/includes/cache/driver/interface.php @@ -0,0 +1,104 @@ +memcache = new Memcache; + foreach(explode(',', PHPBB_ACM_MEMCACHE) as $u) + { + $parts = explode('/', $u); + $this->memcache->addServer(trim($parts[0]), trim($parts[1])); + } + $this->flags = (PHPBB_ACM_MEMCACHE_COMPRESS) ? MEMCACHE_COMPRESSED : 0; + } + + /** + * Unload the cache resources + * + * @return void + */ + function unload() + { + parent::unload(); + + $this->memcache->close(); + } + + /** + * Purge cache data + * + * @return void + */ + function purge() + { + $this->memcache->flush(); + + parent::purge(); + } + + /** + * Fetch an item from the cache + * + * @access protected + * @param string $var Cache key + * @return mixed Cached data + */ + function _read($var) + { + return $this->memcache->get($this->key_prefix . $var); + } + + /** + * Store data in the cache + * + * @access protected + * @param string $var Cache key + * @param mixed $data Data to store + * @param int $ttl Time-to-live of cached data + * @return bool True if the operation succeeded + */ + function _write($var, $data, $ttl = 2592000) + { + if (!$this->memcache->replace($this->key_prefix . $var, $data, $this->flags, $ttl)) + { + return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl); + } + return true; + } + + /** + * Remove an item from the cache + * + * @access protected + * @param string $var Cache key + * @return bool True if the operation succeeded + */ + function _delete($var) + { + return $this->memcache->delete($this->key_prefix . $var); + } +} diff --git a/phpBB/includes/cache/driver/memory.php b/phpBB/includes/cache/driver/memory.php new file mode 100644 index 0000000000..633a0fe699 --- /dev/null +++ b/phpBB/includes/cache/driver/memory.php @@ -0,0 +1,437 @@ +cache_dir = $phpbb_root_path . 'cache/'; + $this->key_prefix = substr(md5($dbname . $table_prefix), 0, 8) . '_'; + + if (!isset($this->extension) || !extension_loaded($this->extension)) + { + global $acm_type; + + trigger_error("Could not find required extension [{$this->extension}] for the ACM module $acm_type.", E_USER_ERROR); + } + + if (isset($this->function) && !function_exists($this->function)) + { + global $acm_type; + + trigger_error("The required function [{$this->function}] is not available for the ACM module $acm_type.", E_USER_ERROR); + } + } + + /** + * Load global cache + */ + function load() + { + // grab the global cache + $this->vars = $this->_read('global'); + + if ($this->vars !== false) + { + return true; + } + + return false; + } + + /** + * Unload cache object + */ + function unload() + { + $this->save(); + unset($this->vars); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + } + + /** + * Save modified objects + */ + function save() + { + if (!$this->is_modified) + { + return; + } + + $this->_write('global', $this->vars, 2592000); + + $this->is_modified = false; + } + + /** + * Tidy cache + */ + function tidy() + { + // cache has auto GC, no need to have any code here :) + + set_config('cache_last_gc', time(), true); + } + + /** + * Get saved cache object + */ + function get($var_name) + { + if ($var_name[0] == '_') + { + if (!$this->_exists($var_name)) + { + return false; + } + + return $this->_read($var_name); + } + else + { + return ($this->_exists($var_name)) ? $this->vars[$var_name] : false; + } + } + + /** + * Put data into cache + */ + function put($var_name, $var, $ttl = 2592000) + { + if ($var_name[0] == '_') + { + $this->_write($var_name, $var, $ttl); + } + else + { + $this->vars[$var_name] = $var; + $this->is_modified = true; + } + } + + /** + * Purge cache data + */ + function purge() + { + // Purge all phpbb cache files + $dir = @opendir($this->cache_dir); + + if (!$dir) + { + return; + } + + while (($entry = readdir($dir)) !== false) + { + if (strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && strpos($entry, 'tpl_') !== 0) + { + continue; + } + + $this->remove_file($this->cache_dir . $entry); + } + closedir($dir); + + unset($this->vars); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + + $this->is_modified = false; + } + + + /** + * Destroy cache data + */ + function destroy($var_name, $table = '') + { + if ($var_name == 'sql' && !empty($table)) + { + if (!is_array($table)) + { + $table = array($table); + } + + foreach ($table as $table_name) + { + // gives us the md5s that we want + $temp = $this->_read('sql_' . $table_name); + + if ($temp === false) + { + continue; + } + + // delete each query ref + foreach ($temp as $md5_id => $void) + { + $this->_delete('sql_' . $md5_id); + } + + // delete the table ref + $this->_delete('sql_' . $table_name); + } + + return; + } + + if (!$this->_exists($var_name)) + { + return; + } + + if ($var_name[0] == '_') + { + $this->_delete($var_name); + } + else if (isset($this->vars[$var_name])) + { + $this->is_modified = true; + unset($this->vars[$var_name]); + + // We save here to let the following cache hits succeed + $this->save(); + } + } + + /** + * Check if a given cache entry exist + */ + function _exists($var_name) + { + if ($var_name[0] == '_') + { + return $this->_isset($var_name); + } + else + { + if (!sizeof($this->vars)) + { + $this->load(); + } + + return isset($this->vars[$var_name]); + } + } + + /** + * Load cached sql query + */ + function sql_load($query) + { + // Remove extra spaces and tabs + $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + $query_id = sizeof($this->sql_rowset); + + if (($result = $this->_read('sql_' . md5($query))) === false) + { + return false; + } + + $this->sql_rowset[$query_id] = $result; + $this->sql_row_pointer[$query_id] = 0; + + return $query_id; + } + + /** + * Save sql query + */ + function sql_save($query, &$query_result, $ttl) + { + global $db; + + // Remove extra spaces and tabs + $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + $hash = md5($query); + + // determine which tables this query belongs to + // Some queries use backticks, namely the get_database_size() query + // don't check for conformity, the SQL would error and not reach here. + if (!preg_match('/FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?/', $query, $regs)) + { + // Bail out if the match fails. + return; + } + $tables = array_map('trim', explode(',', $regs[1])); + + foreach ($tables as $table_name) + { + // Remove backticks + $table_name = ($table_name[0] == '`') ? substr($table_name, 1, -1) : $table_name; + + if (($pos = strpos($table_name, ' ')) !== false) + { + $table_name = substr($table_name, 0, $pos); + } + + $temp = $this->_read('sql_' . $table_name); + + if ($temp === false) + { + $temp = array(); + } + + $temp[$hash] = true; + + // This must never expire + $this->_write('sql_' . $table_name, $temp, 0); + } + + // store them in the right place + $query_id = sizeof($this->sql_rowset); + $this->sql_rowset[$query_id] = array(); + $this->sql_row_pointer[$query_id] = 0; + + while ($row = $db->sql_fetchrow($query_result)) + { + $this->sql_rowset[$query_id][] = $row; + } + $db->sql_freeresult($query_result); + + $this->_write('sql_' . $hash, $this->sql_rowset[$query_id], $ttl); + + $query_result = $query_id; + } + + /** + * Ceck if a given sql query exist in cache + */ + function sql_exists($query_id) + { + return isset($this->sql_rowset[$query_id]); + } + + /** + * Fetch row from cache (database) + */ + function sql_fetchrow($query_id) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; + } + + return false; + } + + /** + * Fetch a field from the current row of a cached database result (database) + */ + function sql_fetchfield($query_id, $field) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; + } + + return false; + } + + /** + * Seek a specific row in an a cached database result (database) + */ + function sql_rowseek($rownum, $query_id) + { + if ($rownum >= sizeof($this->sql_rowset[$query_id])) + { + return false; + } + + $this->sql_row_pointer[$query_id] = $rownum; + return true; + } + + /** + * Free memory used for a cached database result (database) + */ + function sql_freeresult($query_id) + { + if (!isset($this->sql_rowset[$query_id])) + { + return false; + } + + unset($this->sql_rowset[$query_id]); + unset($this->sql_row_pointer[$query_id]); + + return true; + } + + /** + * Removes/unlinks file + */ + function remove_file($filename, $check = false) + { + if (!function_exists('phpbb_is_writable')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/functions.' . $phpEx); + } + + if ($check && !phpbb_is_writable($this->cache_dir)) + { + // E_USER_ERROR - not using language entry - intended. + trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); + } + + return @unlink($filename); + } + + /** + * Check if a cache var exists + * + * @access protected + * @param string $var Cache key + * @return bool True if it exists, otherwise false + */ + function _isset($var) + { + // Most caches don't need to check + return true; + } +} diff --git a/phpBB/includes/cache/driver/null.php b/phpBB/includes/cache/driver/null.php new file mode 100644 index 0000000000..0a520b572e --- /dev/null +++ b/phpBB/includes/cache/driver/null.php @@ -0,0 +1,154 @@ + 0 +* - xcache.admin.enable_auth = off (or xcache.admin.user and xcache.admin.password set) +* +*/ +class phpbb_cache_driver_xcache extends phpbb_cache_driver_memory +{ + var $extension = 'XCache'; + + function __construct() + { + parent::__construct(); + + if (!function_exists('ini_get') || (int) ini_get('xcache.var_size') <= 0) + { + trigger_error('Increase xcache.var_size setting above 0 or enable ini_get() to use this ACM module.', E_USER_ERROR); + } + } + + /** + * Purge cache data + * + * @return void + */ + function purge() + { + // Run before for XCache, if admin functions are disabled it will terminate execution + parent::purge(); + + // If the admin authentication is enabled but not set up, this will cause a nasty error. + // Not much we can do about it though. + $n = xcache_count(XC_TYPE_VAR); + + for ($i = 0; $i < $n; $i++) + { + xcache_clear_cache(XC_TYPE_VAR, $i); + } + } + + /** + * Fetch an item from the cache + * + * @access protected + * @param string $var Cache key + * @return mixed Cached data + */ + function _read($var) + { + $result = xcache_get($this->key_prefix . $var); + + return ($result !== null) ? $result : false; + } + + /** + * Store data in the cache + * + * @access protected + * @param string $var Cache key + * @param mixed $data Data to store + * @param int $ttl Time-to-live of cached data + * @return bool True if the operation succeeded + */ + function _write($var, $data, $ttl = 2592000) + { + return xcache_set($this->key_prefix . $var, $data, $ttl); + } + + /** + * Remove an item from the cache + * + * @access protected + * @param string $var Cache key + * @return bool True if the operation succeeded + */ + function _delete($var) + { + return xcache_unset($this->key_prefix . $var); + } + + /** + * Check if a cache var exists + * + * @access protected + * @param string $var Cache key + * @return bool True if it exists, otherwise false + */ + function _isset($var) + { + return xcache_isset($this->key_prefix . $var); + } +} diff --git a/phpBB/includes/cache/factory.php b/phpBB/includes/cache/factory.php new file mode 100644 index 0000000000..cc88780bf2 --- /dev/null +++ b/phpBB/includes/cache/factory.php @@ -0,0 +1,52 @@ +acm_type = $acm_type; + } + + public function get_acm() + { + $class_name = 'phpbb_cache_driver_' . $this->acm_type; + return new $class_name(); + } + + public function get_service() + { + $acm = $this->get_acm(); + $service = new phpbb_cache_service($acm); + return $service; + } + + /** + * for convenience to allow: + * $cache = phpbb_cache_factory::create('file')->get_service(); + */ + public static function create($acm_type) + { + return new self($acm_type); + } +} diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php new file mode 100644 index 0000000000..424606bfc8 --- /dev/null +++ b/phpBB/includes/cache/service.php @@ -0,0 +1,452 @@ +set_acm($acm); + } + + public function set_acm(phpbb_cache_driver_interface $acm) + { + $this->acm = $acm; + } + + public function __call($method, $arguments) + { + return call_user_func_array(array($this->acm, $method), $arguments); + } + + /** + * Get config values + */ + function obtain_config() + { + global $db; + + if (($config = $this->acm->get('config')) !== false) + { + $sql = 'SELECT config_name, config_value + FROM ' . CONFIG_TABLE . ' + WHERE is_dynamic = 1'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + } + else + { + $config = $cached_config = array(); + + $sql = 'SELECT config_name, config_value, is_dynamic + FROM ' . CONFIG_TABLE; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + if (!$row['is_dynamic']) + { + $cached_config[$row['config_name']] = $row['config_value']; + } + + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + + $this->acm->put('config', $cached_config); + } + + return $config; + } + + /** + * Obtain list of naughty words and build preg style replacement arrays for use by the + * calling script + */ + function obtain_word_list() + { + global $db; + + if (($censors = $this->acm->get('_word_censors')) === false) + { + $sql = 'SELECT word, replacement + FROM ' . WORDS_TABLE; + $result = $db->sql_query($sql); + + $censors = array(); + while ($row = $db->sql_fetchrow($result)) + { + $censors['match'][] = get_censor_preg_expression($row['word']); + $censors['replace'][] = $row['replacement']; + } + $db->sql_freeresult($result); + + $this->acm->put('_word_censors', $censors); + } + + return $censors; + } + + /** + * Obtain currently listed icons + */ + function obtain_icons() + { + if (($icons = $this->acm->get('_icons')) === false) + { + global $db; + + // Topic icons + $sql = 'SELECT * + FROM ' . ICONS_TABLE . ' + ORDER BY icons_order'; + $result = $db->sql_query($sql); + + $icons = array(); + while ($row = $db->sql_fetchrow($result)) + { + $icons[$row['icons_id']]['img'] = $row['icons_url']; + $icons[$row['icons_id']]['width'] = (int) $row['icons_width']; + $icons[$row['icons_id']]['height'] = (int) $row['icons_height']; + $icons[$row['icons_id']]['display'] = (bool) $row['display_on_posting']; + } + $db->sql_freeresult($result); + + $this->acm->put('_icons', $icons); + } + + return $icons; + } + + /** + * Obtain ranks + */ + function obtain_ranks() + { + if (($ranks = $this->acm->get('_ranks')) === false) + { + global $db; + + $sql = 'SELECT * + FROM ' . RANKS_TABLE . ' + ORDER BY rank_min DESC'; + $result = $db->sql_query($sql); + + $ranks = array(); + while ($row = $db->sql_fetchrow($result)) + { + if ($row['rank_special']) + { + $ranks['special'][$row['rank_id']] = array( + 'rank_title' => $row['rank_title'], + 'rank_image' => $row['rank_image'] + ); + } + else + { + $ranks['normal'][] = array( + 'rank_title' => $row['rank_title'], + 'rank_min' => $row['rank_min'], + 'rank_image' => $row['rank_image'] + ); + } + } + $db->sql_freeresult($result); + + $this->acm->put('_ranks', $ranks); + } + + return $ranks; + } + + /** + * Obtain allowed extensions + * + * @param mixed $forum_id If false then check for private messaging, if int then check for forum id. If true, then only return extension informations. + * + * @return array allowed extensions array. + */ + function obtain_attach_extensions($forum_id) + { + if (($extensions = $this->acm->get('_extensions')) === false) + { + global $db; + + $extensions = array( + '_allowed_post' => array(), + '_allowed_pm' => array(), + ); + + // The rule is to only allow those extensions defined. ;) + $sql = 'SELECT e.extension, g.* + FROM ' . EXTENSIONS_TABLE . ' e, ' . EXTENSION_GROUPS_TABLE . ' g + WHERE e.group_id = g.group_id + AND (g.allow_group = 1 OR g.allow_in_pm = 1)'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $extension = strtolower(trim($row['extension'])); + + $extensions[$extension] = array( + 'display_cat' => (int) $row['cat_id'], + 'download_mode' => (int) $row['download_mode'], + 'upload_icon' => trim($row['upload_icon']), + 'max_filesize' => (int) $row['max_filesize'], + 'allow_group' => $row['allow_group'], + 'allow_in_pm' => $row['allow_in_pm'], + ); + + $allowed_forums = ($row['allowed_forums']) ? unserialize(trim($row['allowed_forums'])) : array(); + + // Store allowed extensions forum wise + if ($row['allow_group']) + { + $extensions['_allowed_post'][$extension] = (!sizeof($allowed_forums)) ? 0 : $allowed_forums; + } + + if ($row['allow_in_pm']) + { + $extensions['_allowed_pm'][$extension] = 0; + } + } + $db->sql_freeresult($result); + + $this->acm->put('_extensions', $extensions); + } + + // Forum post + if ($forum_id === false) + { + // We are checking for private messages, therefore we only need to get the pm extensions... + $return = array('_allowed_' => array()); + + foreach ($extensions['_allowed_pm'] as $extension => $check) + { + $return['_allowed_'][$extension] = 0; + $return[$extension] = $extensions[$extension]; + } + + $extensions = $return; + } + else if ($forum_id === true) + { + return $extensions; + } + else + { + $forum_id = (int) $forum_id; + $return = array('_allowed_' => array()); + + foreach ($extensions['_allowed_post'] as $extension => $check) + { + // Check for allowed forums + if (is_array($check)) + { + $allowed = (!in_array($forum_id, $check)) ? false : true; + } + else + { + $allowed = true; + } + + if ($allowed) + { + $return['_allowed_'][$extension] = 0; + $return[$extension] = $extensions[$extension]; + } + } + + $extensions = $return; + } + + if (!isset($extensions['_allowed_'])) + { + $extensions['_allowed_'] = array(); + } + + return $extensions; + } + + /** + * Obtain active bots + */ + function obtain_bots() + { + if (($bots = $this->acm->get('_bots')) === false) + { + global $db; + + switch ($db->sql_layer) + { + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $sql = 'SELECT user_id, bot_agent, bot_ip + FROM ' . BOTS_TABLE . ' + WHERE bot_active = 1 + ORDER BY LEN(bot_agent) DESC'; + break; + + case 'firebird': + $sql = 'SELECT user_id, bot_agent, bot_ip + FROM ' . BOTS_TABLE . ' + WHERE bot_active = 1 + ORDER BY CHAR_LENGTH(bot_agent) DESC'; + break; + + // LENGTH supported by MySQL, IBM DB2 and Oracle for sure... + default: + $sql = 'SELECT user_id, bot_agent, bot_ip + FROM ' . BOTS_TABLE . ' + WHERE bot_active = 1 + ORDER BY LENGTH(bot_agent) DESC'; + break; + } + $result = $db->sql_query($sql); + + $bots = array(); + while ($row = $db->sql_fetchrow($result)) + { + $bots[] = $row; + } + $db->sql_freeresult($result); + + $this->acm->put('_bots', $bots); + } + + return $bots; + } + + /** + * Obtain cfg file data + */ + function obtain_cfg_items($theme) + { + global $config, $phpbb_root_path; + + $parsed_items = array( + 'theme' => array(), + 'template' => array(), + 'imageset' => array() + ); + + foreach ($parsed_items as $key => $parsed_array) + { + $parsed_array = $this->acm->get('_cfg_' . $key . '_' . $theme[$key . '_path']); + + if ($parsed_array === false) + { + $parsed_array = array(); + } + + $reparse = false; + $filename = $phpbb_root_path . 'styles/' . $theme[$key . '_path'] . '/' . $key . '/' . $key . '.cfg'; + + if (!file_exists($filename)) + { + continue; + } + + if (!isset($parsed_array['filetime']) || (($config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) + { + $reparse = true; + } + + // Re-parse cfg file + if ($reparse) + { + $parsed_array = parse_cfg_file($filename); + $parsed_array['filetime'] = @filemtime($filename); + + $this->acm->put('_cfg_' . $key . '_' . $theme[$key . '_path'], $parsed_array); + } + $parsed_items[$key] = $parsed_array; + } + + return $parsed_items; + } + + /** + * Obtain disallowed usernames + */ + function obtain_disallowed_usernames() + { + if (($usernames = $this->acm->get('_disallowed_usernames')) === false) + { + global $db; + + $sql = 'SELECT disallow_username + FROM ' . DISALLOW_TABLE; + $result = $db->sql_query($sql); + + $usernames = array(); + while ($row = $db->sql_fetchrow($result)) + { + $usernames[] = str_replace('%', '.*?', preg_quote(utf8_clean_string($row['disallow_username']), '#')); + } + $db->sql_freeresult($result); + + $this->acm->put('_disallowed_usernames', $usernames); + } + + return $usernames; + } + + /** + * Obtain hooks... + */ + function obtain_hooks() + { + global $phpbb_root_path, $phpEx; + + if (($hook_files = $this->acm->get('_hooks')) === false) + { + $hook_files = array(); + + // Now search for hooks... + $dh = @opendir($phpbb_root_path . 'includes/hooks/'); + + if ($dh) + { + while (($file = readdir($dh)) !== false) + { + if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) + { + $hook_files[] = substr($file, 0, -(strlen($phpEx) + 1)); + } + } + closedir($dh); + } + + $this->acm->put('_hooks', $hook_files); + } + + return $hook_files; + } +} diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php index 5df654799a..fa121341aa 100644 --- a/phpBB/includes/class_loader.php +++ b/phpBB/includes/class_loader.php @@ -33,7 +33,7 @@ class phpbb_class_loader { private $phpbb_root_path; private $php_ext; - private $cache; + private $acm; private $cached_paths = array(); /** @@ -42,13 +42,14 @@ class phpbb_class_loader * * @param string $phpbb_root_path phpBB's root directory containing includes/ * @param string $php_ext The file extension for PHP files + * @param phpbb_acm_interface $acm An implementation of the phpBB cache interface. */ - public function __construct($phpbb_root_path, $php_ext = '.php', $cache = null) + public function __construct($phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $acm = null) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->set_cache($cache); + $this->set_acm($acm); } /** @@ -56,13 +57,13 @@ class phpbb_class_loader * the class loader will resolve paths by checking for the existance of every * directory in the class name every time. * - * @param acm $cache An implementation of the phpBB cache interface. + * @param phpbb_acm_interface $acm An implementation of the phpBB cache interface. */ - public function set_cache($cache = null) + public function set_acm(phpbb_cache_driver_interface $acm = null) { - if ($cache) + if ($acm) { - $this->cached_paths = $cache->get('class_loader'); + $this->cached_paths = $acm->get('class_loader'); if ($this->cached_paths === false) { @@ -70,7 +71,7 @@ class phpbb_class_loader } } - $this->cache = $cache; + $this->acm = $acm; } /** @@ -133,10 +134,10 @@ class phpbb_class_loader return false; } - if ($this->cache) + if ($this->acm) { $this->cached_paths[$class] = $relative_path; - $this->cache->put('class_loader', $this->cached_paths); + $this->acm->put('class_loader', $this->cached_paths); } return $path_prefix . $relative_path . $this->php_ext; diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index b33c0f4a11..961edd589f 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -61,8 +61,6 @@ if (!empty($load_extensions) && function_exists('dl')) // Include files require($phpbb_root_path . 'includes/class_loader.' . $phpEx); -require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx); -require($phpbb_root_path . 'includes/cache.' . $phpEx); require($phpbb_root_path . 'includes/template.' . $phpEx); require($phpbb_root_path . 'includes/session.' . $phpEx); require($phpbb_root_path . 'includes/auth.' . $phpEx); @@ -93,11 +91,14 @@ else define('STRIP', (get_magic_quotes_gpc()) ? true : false); } -$cache = new cache(); - -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx, $cache); +$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); +// set up caching +$acm = phpbb_cache_factory::create($acm_type)->get_acm(); +$class_loader->set_acm($acm); +$cache = new phpbb_cache_service($acm); + $request = new phpbb_request(); $user = new user(); $db = new $sql_db(); diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 1a037fe496..6486eb09d8 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -163,8 +163,6 @@ if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx)) include($phpbb_root_path . 'includes/auth.' . $phpEx); include($phpbb_root_path . 'includes/session.' . $phpEx); include($phpbb_root_path . 'includes/template.' . $phpEx); -include($phpbb_root_path . 'includes/acm/acm_file.' . $phpEx); -include($phpbb_root_path . 'includes/cache.' . $phpEx); include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); include($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); require($phpbb_root_path . 'includes/functions_install.' . $phpEx); @@ -172,6 +170,11 @@ require($phpbb_root_path . 'includes/functions_install.' . $phpEx); $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); +// set up caching +$acm = phpbb_cache_factory::create($acm_type)->get_acm(); +$class_loader->set_acm($acm); +$cache = new phpbb_cache_service($acm); + $request = new phpbb_request(); // make sure request_var uses this request instance diff --git a/phpBB/style.php b/phpBB/style.php index 3c2f94023b..418bbb9bab 100644 --- a/phpBB/style.php +++ b/phpBB/style.php @@ -57,18 +57,19 @@ if ($id) { // Include files require($phpbb_root_path . 'includes/class_loader.' . $phpEx); - require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx); - require($phpbb_root_path . 'includes/cache.' . $phpEx); require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); require($phpbb_root_path . 'includes/functions.' . $phpEx); - $cache = new cache(); - - $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx, $cache); + $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); - $request = new phpbb_request(); + // set up caching + $acm = phpbb_cache_factory::create($acm_type)->get_acm(); + $class_loader->set_acm($acm); + $cache = new phpbb_cache_service($acm); + + $request = new phpbb_request(); $db = new $sql_db(); // make sure request_var uses this request instance @@ -308,5 +309,3 @@ if ($id) } $db->sql_close(); } - -exit; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 161bd83a3d..8d4e9c4527 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -28,7 +28,7 @@ else require_once $phpbb_root_path . 'includes/constants.php'; require_once $phpbb_root_path . 'includes/class_loader.' . $phpEx; -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); +$class_loader = new phpbb_class_loader($phpbb_root_path, '.php'); $class_loader->register(); require_once 'test_framework/phpbb_test_case_helpers.php'; diff --git a/tests/cache/all_tests.php b/tests/cache/all_tests.php new file mode 100644 index 0000000000..829d496e5d --- /dev/null +++ b/tests/cache/all_tests.php @@ -0,0 +1,40 @@ +addTestSuite('phpbb_cache_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_cache_all_tests::main') +{ + phpbb_cache_all_tests::main(); +} diff --git a/tests/cache/cache_test.php b/tests/cache/cache_test.php new file mode 100644 index 0000000000..220fddfd25 --- /dev/null +++ b/tests/cache/cache_test.php @@ -0,0 +1,39 @@ +put('test_key', 'test_value'); + $acm->save(); + + $this->assertEquals( + 'test_value', + $acm->get('test_key'), + 'File ACM put and get' + ); + } +} diff --git a/tests/class_loader/cache_mock.php b/tests/class_loader/cache_mock.php index b254978fcc..73d1e64cf5 100644 --- a/tests/class_loader/cache_mock.php +++ b/tests/class_loader/cache_mock.php @@ -8,7 +8,9 @@ * */ -class phpbb_cache_mock +require '../phpBB/includes/cache/driver/interface.php'; + +class phpbb_cache_mock implements phpbb_cache_driver_interface { private $variables = array(); @@ -22,8 +24,51 @@ class phpbb_cache_mock return false; } - function put($var_name, $value) + function put($var_name, $value, $ttl = 0) { $this->variables[$var_name] = $value; } + + function load() + { + } + function unload() + { + } + function save() + { + } + function tidy() + { + } + function purge() + { + } + function destroy($var_name, $table = '') + { + } + public function _exists($var_name) + { + } + public function sql_load($query) + { + } + public function sql_save($query, &$query_result, $ttl) + { + } + public function sql_exists($query_id) + { + } + public function sql_fetchrow($query_id) + { + } + public function sql_fetchfield($query_id, $field) + { + } + public function sql_rowseek($rownum, $query_id) + { + } + public function sql_freeresult($query_id) + { + } } diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php index 3eb3c915a1..c01278f914 100644 --- a/tests/class_loader/class_loader_test.php +++ b/tests/class_loader/class_loader_test.php @@ -10,8 +10,6 @@ require_once __DIR__ . '/cache_mock.php'; -require_once __DIR__ . '/../../phpBB/includes/class_loader.php'; - class phpbb_class_loader_test extends PHPUnit_Framework_TestCase { public function setUp() @@ -63,8 +61,16 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase public function test_resolve_cached() { - $cache = new phpbb_cache_mock; - $cache->put('class_loader', array('phpbb_a_cached_name' => 'a/cached_name')); + $cacheMap = array('class_loader' => array('phpbb_a_cached_name' => 'a/cached_name')); + + $cache = $this->getMock('phpbb_cache_driver_interface', + array('get', 'put', 'load', 'unload', 'save', 'tidy', 'purge', 'destroy', '_exists', + 'sql_load', 'sql_save', 'sql_exists', 'sql_fetchrow', 'sql_fetchfield', 'sql_rowseek', 'sql_freeresult')); + $cache->expects($this->any()) + ->method('get') + ->will($this->returnCallback(function($var_name) use ($cacheMap) { + return $cacheMap[$var_name]; + })); $prefix = __DIR__ . '/'; $class_loader = new phpbb_class_loader($prefix, '.php', $cache); -- cgit v1.2.1 From 1aef7eb20ee195c7f21d6c5b78653b7c43e669ec Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 9 Jan 2011 21:09:56 +0100 Subject: [task/acm-refactor] Cleaning up left over mentions of ACM and fixing tests. PHPBB3-9983 --- phpBB/common.php | 6 +-- phpBB/download/file.php | 6 +-- phpBB/includes/cache/factory.php | 21 +++----- phpBB/includes/class_loader.php | 22 ++++---- phpBB/install/database_update.php | 6 +-- phpBB/install/index.php | 7 ++- phpBB/style.php | 6 +-- phpunit.xml.dist | 2 +- tests/cache/all_tests.php | 40 --------------- tests/cache/cache_test.php | 24 +++++---- tests/cache/tmp/.gitkeep | 0 tests/class_loader/cache_mock.php | 74 --------------------------- tests/class_loader/class_loader_test.php | 18 +++---- tests/mock/cache.php | 87 ++++++++++++++++++++++++++++++++ 14 files changed, 139 insertions(+), 180 deletions(-) delete mode 100644 tests/cache/all_tests.php create mode 100644 tests/cache/tmp/.gitkeep delete mode 100644 tests/class_loader/cache_mock.php create mode 100644 tests/mock/cache.php diff --git a/phpBB/common.php b/phpBB/common.php index fc6009eb21..7b6a407c94 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -206,9 +206,9 @@ $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); // set up caching -$acm = phpbb_cache_factory::create($acm_type)->get_acm(); -$class_loader->set_acm($acm); -$cache = new phpbb_cache_service($acm); +$cache_factory = new phpbb_cache_factory($acm_type); +$class_loader->set_cache($cache_factory->get_driver()); +$cache = $cache_factory->get_service(); // Instantiate some basic classes $request = new phpbb_request(); diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 74925fb447..a7e8b9f06c 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -54,9 +54,9 @@ if (isset($_GET['avatar'])) $class_loader->register(); // set up caching - $acm = phpbb_cache_factory::create($acm_type)->get_acm(); - $class_loader->set_acm($acm); - $cache = new phpbb_cache_service($acm); + $cache_factory = new phpbb_cache_factory($acm_type); + $class_loader->set_cache($cache_factory->get_driver()); + $cache = $cache_factory->get_service(); $db = new $sql_db(); diff --git a/phpBB/includes/cache/factory.php b/phpBB/includes/cache/factory.php index cc88780bf2..f38e19cbe6 100644 --- a/phpBB/includes/cache/factory.php +++ b/phpBB/includes/cache/factory.php @@ -22,31 +22,22 @@ if (!defined('IN_PHPBB')) class phpbb_cache_factory { private $acm_type; - + public function __construct($acm_type) { $this->acm_type = $acm_type; } - - public function get_acm() + + public function get_driver() { $class_name = 'phpbb_cache_driver_' . $this->acm_type; return new $class_name(); } - + public function get_service() { - $acm = $this->get_acm(); - $service = new phpbb_cache_service($acm); + $driver = $this->get_driver(); + $service = new phpbb_cache_service($driver); return $service; } - - /** - * for convenience to allow: - * $cache = phpbb_cache_factory::create('file')->get_service(); - */ - public static function create($acm_type) - { - return new self($acm_type); - } } diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php index fa121341aa..a28d745983 100644 --- a/phpBB/includes/class_loader.php +++ b/phpBB/includes/class_loader.php @@ -33,7 +33,7 @@ class phpbb_class_loader { private $phpbb_root_path; private $php_ext; - private $acm; + private $cache; private $cached_paths = array(); /** @@ -42,14 +42,14 @@ class phpbb_class_loader * * @param string $phpbb_root_path phpBB's root directory containing includes/ * @param string $php_ext The file extension for PHP files - * @param phpbb_acm_interface $acm An implementation of the phpBB cache interface. + * @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface. */ - public function __construct($phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $acm = null) + public function __construct($phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->set_acm($acm); + $this->set_cache($cache); } /** @@ -57,13 +57,13 @@ class phpbb_class_loader * the class loader will resolve paths by checking for the existance of every * directory in the class name every time. * - * @param phpbb_acm_interface $acm An implementation of the phpBB cache interface. + * @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface. */ - public function set_acm(phpbb_cache_driver_interface $acm = null) + public function set_cache(phpbb_cache_driver_interface $cache = null) { - if ($acm) + if ($cache) { - $this->cached_paths = $acm->get('class_loader'); + $this->cached_paths = $cache->get('class_loader'); if ($this->cached_paths === false) { @@ -71,7 +71,7 @@ class phpbb_class_loader } } - $this->acm = $acm; + $this->cache = $cache; } /** @@ -134,10 +134,10 @@ class phpbb_class_loader return false; } - if ($this->acm) + if ($this->cache) { $this->cached_paths[$class] = $relative_path; - $this->acm->put('class_loader', $this->cached_paths); + $this->cache->put('class_loader', $this->cached_paths); } return $path_prefix . $relative_path . $this->php_ext; diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 961edd589f..f73f7472f0 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -95,9 +95,9 @@ $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); // set up caching -$acm = phpbb_cache_factory::create($acm_type)->get_acm(); -$class_loader->set_acm($acm); -$cache = new phpbb_cache_service($acm); +$cache_factory = new phpbb_cache_factory($acm_type); +$class_loader->set_cache($cache_factory->get_driver()); +$cache = $cache_factory->get_service(); $request = new phpbb_request(); $user = new user(); diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 6486eb09d8..653268ba68 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -171,9 +171,9 @@ $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); $class_loader->register(); // set up caching -$acm = phpbb_cache_factory::create($acm_type)->get_acm(); -$class_loader->set_acm($acm); -$cache = new phpbb_cache_service($acm); +$cache_factory = new phpbb_cache_factory('file'); +$class_loader->set_cache($cache_factory->get_driver()); +$cache = $cache_factory->get_service(); $request = new phpbb_request(); @@ -262,7 +262,6 @@ set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handle $user = new user(); $auth = new auth(); -$cache = new cache(); $template = new template(); // Add own hook handler, if present. :o diff --git a/phpBB/style.php b/phpBB/style.php index 418bbb9bab..cff91a2312 100644 --- a/phpBB/style.php +++ b/phpBB/style.php @@ -65,9 +65,9 @@ if ($id) $class_loader->register(); // set up caching - $acm = phpbb_cache_factory::create($acm_type)->get_acm(); - $class_loader->set_acm($acm); - $cache = new phpbb_cache_service($acm); + $cache_factory = new phpbb_cache_factory($acm_type); + $class_loader->set_cache($cache_factory->get_driver()); + $cache = $cache_factory->get_service(); $request = new phpbb_request(); $db = new $sql_db(); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d1d8adbdd5..4209c61947 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,7 +16,7 @@ ./tests/ - + ./tests/ diff --git a/tests/cache/all_tests.php b/tests/cache/all_tests.php deleted file mode 100644 index 829d496e5d..0000000000 --- a/tests/cache/all_tests.php +++ /dev/null @@ -1,40 +0,0 @@ -addTestSuite('phpbb_cache_test'); - - return $suite; - } -} - -if (PHPUnit_MAIN_METHOD == 'phpbb_cache_all_tests::main') -{ - phpbb_cache_all_tests::main(); -} diff --git a/tests/cache/cache_test.php b/tests/cache/cache_test.php index 220fddfd25..463095f129 100644 --- a/tests/cache/cache_test.php +++ b/tests/cache/cache_test.php @@ -2,37 +2,39 @@ /** * * @package testing -* @version $Id$ * @copyright (c) 2010 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ -require_once 'test_framework/framework.php'; +require_once __DIR__ . '/../../phpBB/includes/functions.php'; class phpbb_cache_test extends phpbb_test_case { protected function tearDown() { - $iterator = new DirectoryIterator('cache/tmp'); + $iterator = new DirectoryIterator(__DIR__ . '/tmp'); foreach ($iterator as $file) { - if (is_file('cache/tmp/' . $file)) + if (is_file(__DIR__ . '/tmp/' . $file) && $file != '.gitkeep') { - unlink('cache/tmp/' . $file); + unlink(__DIR__ . '/tmp/' . $file); } } } - public function test_acm_file() + public function test_cache_driver_file() { - $acm = new phpbb_cache_driver_file('cache/tmp/'); - $acm->put('test_key', 'test_value'); - $acm->save(); - + global $phpEx; + $phpEx = 'txt'; // do not store files as .php + + $driver = new phpbb_cache_driver_file(__DIR__ . '/tmp/'); + $driver->put('test_key', 'test_value'); + $driver->save(); + $this->assertEquals( 'test_value', - $acm->get('test_key'), + $driver->get('test_key'), 'File ACM put and get' ); } diff --git a/tests/cache/tmp/.gitkeep b/tests/cache/tmp/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/class_loader/cache_mock.php b/tests/class_loader/cache_mock.php deleted file mode 100644 index 73d1e64cf5..0000000000 --- a/tests/class_loader/cache_mock.php +++ /dev/null @@ -1,74 +0,0 @@ -variables[$var_name])) - { - return $this->variables[$var_name]; - } - - return false; - } - - function put($var_name, $value, $ttl = 0) - { - $this->variables[$var_name] = $value; - } - - function load() - { - } - function unload() - { - } - function save() - { - } - function tidy() - { - } - function purge() - { - } - function destroy($var_name, $table = '') - { - } - public function _exists($var_name) - { - } - public function sql_load($query) - { - } - public function sql_save($query, &$query_result, $ttl) - { - } - public function sql_exists($query_id) - { - } - public function sql_fetchrow($query_id) - { - } - public function sql_fetchfield($query_id, $field) - { - } - public function sql_rowseek($rownum, $query_id) - { - } - public function sql_freeresult($query_id) - { - } -} diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php index c01278f914..cc6862dc70 100644 --- a/tests/class_loader/class_loader_test.php +++ b/tests/class_loader/class_loader_test.php @@ -2,13 +2,12 @@ /** * * @package testing -* @version $Id$ -* @copyright (c) 2008 phpBB Group +* @copyright (c) 2011 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ -require_once __DIR__ . '/cache_mock.php'; +require_once __DIR__ . '/../mock/cache.php'; class phpbb_class_loader_test extends PHPUnit_Framework_TestCase { @@ -62,15 +61,7 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase public function test_resolve_cached() { $cacheMap = array('class_loader' => array('phpbb_a_cached_name' => 'a/cached_name')); - - $cache = $this->getMock('phpbb_cache_driver_interface', - array('get', 'put', 'load', 'unload', 'save', 'tidy', 'purge', 'destroy', '_exists', - 'sql_load', 'sql_save', 'sql_exists', 'sql_fetchrow', 'sql_fetchfield', 'sql_rowseek', 'sql_freeresult')); - $cache->expects($this->any()) - ->method('get') - ->will($this->returnCallback(function($var_name) use ($cacheMap) { - return $cacheMap[$var_name]; - })); + $cache = new phpbb_mock_cache($cacheMap); $prefix = __DIR__ . '/'; $class_loader = new phpbb_class_loader($prefix, '.php', $cache); @@ -88,5 +79,8 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase $class_loader->resolve_path('phpbb_a_cached_name'), 'Class in a directory' ); + + $cacheMap['class_loader']['phpbb_dir_class_name'] = 'dir/class_name'; + $cache->check($this, $cacheMap); } } diff --git a/tests/mock/cache.php b/tests/mock/cache.php new file mode 100644 index 0000000000..3bfb31f1be --- /dev/null +++ b/tests/mock/cache.php @@ -0,0 +1,87 @@ +data = $data; + } + + public function get($var_name) + { + if (isset($this->data[$var_name])) + { + return $this->data[$var_name]; + } + + return false; + } + + public function put($var_name, $var, $ttl = 0) + { + $this->data[$var_name] = $var; + } + + public function checkVar(PHPUnit_Framework_Assert $test, $var_name, $data) + { + $test->assertTrue(isset($this->data[$var_name])); + $test->assertEquals($data, $this->data[$var_name]); + } + + public function check(PHPUnit_Framework_Assert $test, $data) + { + $test->assertEquals($data, $this->data); + } + + function load() + { + } + function unload() + { + } + function save() + { + } + function tidy() + { + } + function purge() + { + } + function destroy($var_name, $table = '') + { + } + public function _exists($var_name) + { + } + public function sql_load($query) + { + } + public function sql_save($query, &$query_result, $ttl) + { + } + public function sql_exists($query_id) + { + } + public function sql_fetchrow($query_id) + { + } + public function sql_fetchfield($query_id, $field) + { + } + public function sql_rowseek($rownum, $query_id) + { + } + public function sql_freeresult($query_id) + { + } +} -- cgit v1.2.1