From 14f1e581faa3b66e7689c55c1e9c0485c0872b1e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 9 Jun 2011 05:13:26 +0200 Subject: [feature/extension-manager] Extension Manager & Finder Extensions RFC: http://area51.phpbb.com/phpBB/viewtopic.php?f=84&t=41499 Ticket: http://tracker.phpbb.com/browse/PHPBB3-10323 PHPBB3-10323 --- phpBB/common.php | 2 +- phpBB/develop/create_schema_files.php | 11 ++ phpBB/download/file.php | 2 +- phpBB/includes/class_loader.php | 28 ++- phpBB/includes/constants.php | 1 + phpBB/includes/extension/base.php | 35 ++++ phpBB/includes/extension/finder.php | 246 ++++++++++++++++++++++++ phpBB/includes/extension/interface.php | 27 +++ phpBB/includes/extension/manager.php | 301 ++++++++++++++++++++++++++++++ phpBB/install/database_update.php | 18 +- phpBB/install/index.php | 2 +- phpBB/install/schemas/firebird_schema.sql | 9 + phpBB/install/schemas/mssql_schema.sql | 16 ++ phpBB/install/schemas/mysql_40_schema.sql | 9 + phpBB/install/schemas/mysql_41_schema.sql | 9 + phpBB/install/schemas/oracle_schema.sql | 13 ++ phpBB/install/schemas/postgres_schema.sql | 11 ++ phpBB/install/schemas/sqlite_schema.sql | 9 + 18 files changed, 737 insertions(+), 12 deletions(-) create mode 100644 phpBB/includes/extension/base.php create mode 100644 phpBB/includes/extension/finder.php create mode 100644 phpBB/includes/extension/interface.php create mode 100644 phpBB/includes/extension/manager.php (limited to 'phpBB') diff --git a/phpBB/common.php b/phpBB/common.php index 524c05ae70..7ff06e68d7 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -96,7 +96,7 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); +$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); $class_loader->register(); // set up caching diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 2057d292b7..9f2015f38e 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1031,6 +1031,17 @@ function get_schema_struct() ), ); + $schema_data['phpbb_ext'] = array( + 'COLUMNS' => array( + 'ext_name' => array('VCHAR', ''), + 'ext_active' => array('BOOL', 0), + ), + 'KEYS' => array( + 'ext_name' => array('UNIQUE', 'ext_name'), + 'ext_active' => array('INDEX', 'ext_active'), + ), + ); + $schema_data['phpbb_extensions'] = array( 'COLUMNS' => array( 'extension_id' => array('UINT', NULL, 'auto_increment'), diff --git a/phpBB/download/file.php b/phpBB/download/file.php index ec15d36e08..956af75c81 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -46,7 +46,7 @@ if (isset($_GET['avatar'])) require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); - $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); + $class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); $class_loader->register(); // set up caching diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php index a28d745983..bcf1ba1650 100644 --- a/phpBB/includes/class_loader.php +++ b/phpBB/includes/class_loader.php @@ -31,22 +31,25 @@ if (!defined('IN_PHPBB')) */ class phpbb_class_loader { - private $phpbb_root_path; + private $core_path; + private $ext_path; private $php_ext; private $cache; private $cached_paths = array(); /** * Creates a new phpbb_class_loader, which loads files with the given - * file extension from the given phpbb root path. + * file extension from the given core or extension path. * - * @param string $phpbb_root_path phpBB's root directory containing includes/ - * @param string $php_ext The file extension for PHP files + * @param string $core_path phpBB's include directory for core files + * @param string $ext_path phpBB's extension directory + * @param string $php_ext The file extension for PHP files * @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 $cache = null) + public function __construct($core_path, $ext_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) { - $this->phpbb_root_path = $phpbb_root_path; + $this->core_path = $core_path; + $this->ext_path = $ext_path; $this->php_ext = $php_ext; $this->set_cache($cache); @@ -100,7 +103,16 @@ class phpbb_class_loader */ public function resolve_path($class) { - $path_prefix = $this->phpbb_root_path . 'includes/'; + if (substr($class, 6, 4) === 'ext_') + { + $path_prefix = $this->ext_path; + $prefix_length = 10; + } + else + { + $path_prefix = $this->core_path; + $prefix_length = 6; + } if (isset($this->cached_paths[$class])) { @@ -112,7 +124,7 @@ class phpbb_class_loader return false; } - $parts = explode('_', substr($class, 6)); + $parts = explode('_', substr($class, $prefix_length)); $dirs = ''; diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 8ef1a4655d..d5b398b7bf 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -226,6 +226,7 @@ define('CONFIG_TABLE', $table_prefix . 'config'); define('CONFIRM_TABLE', $table_prefix . 'confirm'); define('DISALLOW_TABLE', $table_prefix . 'disallow'); define('DRAFTS_TABLE', $table_prefix . 'drafts'); +define('EXT_TABLE', $table_prefix . 'ext'); define('EXTENSIONS_TABLE', $table_prefix . 'extensions'); define('EXTENSION_GROUPS_TABLE', $table_prefix . 'extension_groups'); define('FORUMS_TABLE', $table_prefix . 'forums'); diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php new file mode 100644 index 0000000000..0e6c89491d --- /dev/null +++ b/phpBB/includes/extension/base.php @@ -0,0 +1,35 @@ +extension_manager = $extension_manager; + $this->phpbb_root_path = $phpbb_root_path; + $this->cache = $cache; + $this->phpEx = $phpEx; + + $this->query = array( + 'default_path' => false, + 'default_suffix' => false, + 'default_directory' => false, + 'suffix' => false, + 'directory' => false, + ); + + $this->cached_queries = ($this->cache) ? $this->cache->get('_extension_finder') : false; + } + + /** + * Sets a default path to be searched in addition to extensions + * + * @param string $default_path The path relative to / + * @return phpbb_extension_finder This object for chaining calls + */ + public function default_path($default_path) + { + $this->query['default_path'] = $default_path; + return $this; + } + + /** + * Sets a suffix all files found in extensions must match + * + * Automatically sets the default_suffix if its value does not differ from + * the current suffix. + * + * @param string $default_path A filename suffix + * @return phpbb_extension_finder This object for chaining calls + */ + public function suffix($suffix) + { + if ($this->query['default_suffix'] === $this->query['suffix']) + { + $this->query['default_suffix'] = $suffix; + } + + $this->query['suffix'] = $suffix; + return $this; + } + + /** + * Sets a suffix all files found in the default path must match + * + * @param string $default_suffix A filename suffix + * @return phpbb_extension_finder This object for chaining calls + */ + public function default_suffix($default_suffix) + { + $this->query['default_suffix'] = $default_suffix; + return $this; + } + + /** + * Sets a directory all files found in extensions must be contained in + * + * Automatically sets the default_directory if its value does not differ from + * the current directory. + * + * @param string $directory + * @return phpbb_extension_finder This object for chaining calls + */ + public function directory($directory) + { + if (strlen($directory) > 1 && $directory[strlen($directory) - 1] === '/') + { + $directory = substr($directory, 0, -1); + } + + if ($this->query['default_directory'] === $this->query['directory']) + { + $this->query['default_directory'] = $directory; + } + + $this->query['directory'] = $directory; + return $this; + } + + /** + * Sets a directory all files found in the default path must be contained in + * + * @param string $default_directory + * @return phpbb_extension_finder This object for chaining calls + */ + public function default_directory($default_directory) + { + if (strlen($default_directory) > 1 && $default_directory[strlen($default_directory) - 1] === '/') + { + $default_directory = substr($default_directory, 0, -1); + } + + $this->query['default_directory'] = $default_directory; + return $this; + } + + /** + * Finds auto loadable php classes matching the configured options. + * + * The php file extension is automatically added to suffixes. + * + * @param bool $cache Whether the result should be cached + * @return array An array of found class names + */ + public function get_classes($cache = true) + { + $this->query['suffix'] .= $this->phpEx; + $this->query['default_suffix'] .= $this->phpEx; + + $files = $this->get_files($cache); + + $classes = array(); + foreach ($files as $file) + { + $file = preg_replace('#^includes/#', '', $file); + + $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->phpEx))); + } + return $classes; + } + + /** + * Finds all files matching the configured options. + * + * @param bool $cache Whether the result should be cached + * @return array An array of found class names + */ + public function get_files($cache = true) + { + $query = md5(serialize($this->query)); + + if ($cache && isset($this->cached_queries[$query])) + { + return $this->cached_queries[$query]; + } + + $files = array(); + + $extensions = $this->extension_manager->all_enabled(); + + if ($this->query['default_path']) + { + $extensions['/'] = $this->phpbb_root_path . $this->query['default_path']; + } + + foreach ($extensions as $name => $path) + { + if (!file_exists($path)) + { + continue; + } + + if ($name === '/') + { + $prefix = $this->query['default_path']; + $name = ''; + $suffix = $this->query['default_suffix']; + $directory = $this->query['default_directory']; + } + else + { + $prefix = 'ext/'; + $name .= '/'; + $suffix = $this->query['suffix']; + $directory = $this->query['directory']; + } + + // match only first directory if leading slash is given + $directory_pattern = ($directory && $directory[0] === '/') ? '#^' : '#' . DIRECTORY_SEPARATOR; + $directory_pattern .= preg_quote($directory . DIRECTORY_SEPARATOR, '#') . '#'; + + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); + foreach ($iterator as $file_info) + { + if (!$file_info->isDir()) + { + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + + if ((!$suffix || substr($relative_path, -strlen($suffix)) == $suffix) && + (!$directory || preg_match($directory_pattern, DIRECTORY_SEPARATOR . $relative_path))) + { + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $prefix . $name . $relative_path); + } + } + } + } + + if ($cache && $this->cache) + { + $this->cached_queries[$query] = $files; + $this->cache->put('_extension_finder', $this->cached_queries); + } + + return $files; + } +} diff --git a/phpBB/includes/extension/interface.php b/phpBB/includes/extension/interface.php new file mode 100644 index 0000000000..40a5a066a3 --- /dev/null +++ b/phpBB/includes/extension/interface.php @@ -0,0 +1,27 @@ +phpbb_root_path = $phpbb_root_path; + $this->db = $db; + $this->cache = $cache; + $this->phpEx = $phpEx; + $this->extension_table = $extension_table; + + if (false === ($this->extensions = $this->cache->get('_extensions'))) + { + $this->load_extensions(); + } + } + + /** + * Loads all extension information from the database + * + * @return null + */ + protected function load_extensions() + { + $sql = 'SELECT * + FROM ' . $this->extension_table; + + $result = $this->db->sql_query($sql); + $extensions = $this->db->sql_fetchrowset($result); + + $this->extensions = array(); + foreach ($extensions as $extension) + { + $extension['ext_path'] = $this->get_extension_path($extension['ext_name']); + $this->extensions[$extension['ext_name']] = $extension; + } + + ksort($this->extensions); + $this->cache->put('_extensions', $this->extensions); + } + + /** + * Generates the path to an extension + * + * @param string $name The name of the extension + * @return string Path to an extension + */ + public function get_extension_path($name) + { + return $this->phpbb_root_path . 'ext/' . basename($name) . '/'; + } + + /** + * Instantiates the extension meta class for the given name. + * + * @param string $name The extension name + * @return phpbb_extension_interface Instance of the extension meta class or + * phpbb_extension_base if the class does not exist + */ + public function get_extension($name) + { + $extension_class_name = 'phpbb_ext_' . $name; + + if (class_exists($extension_class_name)) + { + return new $extension_class_name; + } + else + { + return new phpbb_extension_base; + } + } + + /** + * Enables an extension + * + * Calls the enable method on the extension's meta class to allow it to + * make database changes and execute other initialisation code. + * + * @param string $name The extension's name + * @return null + */ + public function enable($name) + { + // ignore extensions that are already enabled + if (isset($this->extensions[$name]) && $this->extensions[$name]['ext_active']) + { + return; + } + + $extension = $this->get_extension($name); + $extension->enable(); + + $extension_data = array( + 'ext_name' => $name, + 'ext_active' => true, + ); + + $this->extensions[$name] = $extension_data; + $this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']); + ksort($this->extensions); + + $sql = 'UPDATE ' . $this->extension_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " + WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + if (!$this->db->sql_affectedrows()) + { + $sql = 'INSERT INTO ' . $this->extension_table . ' + ' . $this->db->sql_build_array('INSERT', $extension_data); + $this->db->sql_query($sql); + } + } + + /** + * Disables an extension + * + * Calls the disable method on the extension's meta class to allow it to + * process the event. + * + * @param string $name The extension's name + * @return null + */ + public function disable($name) + { + // ignore extensions that are already disabled + if (!isset($this->extensions[$name]) || !$this->extensions[$name]['ext_active']) + { + return; + } + + $extension = $this->get_extension($name); + $extension->disable(); + + $extension_data = array( + 'ext_active' => false, + ); + $this->extensions[$name]['ext_active'] = false; + ksort($this->extensions); + + $sql = 'UPDATE ' . $this->extension_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " + WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + } + + /** + * Purge an extension + * + * Disables the extension first if active, and then calls purge on the + * extension's meta class to delete the extension's database content. + * + * @param string $name The extension's name + * @return null + */ + public function purge($name) + { + // ignore extensions that do not exist + if (!isset($this->extensions[$name])) + { + return; + } + + // disable first if necessary + if ($this->extensions[$name]['ext_active']) + { + $this->disable($name); + } + + $extension = $this->get_extension($name); + $extension->purge(); + + unset($this->extensions[$name]); + + $sql = 'DELETE FROM ' . $this->extension_table . " + WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + } + + /** + * Retrieves a list of all available extensions on the filesystem + * + * @return array An array with extension names as keys and paths to the + * extension as values + */ + public function all_available() + { + $available = array(); + + $iterator = new DirectoryIterator($this->phpbb_root_path . 'ext/'); + foreach ($iterator as $file_info) + { + $path = $this->phpbb_root_path . 'ext/' . $file_info->getBasename() . '/'; + if (!$file_info->isDot() && $file_info->isDir() && file_exists($path)) + { + $available[$file_info->getBasename()] = $path; + } + } + ksort($available); + return $available; + } + + /** + * Retrieves all configured extensions. + * + * All enabled and disabled extensions are considered configured. A purged + * extension that is no longer in the database is not configured. + * + * @return array An array with extension names as keys and and the + * database stored extension information as values + */ + public function all_configured() + { + return $this->extensions; + } + + /** + * Retrieves all enabled extensions. + * + * @return array An array with extension names as keys and and the + * database stored extension information as values + */ + public function all_enabled() + { + $enabled = array(); + foreach ($this->extensions as $name => $data) + { + if ($data['ext_active']) + { + $enabled[$name] = $data['ext_path']; + } + } + return $enabled; + } + + /** + * Retrieves all disabled extensions. + * + * @return array An array with extension names as keys and and the + * database stored extension information as values + */ + public function all_disabled() + { + $disabled = array(); + foreach ($this->extensions as $name => $data) + { + if (!$data['ext_active']) + { + $disabled[$name] = $data['ext_path']; + } + } + return $disabled; + } + + /** + * Instantiates a phpbb_extension_finder. + * + * @return phpbb_extension_finder An extension finder instance + */ + public function get_finder() + { + return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx); + } +} diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 18741191d8..b2419df3c9 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -104,8 +104,12 @@ if (!defined('LOGIN_ATTEMPT_TABLE')) { define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts'); } +if (!defined('EXT_TABLE')) +{ + define('EXT_TABLE', $table_prefix . 'ext'); +} -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); +$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); $class_loader->register(); // set up caching @@ -1048,6 +1052,18 @@ function database_update_info() // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( + 'add_tables' => array( + EXT_TABLE => array( + 'COLUMNS' => array( + 'ext_name' => array('VCHAR', ''), + 'ext_active' => array('BOOL', 0), + ), + 'KEYS' => array( + 'ext_name' => array('UNIQUE', 'ext_name'), + 'ext_active' => array('INDEX', 'ext_active'), + ), + ), + ), 'add_columns' => array( GROUPS_TABLE => array( 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), diff --git a/phpBB/install/index.php b/phpBB/install/index.php index a4ff93e701..fbe8ae63a7 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -82,7 +82,7 @@ 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); -$class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); +$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); $class_loader->register(); // set up caching diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 67e5547bb6..5f5aaaaa45 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -281,6 +281,15 @@ BEGIN END;; +# Table: 'phpbb_ext' +CREATE TABLE phpbb_ext ( + ext_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + ext_active INTEGER DEFAULT 0 NOT NULL +);; + +CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext(ext_name);; +CREATE INDEX phpbb_ext_ext_active ON phpbb_ext(ext_active);; + # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( extension_id INTEGER NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index fe69670ded..052531993f 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -358,6 +358,22 @@ CREATE INDEX [save_time] ON [phpbb_drafts]([save_time]) ON [PRIMARY] GO +/* + Table: 'phpbb_ext' +*/ +CREATE TABLE [phpbb_ext] ( + [ext_name] [varchar] (255) DEFAULT ('') NOT NULL , + [ext_active] [int] DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +CREATE UNIQUE INDEX [ext_name] ON [phpbb_ext]([ext_name]) ON [PRIMARY] +GO + +CREATE INDEX [ext_active] ON [phpbb_ext]([ext_active]) ON [PRIMARY] +GO + + /* Table: 'phpbb_extensions' */ diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index da6ce35be3..03402d7ed1 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -191,6 +191,15 @@ CREATE TABLE phpbb_drafts ( ); +# Table: 'phpbb_ext' +CREATE TABLE phpbb_ext ( + ext_name varbinary(255) DEFAULT '' NOT NULL, + ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE ext_name (ext_name), + KEY ext_active (ext_active) +); + + # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( extension_id mediumint(8) UNSIGNED NOT NULL auto_increment, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index cdbe377178..8876b52a30 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -191,6 +191,15 @@ CREATE TABLE phpbb_drafts ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_ext' +CREATE TABLE phpbb_ext ( + ext_name varchar(255) DEFAULT '' NOT NULL, + ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE ext_name (ext_name), + KEY ext_active (ext_active) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( extension_id mediumint(8) UNSIGNED NOT NULL auto_increment, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 8797457e87..df31f6d3d6 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -407,6 +407,19 @@ END; / +/* + Table: 'phpbb_ext' +*/ +CREATE TABLE phpbb_ext ( + ext_name varchar2(255) DEFAULT '' , + ext_active number(1) DEFAULT '0' NOT NULL, + CONSTRAINT u_phpbb_ext_name UNIQUE (ext_name) +) +/ + +CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active) +/ + /* Table: 'phpbb_extensions' */ diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 3c79aacd6b..dbe891a3ac 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -312,6 +312,17 @@ CREATE TABLE phpbb_drafts ( CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); +/* + Table: 'phpbb_ext' +*/ +CREATE TABLE phpbb_ext ( + ext_name varchar(255) DEFAULT '' NOT NULL, + ext_active INT2 DEFAULT '0' NOT NULL CHECK (ext_active >= 0) +); + +CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); +CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active); + /* Table: 'phpbb_extensions' */ diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index e0631160fd..3c1d476daa 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -186,6 +186,15 @@ CREATE TABLE phpbb_drafts ( CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); +# Table: 'phpbb_ext' +CREATE TABLE phpbb_ext ( + ext_name varchar(255) NOT NULL DEFAULT '', + ext_active INTEGER UNSIGNED NOT NULL DEFAULT '0' +); + +CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); +CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active); + # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( extension_id INTEGER PRIMARY KEY NOT NULL , -- cgit v1.2.1 From fabde989a2676c762f58e17b06772c9a3ba2f85e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 13 Jul 2011 08:22:27 -0400 Subject: [feature/extension-manager] Porting cron tasks over to the extension finder PHPBB3-10323 --- phpBB/includes/cron/manager.php | 125 +++++++++------------------------------- 1 file changed, 26 insertions(+), 99 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php index 31be1a69cb..ae48e233e0 100644 --- a/phpBB/includes/cron/manager.php +++ b/phpBB/includes/cron/manager.php @@ -33,126 +33,53 @@ class phpbb_cron_manager protected $tasks = array(); /** - * Path to the root of directory tree with tasks. - * For bundled phpBB tasks, this is the path to includes/cron/tasks - * under phpBB root. - * @var string + * An extension manager to search for cron tasks in extensions. + * @var phpbb_extension_manager */ - protected $task_path; - - /** - * PHP file extension - * @var string - */ - protected $phpEx; - - /** - * Cache driver - * @var phpbb_cache_driver_interface - */ - protected $cache; + protected $extension_manager; /** * Constructor. Loads all available tasks. * - * Tasks will be looked up in directory tree rooted at $task_path. - * Task classes will be autoloaded and must be named according to - * autoloading naming conventions. To load cron tasks shipped with - * phpbb, pass $phpbb_root_path . 'includes/cron/task' as $task_path. + * Tasks will be looked up in the core task directory located in + * includes/cron/task/core/ and in extensions. Task classes will be + * autoloaded and must be named according to autoloading naming conventions. * - * If $cache is given, names of found cron tasks will be cached in it - * for one hour. Note that the cron task names are stored without - * namespacing; if two different phbb_cron_manager instances are - * constructed with different $task_path arguments but the same $cache, - * the second instance will use task names found by the first instance. + * Tasks in extensions must be located in a directory called cron or a subdir + * of a directory called cron. The class and filename must end in a _task + * suffix. * - * @param string $task_path Directory containing cron tasks - * @param string $phpEx PHP file extension - * @param phpbb_cache_driver_interface $cache Cache for task names (optional) - * @return void + * @param phpbb_extension_manager $extension_manager phpBB extension manager */ - public function __construct($task_path, $phpEx, phpbb_cache_driver_interface $cache = null) + public function __construct(phpbb_extension_manager $extension_manager) { - if (DIRECTORY_SEPARATOR != '/') - { - // Need this on some platforms since the code elsewhere uses / - // to separate directory components, but PHP iterators return - // paths with platform-specific directory separators. - $task_path = str_replace('/', DIRECTORY_SEPARATOR, $task_path); - } - - $this->task_path = $task_path; - $this->phpEx = $phpEx; - $this->cache = $cache; + $this->extension_manager = $extension_manager; $task_names = $this->find_cron_task_names(); $this->load_tasks($task_names); } /** - * Finds cron task names. + * Finds cron task names using the extension manager. * - * A cron task file must follow the naming convention: - * includes/cron/task/$mod/$name.php. - * $mod is core for tasks that are part of phpbb. - * Modifications should use their name as $mod. - * $name is the name of the cron task. - * Cron task is expected to be a class named phpbb_cron_task_${mod}_${name}. + * All PHP files in includes/cron/task/core/ are considered tasks. Tasks + * in extensions have to be located in a directory called cron or a subdir + * of a directory called cron. The class and filename must end in a _task + * suffix. * * @return array List of task names */ public function find_cron_task_names() { - if ($this->cache) - { - $task_names = $this->cache->get('_cron_tasks'); - - if ($task_names !== false) - { - return $task_names; - } - } - - $task_names = array(); - $ext = '.' . $this->phpEx; - $ext_length = strlen($ext); - - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->task_path)); - - foreach ($iterator as $fileinfo) - { - $file = preg_replace('#^' . preg_quote($this->task_path, '#') . '#', '', $fileinfo->getPathname()); - - // skip directories and files direclty in the task root path - if ($fileinfo->isFile() && strpos($file, DIRECTORY_SEPARATOR) !== false) - { - $task_name = str_replace(DIRECTORY_SEPARATOR, '_', substr($file, 0, -$ext_length)); - if (substr($file, -$ext_length) == $ext && $this->is_valid_name($task_name)) - { - $task_names[] = 'phpbb_cron_task_' . $task_name; - } - } - } - - if ($this->cache) - { - $this->cache->put('_cron_tasks', $task_names, 3600); - } - - return $task_names; - } - - /** - * Checks whether $name is a valid identifier, and - * therefore part of valid cron task class name. - * - * @param string $name Name to check - * - * @return bool - */ - public function is_valid_name($name) - { - return (bool) preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $name); + $finder = $this->extension_manager->get_finder(); + + return $finder + ->suffix('_task') + ->directory('/cron') + ->default_path('includes/cron/task/core/') + ->default_suffix('') + ->default_directory('') + ->get_classes(); } /** -- cgit v1.2.1 From fb943d4d6b39cea9825aab78e397eefe26cf7bdf Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 15 Aug 2011 19:34:30 -0400 Subject: [feature/extension-manager] Load the extension manager on all pages PHPBB3-10323 --- phpBB/common.php | 5 ++++- phpBB/download/file.php | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/common.php b/phpBB/common.php index 7ff06e68d7..cc33b29a09 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -124,6 +124,9 @@ $config = new phpbb_config_db($db, $cache->get_driver(), CONFIG_TABLE); set_config(null, null, null, $config); set_config_count(null, null, null, $config); +// load extensions +$phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_root_path, ".$phpEx", $cache->get_driver()); + $template_locator = new phpbb_template_locator(); $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator); @@ -138,5 +141,5 @@ foreach ($cache->obtain_hooks() as $hook) if (!$config['use_system_cron']) { - $cron = new phpbb_cron_manager($phpbb_root_path . 'includes/cron/task', $phpEx, $cache->get_driver()); + $cron = new phpbb_cron_manager($phpbb_extension_manager, $cache->get_driver()); } diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 956af75c81..e13524f922 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -73,6 +73,9 @@ if (isset($_GET['avatar'])) set_config(null, null, null, $config); set_config_count(null, null, null, $config); + // load extensions + $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_root_path, ".$phpEx", $cache->get_driver()); + $filename = request_var('avatar', ''); $avatar_group = false; $exit = false; -- cgit v1.2.1 From dcc5ca53778184f0719b9ac0c221688ad03bd57e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 15 Aug 2011 20:00:47 -0400 Subject: [feature/extension-manager] Make search backends loadable from extensions Search backends are now required to be autoloadable. The database updater to 3.1 tries to guess the class name as phpbb_search_ which works for the default backends we ship. PHPBB3-10323 --- phpBB/includes/acp/acp_search.php | 29 +-- phpBB/includes/functions_posting.php | 9 +- phpBB/includes/search/base.php | 318 ++++++++++++++++++++++++++++++ phpBB/includes/search/fulltext_mysql.php | 14 +- phpBB/includes/search/fulltext_native.php | 17 +- phpBB/includes/search/search.php | 318 ------------------------------ phpBB/install/database_update.php | 4 + phpBB/install/schemas/schema_data.sql | 2 +- phpBB/search.php | 11 +- 9 files changed, 360 insertions(+), 362 deletions(-) create mode 100644 phpBB/includes/search/base.php delete mode 100644 phpBB/includes/search/search.php (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php index a3061ae2da..a6377f6b49 100644 --- a/phpBB/includes/acp/acp_search.php +++ b/phpBB/includes/acp/acp_search.php @@ -77,7 +77,8 @@ class acp_search continue; } - $name = ucfirst(strtolower(str_replace('_', ' ', $type))); + $name = $search->get_name(); + $selected = ($config['search_type'] == $type) ? ' selected="selected"' : ''; $search_options .= ''; @@ -275,7 +276,7 @@ class acp_search { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } - $name = ucfirst(strtolower(str_replace('_', ' ', $this->state[0]))); + $name = $this->search->get_name(); $action = &$this->state[1]; @@ -454,7 +455,7 @@ class acp_search continue; } - $name = ucfirst(strtolower(str_replace('_', ' ', $type))); + $name = $search->get_name(); $data = array(); if (method_exists($search, 'index_stats')) @@ -553,8 +554,19 @@ class acp_search function get_search_types() { - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_extension_manager; + + $finder = $phpbb_extension_manager->get_finder(); + + return $finder + ->suffix('_backend') + ->directory('/search') + ->default_path('includes/search/') + ->default_suffix('') + ->default_directory('') + ->get_classes(); +/* $search_types = array(); $dp = @opendir($phpbb_root_path . 'includes/search'); @@ -574,6 +586,7 @@ class acp_search } return $search_types; +*/ } function get_max_post_id() @@ -610,14 +623,6 @@ class acp_search { global $phpbb_root_path, $phpEx, $user; - if (!preg_match('#^\w+$#', $type) || !file_exists("{$phpbb_root_path}includes/search/$type.$phpEx")) - { - $error = $user->lang['NO_SUCH_SEARCH_MODULE']; - return $error; - } - - include_once("{$phpbb_root_path}includes/search/$type.$phpEx"); - if (!class_exists($type)) { $error = $user->lang['NO_SUCH_SEARCH_MODULE']; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 4ca76344de..adc285cf6e 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2350,16 +2350,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if ($update_search_index && $data['enable_indexing']) { // Select the search method and do some additional checks to ensure it can actually be utilised - $search_type = basename($config['search_type']); - - if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } + $search_type = $config['search_type']; if (!class_exists($search_type)) { - include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); + trigger_error('NO_SUCH_SEARCH_MODULE'); } $error = false; diff --git a/phpBB/includes/search/base.php b/phpBB/includes/search/base.php new file mode 100644 index 0000000000..bb63957aba --- /dev/null +++ b/phpBB/includes/search/base.php @@ -0,0 +1,318 @@ +ignore_words)) + { + global $user, $phpEx; + + $words = array(); + + if (file_exists("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx")) + { + // include the file containing ignore words + include("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx"); + } + + $this->ignore_words = $words; + unset($words); + } + } + + /** + * Stores a list of synonyms that should be replaced in $this->match_synonym and $this->replace_synonym and caches them + */ + function get_synonyms() + { + if (!sizeof($this->match_synonym)) + { + global $user, $phpEx; + + $synonyms = array(); + + if (file_exists("{$user->lang_path}{$user->lang_name}/search_synonyms.$phpEx")) + { + // include the file containing synonyms + include("{$user->lang_path}{$user->lang_name}/search_synonyms.$phpEx"); + } + + $this->match_synonym = array_keys($synonyms); + $this->replace_synonym = array_values($synonyms); + + unset($synonyms); + } + } + + /** + * Retrieves cached search results + * + * @param int &$result_count will contain the number of all results for the search (not only for the current page) + * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache + * + * @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE + */ + function obtain_ids($search_key, &$result_count, &$id_ary, $start, $per_page, $sort_dir) + { + global $cache; + + if (!($stored_ids = $cache->get('_search_results_' . $search_key))) + { + // no search results cached for this search_key + return SEARCH_RESULT_NOT_IN_CACHE; + } + else + { + $result_count = $stored_ids[-1]; + $reverse_ids = ($stored_ids[-2] != $sort_dir) ? true : false; + $complete = true; + + // change the start to the actual end of the current request if the sort direction differs + // from the dirction in the cache and reverse the ids later + if ($reverse_ids) + { + $start = $result_count - $start - $per_page; + + // the user requested a page past the last index + if ($start < 0) + { + return SEARCH_RESULT_NOT_IN_CACHE; + } + } + + for ($i = $start, $n = $start + $per_page; ($i < $n) && ($i < $result_count); $i++) + { + if (!isset($stored_ids[$i])) + { + $complete = false; + } + else + { + $id_ary[] = $stored_ids[$i]; + } + } + unset($stored_ids); + + if ($reverse_ids) + { + $id_ary = array_reverse($id_ary); + } + + if (!$complete) + { + return SEARCH_RESULT_INCOMPLETE; + } + return SEARCH_RESULT_IN_CACHE; + } + } + + /** + * Caches post/topic ids + * + * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element + * must have the absolute index $start in the result set. + */ + function save_ids($search_key, $keywords, $author_ary, $result_count, &$id_ary, $start, $sort_dir) + { + global $cache, $config, $db, $user; + + $length = min(sizeof($id_ary), $config['search_block_size']); + + // nothing to cache so exit + if (!$length) + { + return; + } + + $store_ids = array_slice($id_ary, 0, $length); + + // create a new resultset if there is none for this search_key yet + // or add the ids to the existing resultset + if (!($store = $cache->get('_search_results_' . $search_key))) + { + // add the current keywords to the recent searches in the cache which are listed on the search page + if (!empty($keywords) || sizeof($author_ary)) + { + $sql = 'SELECT search_time + FROM ' . SEARCH_RESULTS_TABLE . ' + WHERE search_key = \'' . $db->sql_escape($search_key) . '\''; + $result = $db->sql_query($sql); + + if (!$db->sql_fetchrow($result)) + { + $sql_ary = array( + 'search_key' => $search_key, + 'search_time' => time(), + 'search_keywords' => $keywords, + 'search_authors' => ' ' . implode(' ', $author_ary) . ' ' + ); + + $sql = 'INSERT INTO ' . SEARCH_RESULTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); + $db->sql_query($sql); + } + $db->sql_freeresult($result); + } + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_last_search = ' . time() . ' + WHERE user_id = ' . $user->data['user_id']; + $db->sql_query($sql); + + $store = array(-1 => $result_count, -2 => $sort_dir); + $id_range = range($start, $start + $length - 1); + } + else + { + // we use one set of results for both sort directions so we have to calculate the indizes + // for the reversed array and we also have to reverse the ids themselves + if ($store[-2] != $sort_dir) + { + $store_ids = array_reverse($store_ids); + $id_range = range($store[-1] - $start - $length, $store[-1] - $start - 1); + } + else + { + $id_range = range($start, $start + $length - 1); + } + } + + $store_ids = array_combine($id_range, $store_ids); + + // append the ids + if (is_array($store_ids)) + { + $store += $store_ids; + + // if the cache is too big + if (sizeof($store) - 2 > 20 * $config['search_block_size']) + { + // remove everything in front of two blocks in front of the current start index + for ($i = 0, $n = $id_range[0] - 2 * $config['search_block_size']; $i < $n; $i++) + { + if (isset($store[$i])) + { + unset($store[$i]); + } + } + + // remove everything after two blocks after the current stop index + end($id_range); + for ($i = $store[-1] - 1, $n = current($id_range) + 2 * $config['search_block_size']; $i > $n; $i--) + { + if (isset($store[$i])) + { + unset($store[$i]); + } + } + } + $cache->put('_search_results_' . $search_key, $store, $config['search_store_results']); + + $sql = 'UPDATE ' . SEARCH_RESULTS_TABLE . ' + SET search_time = ' . time() . ' + WHERE search_key = \'' . $db->sql_escape($search_key) . '\''; + $db->sql_query($sql); + } + + unset($store); + unset($store_ids); + unset($id_range); + } + + /** + * Removes old entries from the search results table and removes searches with keywords that contain a word in $words. + */ + function destroy_cache($words, $authors = false) + { + global $db, $cache, $config; + + // clear all searches that searched for the specified words + if (sizeof($words)) + { + $sql_where = ''; + foreach ($words as $word) + { + $sql_where .= " OR search_keywords " . $db->sql_like_expression($db->any_char . $word . $db->any_char); + } + + $sql = 'SELECT search_key + FROM ' . SEARCH_RESULTS_TABLE . " + WHERE search_keywords LIKE '%*%' $sql_where"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $cache->destroy('_search_results_' . $row['search_key']); + } + $db->sql_freeresult($result); + } + + // clear all searches that searched for the specified authors + if (is_array($authors) && sizeof($authors)) + { + $sql_where = ''; + foreach ($authors as $author) + { + $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors LIKE \'% ' . (int) $author . ' %\''; + } + + $sql = 'SELECT search_key + FROM ' . SEARCH_RESULTS_TABLE . " + WHERE $sql_where"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $cache->destroy('_search_results_' . $row['search_key']); + } + $db->sql_freeresult($result); + } + + $sql = 'DELETE + FROM ' . SEARCH_RESULTS_TABLE . ' + WHERE search_time < ' . (time() - $config['search_store_results']); + $db->sql_query($sql); + } +} diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 827205f20d..b9920da624 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -16,17 +16,12 @@ if (!defined('IN_PHPBB')) exit; } -/** -* @ignore -*/ -include_once($phpbb_root_path . 'includes/search/search.' . $phpEx); - /** * fulltext_mysql * Fulltext search for MySQL * @package search */ -class fulltext_mysql extends search_backend +class phpbb_search_fulltext_mysql extends phpbb_search_base { var $stats = array(); var $word_length = array(); @@ -36,7 +31,7 @@ class fulltext_mysql extends search_backend var $pcre_properties = false; var $mbstring_regex = false; - function fulltext_mysql(&$error) + public function __construct(&$error) { global $config; @@ -57,6 +52,11 @@ class fulltext_mysql extends search_backend $error = false; } + function get_name() + { + return 'MySQL Fulltext'; + } + /** * Checks for correct MySQL version and stores min/max word length in the config */ diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index e749e86f68..7c792bba24 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -16,17 +16,12 @@ if (!defined('IN_PHPBB')) exit; } -/** -* @ignore -*/ -include_once($phpbb_root_path . 'includes/search/search.' . $phpEx); - /** * fulltext_native * phpBB's own db driven fulltext search, version 2 * @package search */ -class fulltext_native extends search_backend +class phpbb_search_fulltext_native extends phpbb_search_base { var $stats = array(); var $word_length = array(); @@ -41,10 +36,8 @@ class fulltext_native extends search_backend * Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded. * * @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure. - * - * @access public */ - function fulltext_native(&$error) + public function __construct(&$error) { global $phpbb_root_path, $phpEx, $config; @@ -58,10 +51,14 @@ class fulltext_native extends search_backend include($phpbb_root_path . 'includes/utf/utf_normalizer.' . $phpEx); } - $error = false; } + function get_name() + { + return 'phpBB Native Fulltext'; + } + /** * This function fills $this->search_query with the cleaned user search query. * diff --git a/phpBB/includes/search/search.php b/phpBB/includes/search/search.php deleted file mode 100644 index 7c34ce9ff6..0000000000 --- a/phpBB/includes/search/search.php +++ /dev/null @@ -1,318 +0,0 @@ -ignore_words)) - { - global $user, $phpEx; - - $words = array(); - - if (file_exists("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx")) - { - // include the file containing ignore words - include("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx"); - } - - $this->ignore_words = $words; - unset($words); - } - } - - /** - * Stores a list of synonyms that should be replaced in $this->match_synonym and $this->replace_synonym and caches them - */ - function get_synonyms() - { - if (!sizeof($this->match_synonym)) - { - global $user, $phpEx; - - $synonyms = array(); - - if (file_exists("{$user->lang_path}{$user->lang_name}/search_synonyms.$phpEx")) - { - // include the file containing synonyms - include("{$user->lang_path}{$user->lang_name}/search_synonyms.$phpEx"); - } - - $this->match_synonym = array_keys($synonyms); - $this->replace_synonym = array_values($synonyms); - - unset($synonyms); - } - } - - /** - * Retrieves cached search results - * - * @param int &$result_count will contain the number of all results for the search (not only for the current page) - * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache - * - * @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE - */ - function obtain_ids($search_key, &$result_count, &$id_ary, $start, $per_page, $sort_dir) - { - global $cache; - - if (!($stored_ids = $cache->get('_search_results_' . $search_key))) - { - // no search results cached for this search_key - return SEARCH_RESULT_NOT_IN_CACHE; - } - else - { - $result_count = $stored_ids[-1]; - $reverse_ids = ($stored_ids[-2] != $sort_dir) ? true : false; - $complete = true; - - // change the start to the actual end of the current request if the sort direction differs - // from the dirction in the cache and reverse the ids later - if ($reverse_ids) - { - $start = $result_count - $start - $per_page; - - // the user requested a page past the last index - if ($start < 0) - { - return SEARCH_RESULT_NOT_IN_CACHE; - } - } - - for ($i = $start, $n = $start + $per_page; ($i < $n) && ($i < $result_count); $i++) - { - if (!isset($stored_ids[$i])) - { - $complete = false; - } - else - { - $id_ary[] = $stored_ids[$i]; - } - } - unset($stored_ids); - - if ($reverse_ids) - { - $id_ary = array_reverse($id_ary); - } - - if (!$complete) - { - return SEARCH_RESULT_INCOMPLETE; - } - return SEARCH_RESULT_IN_CACHE; - } - } - - /** - * Caches post/topic ids - * - * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element - * must have the absolute index $start in the result set. - */ - function save_ids($search_key, $keywords, $author_ary, $result_count, &$id_ary, $start, $sort_dir) - { - global $cache, $config, $db, $user; - - $length = min(sizeof($id_ary), $config['search_block_size']); - - // nothing to cache so exit - if (!$length) - { - return; - } - - $store_ids = array_slice($id_ary, 0, $length); - - // create a new resultset if there is none for this search_key yet - // or add the ids to the existing resultset - if (!($store = $cache->get('_search_results_' . $search_key))) - { - // add the current keywords to the recent searches in the cache which are listed on the search page - if (!empty($keywords) || sizeof($author_ary)) - { - $sql = 'SELECT search_time - FROM ' . SEARCH_RESULTS_TABLE . ' - WHERE search_key = \'' . $db->sql_escape($search_key) . '\''; - $result = $db->sql_query($sql); - - if (!$db->sql_fetchrow($result)) - { - $sql_ary = array( - 'search_key' => $search_key, - 'search_time' => time(), - 'search_keywords' => $keywords, - 'search_authors' => ' ' . implode(' ', $author_ary) . ' ' - ); - - $sql = 'INSERT INTO ' . SEARCH_RESULTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); - $db->sql_query($sql); - } - $db->sql_freeresult($result); - } - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_last_search = ' . time() . ' - WHERE user_id = ' . $user->data['user_id']; - $db->sql_query($sql); - - $store = array(-1 => $result_count, -2 => $sort_dir); - $id_range = range($start, $start + $length - 1); - } - else - { - // we use one set of results for both sort directions so we have to calculate the indizes - // for the reversed array and we also have to reverse the ids themselves - if ($store[-2] != $sort_dir) - { - $store_ids = array_reverse($store_ids); - $id_range = range($store[-1] - $start - $length, $store[-1] - $start - 1); - } - else - { - $id_range = range($start, $start + $length - 1); - } - } - - $store_ids = array_combine($id_range, $store_ids); - - // append the ids - if (is_array($store_ids)) - { - $store += $store_ids; - - // if the cache is too big - if (sizeof($store) - 2 > 20 * $config['search_block_size']) - { - // remove everything in front of two blocks in front of the current start index - for ($i = 0, $n = $id_range[0] - 2 * $config['search_block_size']; $i < $n; $i++) - { - if (isset($store[$i])) - { - unset($store[$i]); - } - } - - // remove everything after two blocks after the current stop index - end($id_range); - for ($i = $store[-1] - 1, $n = current($id_range) + 2 * $config['search_block_size']; $i > $n; $i--) - { - if (isset($store[$i])) - { - unset($store[$i]); - } - } - } - $cache->put('_search_results_' . $search_key, $store, $config['search_store_results']); - - $sql = 'UPDATE ' . SEARCH_RESULTS_TABLE . ' - SET search_time = ' . time() . ' - WHERE search_key = \'' . $db->sql_escape($search_key) . '\''; - $db->sql_query($sql); - } - - unset($store); - unset($store_ids); - unset($id_range); - } - - /** - * Removes old entries from the search results table and removes searches with keywords that contain a word in $words. - */ - function destroy_cache($words, $authors = false) - { - global $db, $cache, $config; - - // clear all searches that searched for the specified words - if (sizeof($words)) - { - $sql_where = ''; - foreach ($words as $word) - { - $sql_where .= " OR search_keywords " . $db->sql_like_expression($db->any_char . $word . $db->any_char); - } - - $sql = 'SELECT search_key - FROM ' . SEARCH_RESULTS_TABLE . " - WHERE search_keywords LIKE '%*%' $sql_where"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $cache->destroy('_search_results_' . $row['search_key']); - } - $db->sql_freeresult($result); - } - - // clear all searches that searched for the specified authors - if (is_array($authors) && sizeof($authors)) - { - $sql_where = ''; - foreach ($authors as $author) - { - $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors LIKE \'% ' . (int) $author . ' %\''; - } - - $sql = 'SELECT search_key - FROM ' . SEARCH_RESULTS_TABLE . " - WHERE $sql_where"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $cache->destroy('_search_results_' . $row['search_key']); - } - $db->sql_freeresult($result); - } - - $sql = 'DELETE - FROM ' . SEARCH_RESULTS_TABLE . ' - WHERE search_time < ' . (time() - $config['search_store_results']); - $db->sql_query($sql); - } -} diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index b2419df3c9..1f3c01ee3e 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2106,6 +2106,10 @@ function change_database_data(&$no_updates, $version) // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': + // try to guess the new auto loaded search class name + // works for native and mysql fulltext + set_config('search_type', 'phpbb_search_' . $config['search_type']); + set_config('use_system_cron', 0); $sql = 'UPDATE ' . GROUPS_TABLE . ' diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 5506922e17..bd7334f9d4 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -223,7 +223,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_block_size' INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_gc', '7200'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_interval', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_anonymous_interval', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_type', 'fulltext_native'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_type', 'phpbb_search_fulltext_native'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_store_results', '1800'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_deny', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_empty_referer', '1'); diff --git a/phpBB/search.php b/phpBB/search.php index 1d35dfb062..c6189051a3 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -73,7 +73,7 @@ switch ($search_id) login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']); } break; - + // The "new posts" search uses user_lastvisit which is user based, so it should require user to log in. case 'newposts': if ($user->data['user_id'] == ANONYMOUS) @@ -81,7 +81,7 @@ switch ($search_id) login_box('', $user->lang['LOGIN_EXPLAIN_NEWPOSTS']); } break; - + default: // There's nothing to do here for now ;) break; @@ -273,15 +273,12 @@ if ($keywords || $author || $author_id || $search_id || $submit) } // Select which method we'll use to obtain the post_id or topic_id information - $search_type = basename($config['search_type']); + $search_type = $config['search_type']; - if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) + if (!class_exists($search_type)) { trigger_error('NO_SUCH_SEARCH_MODULE'); } - - require("{$phpbb_root_path}includes/search/$search_type.$phpEx"); - // We do some additional checks in the module to ensure it can actually be utilised $error = false; $search = new $search_type($error); -- cgit v1.2.1 From 956860c21d2285ac325a48d6caf1e4fa45aca922 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 15 Aug 2011 20:07:35 -0400 Subject: [feature/extension-manager] Never cache extension finder queries in debug mode During development the detection of files should happen immediately and performance is less of a concern. PHPBB3-10323 --- phpBB/includes/extension/finder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index fb532e52f8..4180b84dd3 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -179,7 +179,7 @@ class phpbb_extension_finder { $query = md5(serialize($this->query)); - if ($cache && isset($this->cached_queries[$query])) + if (!defined('DEBUG') && $cache && isset($this->cached_queries[$query])) { return $this->cached_queries[$query]; } -- cgit v1.2.1 From 989bd9cde7314024999f5b92fc2ff4572b9ac937 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 15 Aug 2011 20:55:29 -0400 Subject: [feature/extension-manager] Skip phpbb_search_base by checking for get_name() PHPBB3-10323 --- phpBB/includes/acp/acp_search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php index a6377f6b49..0c34d02ac7 100644 --- a/phpBB/includes/acp/acp_search.php +++ b/phpBB/includes/acp/acp_search.php @@ -623,7 +623,7 @@ class acp_search { global $phpbb_root_path, $phpEx, $user; - if (!class_exists($type)) + if (!class_exists($type) || !method_exists($type, 'get_name')) { $error = $user->lang['NO_SUCH_SEARCH_MODULE']; return $error; -- cgit v1.2.1 From 96209e022477d97b581b79cabace4caddd19501b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 15 Aug 2011 21:38:47 -0400 Subject: [feature/extension-manager] The class loader no longer knows about extensions Instead the class loader is instantiated twice. Once with the phpbb_ prefix and once with the phpbb_ext_ prefix. PHPBB3-10323 --- phpBB/common.php | 9 +++++--- phpBB/download/file.php | 9 +++++--- phpBB/includes/class_loader.php | 47 +++++++++++++++------------------------ phpBB/install/database_update.php | 9 +++++--- phpBB/install/index.php | 9 +++++--- 5 files changed, 42 insertions(+), 41 deletions(-) (limited to 'phpBB') diff --git a/phpBB/common.php b/phpBB/common.php index cc33b29a09..61817972f9 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -96,13 +96,16 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); -$class_loader->register(); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".$phpEx"); +$phpbb_class_loader_ext->register(); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".$phpEx"); +$phpbb_class_loader->register(); // set up caching $cache_factory = new phpbb_cache_factory($acm_type); $cache = $cache_factory->get_service(); -$class_loader->set_cache($cache->get_driver()); +$phpbb_class_loader_ext->set_cache($cache->get_driver()); +$phpbb_class_loader->set_cache($cache->get_driver()); // Instantiate some basic classes $request = new phpbb_request(); diff --git a/phpBB/download/file.php b/phpBB/download/file.php index e13524f922..2a9c472ca7 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -46,13 +46,16 @@ if (isset($_GET['avatar'])) require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); - $class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); - $class_loader->register(); + $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".$phpEx"); + $phpbb_class_loader_ext->register(); + $phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".$phpEx"); + $phpbb_class_loader->register(); // set up caching $cache_factory = new phpbb_cache_factory($acm_type); $cache = $cache_factory->get_service(); - $class_loader->set_cache($cache->get_driver()); + $phpbb_class_loader_ext->set_cache($cache->get_driver()); + $phpbb_class_loader->set_cache($cache->get_driver()); $request = new phpbb_request(); $db = new $sql_db(); diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php index bcf1ba1650..46a271471a 100644 --- a/phpBB/includes/class_loader.php +++ b/phpBB/includes/class_loader.php @@ -31,25 +31,25 @@ if (!defined('IN_PHPBB')) */ class phpbb_class_loader { - private $core_path; - private $ext_path; + private $prefix; + private $path; private $php_ext; private $cache; private $cached_paths = array(); /** * Creates a new phpbb_class_loader, which loads files with the given - * file extension from the given core or extension path. + * file extension from the given path. * - * @param string $core_path phpBB's include directory for core files - * @param string $ext_path phpBB's extension directory - * @param string $php_ext The file extension for PHP files + * @param string $prefix Required class name prefix for files to be loaded + * @param string $path Directory to load files from + * @param string $php_ext The file extension for PHP files * @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface. */ - public function __construct($core_path, $ext_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) + public function __construct($prefix, $path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) { - $this->core_path = $core_path; - $this->ext_path = $ext_path; + $this->prefix = $prefix; + $this->path = $path; $this->php_ext = $php_ext; $this->set_cache($cache); @@ -66,7 +66,7 @@ class phpbb_class_loader { if ($cache) { - $this->cached_paths = $cache->get('class_loader'); + $this->cached_paths = $cache->get('class_loader_' . $this->prefix); if ($this->cached_paths === false) { @@ -103,32 +103,21 @@ class phpbb_class_loader */ public function resolve_path($class) { - if (substr($class, 6, 4) === 'ext_') - { - $path_prefix = $this->ext_path; - $prefix_length = 10; - } - else - { - $path_prefix = $this->core_path; - $prefix_length = 6; - } - if (isset($this->cached_paths[$class])) { - return $path_prefix . $this->cached_paths[$class] . $this->php_ext; + return $this->path . $this->cached_paths[$class] . $this->php_ext; } - if (!preg_match('/phpbb_[a-zA-Z0-9_]+/', $class)) + if (!preg_match('/^' . $this->prefix . '[a-zA-Z0-9_]+$/', $class)) { return false; } - $parts = explode('_', substr($class, $prefix_length)); + $parts = explode('_', substr($class, strlen($this->prefix))); $dirs = ''; - for ($i = 0, $n = sizeof($parts); $i < $n && is_dir($path_prefix . $dirs . $parts[$i]); $i++) + for ($i = 0, $n = sizeof($parts); $i < $n && is_dir($this->path . $dirs . $parts[$i]); $i++) { $dirs .= $parts[$i] . '/'; } @@ -141,7 +130,7 @@ class phpbb_class_loader $relative_path = $dirs . implode(array_slice($parts, $i, sizeof($parts) - $i), '_'); - if (!file_exists($path_prefix . $relative_path . $this->php_ext)) + if (!file_exists($this->path . $relative_path . $this->php_ext)) { return false; } @@ -149,10 +138,10 @@ class phpbb_class_loader if ($this->cache) { $this->cached_paths[$class] = $relative_path; - $this->cache->put('class_loader', $this->cached_paths); + $this->cache->put('class_loader_' . $this->prefix, $this->cached_paths); } - return $path_prefix . $relative_path . $this->php_ext; + return $this->path . $relative_path . $this->php_ext; } /** @@ -162,7 +151,7 @@ class phpbb_class_loader */ public function load_class($class) { - if (substr($class, 0, 6) === 'phpbb_') + if (substr($class, 0, strlen($this->prefix)) === $this->prefix) { $path = $this->resolve_path($class); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 1f3c01ee3e..64dea37ef8 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -109,13 +109,16 @@ if (!defined('EXT_TABLE')) define('EXT_TABLE', $table_prefix . 'ext'); } -$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); -$class_loader->register(); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".$phpEx"); +$phpbb_class_loader_ext->register(); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".$phpEx"); +$phpbb_class_loader->register(); // set up caching $cache_factory = new phpbb_cache_factory($acm_type); $cache = $cache_factory->get_service(); -$class_loader->set_cache($cache->get_driver()); +$phpbb_class_loader_ext->set_cache($cache->get_driver()); +$phpbb_class_loader->set_cache($cache->get_driver()); $request = new phpbb_request(); $user = new user(); diff --git a/phpBB/install/index.php b/phpBB/install/index.php index fbe8ae63a7..0a46a06664 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -82,13 +82,16 @@ 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); -$class_loader = new phpbb_class_loader($phpbb_root_path . 'includes/', $phpbb_root_path . 'ext/', '.' . $phpEx); -$class_loader->register(); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".$phpEx"); +$phpbb_class_loader_ext->register(); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".$phpEx"); +$phpbb_class_loader->register(); // set up caching $cache_factory = new phpbb_cache_factory('file'); $cache = $cache_factory->get_service(); -$class_loader->set_cache($cache->get_driver()); +$phpbb_class_loader_ext->set_cache($cache->get_driver()); +$phpbb_class_loader->set_cache($cache->get_driver()); $request = new phpbb_request(); -- cgit v1.2.1 From 5d5030a48be3d65df85d78e26690085c0889c6e3 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 21 Aug 2011 02:57:01 -0400 Subject: [feature/extension-manager] Remove cron's dependency on the extension manager. Instead a separate cron provider supplies the manager with tasks from the extension finder. PHPBB3-10323 --- phpBB/common.php | 2 +- phpBB/cron.php | 2 +- phpBB/includes/cron/manager.php | 48 ++------------------- phpBB/includes/cron/provider.php | 92 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 46 deletions(-) create mode 100644 phpBB/includes/cron/provider.php (limited to 'phpBB') diff --git a/phpBB/common.php b/phpBB/common.php index 61817972f9..3cc9e57e46 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -144,5 +144,5 @@ foreach ($cache->obtain_hooks() as $hook) if (!$config['use_system_cron']) { - $cron = new phpbb_cron_manager($phpbb_extension_manager, $cache->get_driver()); + $cron = new phpbb_cron_manager(new phpbb_cron_provider($phpbb_extension_manager), $cache->get_driver()); } diff --git a/phpBB/cron.php b/phpBB/cron.php index cc5964218a..6633a6c3fd 100644 --- a/phpBB/cron.php +++ b/phpBB/cron.php @@ -62,7 +62,7 @@ function do_cron($cron_lock, $run_tasks) if ($config['use_system_cron']) { - $cron = new phpbb_cron_manager($phpbb_root_path . 'includes/cron/task', $phpEx, $cache->get_driver()); + $cron = new phpbb_cron_manager(new phpbb_cron_provider($phpbb_extension_manager), $cache->get_driver()); } else { diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php index ae48e233e0..a0bf018b33 100644 --- a/phpBB/includes/cron/manager.php +++ b/phpBB/includes/cron/manager.php @@ -32,65 +32,25 @@ class phpbb_cron_manager */ protected $tasks = array(); - /** - * An extension manager to search for cron tasks in extensions. - * @var phpbb_extension_manager - */ - protected $extension_manager; - /** * Constructor. Loads all available tasks. * - * Tasks will be looked up in the core task directory located in - * includes/cron/task/core/ and in extensions. Task classes will be - * autoloaded and must be named according to autoloading naming conventions. - * - * Tasks in extensions must be located in a directory called cron or a subdir - * of a directory called cron. The class and filename must end in a _task - * suffix. - * - * @param phpbb_extension_manager $extension_manager phpBB extension manager + * @param array|Traversable $task_names Provides an iterable set of task names */ - public function __construct(phpbb_extension_manager $extension_manager) + public function __construct($task_names) { - $this->extension_manager = $extension_manager; - - $task_names = $this->find_cron_task_names(); $this->load_tasks($task_names); } - /** - * Finds cron task names using the extension manager. - * - * All PHP files in includes/cron/task/core/ are considered tasks. Tasks - * in extensions have to be located in a directory called cron or a subdir - * of a directory called cron. The class and filename must end in a _task - * suffix. - * - * @return array List of task names - */ - public function find_cron_task_names() - { - $finder = $this->extension_manager->get_finder(); - - return $finder - ->suffix('_task') - ->directory('/cron') - ->default_path('includes/cron/task/core/') - ->default_suffix('') - ->default_directory('') - ->get_classes(); - } - /** * Loads tasks given by name, wraps them * and puts them into $this->tasks. * - * @param array $task_names Array of strings + * @param array|Traversable $task_names Array of strings * * @return void */ - public function load_tasks(array $task_names) + public function load_tasks($task_names) { foreach ($task_names as $task_name) { diff --git a/phpBB/includes/cron/provider.php b/phpBB/includes/cron/provider.php new file mode 100644 index 0000000000..9936da3f55 --- /dev/null +++ b/phpBB/includes/cron/provider.php @@ -0,0 +1,92 @@ +extension_manager = $extension_manager; + + $this->task_names = $this->find_cron_task_names(); + } + + /** + * Finds cron task names using the extension manager. + * + * All PHP files in includes/cron/task/core/ are considered tasks. Tasks + * in extensions have to be located in a directory called cron or a subdir + * of a directory called cron. The class and filename must end in a _task + * suffix. + * + * @return array List of task names + */ + public function find_cron_task_names() + { + $finder = $this->extension_manager->get_finder(); + + return $finder + ->suffix('_task') + ->directory('/cron') + ->default_path('includes/cron/task/core/') + ->default_suffix('') + ->default_directory('') + ->get_classes(); + } + + /** + * Retrieve an iterator over all task names + * + * @return ArrayIterator An iterator for the array of task names + */ + public function getIterator() + { + return new ArrayIterator($this->task_names); + } +} -- cgit v1.2.1 From 60ad0e21b5d4f940740650df69b7134a573f2a97 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 21 Aug 2011 03:06:56 -0400 Subject: [feature/extension-manager] Remove the ext_active index for lack of specificity PHPBB3-10323 --- phpBB/develop/create_schema_files.php | 1 - phpBB/install/database_update.php | 1 - phpBB/install/schemas/firebird_schema.sql | 1 - phpBB/install/schemas/mssql_schema.sql | 3 --- phpBB/install/schemas/mysql_40_schema.sql | 3 +-- phpBB/install/schemas/mysql_41_schema.sql | 3 +-- phpBB/install/schemas/oracle_schema.sql | 2 -- phpBB/install/schemas/postgres_schema.sql | 1 - phpBB/install/schemas/sqlite_schema.sql | 1 - 9 files changed, 2 insertions(+), 14 deletions(-) (limited to 'phpBB') diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 9f2015f38e..bc1e28572d 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1038,7 +1038,6 @@ function get_schema_struct() ), 'KEYS' => array( 'ext_name' => array('UNIQUE', 'ext_name'), - 'ext_active' => array('INDEX', 'ext_active'), ), ); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 64dea37ef8..45de19c918 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1063,7 +1063,6 @@ function database_update_info() ), 'KEYS' => array( 'ext_name' => array('UNIQUE', 'ext_name'), - 'ext_active' => array('INDEX', 'ext_active'), ), ), ), diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 5f5aaaaa45..4952b6bbdf 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -288,7 +288,6 @@ CREATE TABLE phpbb_ext ( );; CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext(ext_name);; -CREATE INDEX phpbb_ext_ext_active ON phpbb_ext(ext_active);; # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 052531993f..76f3fc6491 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -370,9 +370,6 @@ GO CREATE UNIQUE INDEX [ext_name] ON [phpbb_ext]([ext_name]) ON [PRIMARY] GO -CREATE INDEX [ext_active] ON [phpbb_ext]([ext_active]) ON [PRIMARY] -GO - /* Table: 'phpbb_extensions' diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 03402d7ed1..a1b282418d 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -195,8 +195,7 @@ CREATE TABLE phpbb_drafts ( CREATE TABLE phpbb_ext ( ext_name varbinary(255) DEFAULT '' NOT NULL, ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE ext_name (ext_name), - KEY ext_active (ext_active) + UNIQUE ext_name (ext_name) ); diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 8876b52a30..2f2de17dcb 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -195,8 +195,7 @@ CREATE TABLE phpbb_drafts ( CREATE TABLE phpbb_ext ( ext_name varchar(255) DEFAULT '' NOT NULL, ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE ext_name (ext_name), - KEY ext_active (ext_active) + UNIQUE ext_name (ext_name) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index df31f6d3d6..f0a958d2f6 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -417,8 +417,6 @@ CREATE TABLE phpbb_ext ( ) / -CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active) -/ /* Table: 'phpbb_extensions' diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index dbe891a3ac..956167ff39 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -321,7 +321,6 @@ CREATE TABLE phpbb_ext ( ); CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); -CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active); /* Table: 'phpbb_extensions' diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 3c1d476daa..223dbc3c02 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -193,7 +193,6 @@ CREATE TABLE phpbb_ext ( ); CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); -CREATE INDEX phpbb_ext_ext_active ON phpbb_ext (ext_active); # Table: 'phpbb_extensions' CREATE TABLE phpbb_extensions ( -- cgit v1.2.1 From f6632fcfd08650f13560529a6a04c152aefd4e3c Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 22 Aug 2011 02:17:00 -0400 Subject: [feature/extension-manager] Add filename prefix matching in extension finder PHPBB3-10323 --- phpBB/includes/extension/finder.php | 47 +++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 4180b84dd3..fbc8a3aefb 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -50,8 +50,10 @@ class phpbb_extension_finder $this->query = array( 'default_path' => false, 'default_suffix' => false, + 'default_prefix' => false, 'default_directory' => false, 'suffix' => false, + 'prefix' => false, 'directory' => false, ); @@ -76,7 +78,7 @@ class phpbb_extension_finder * Automatically sets the default_suffix if its value does not differ from * the current suffix. * - * @param string $default_path A filename suffix + * @param string $suffix A filename suffix * @return phpbb_extension_finder This object for chaining calls */ public function suffix($suffix) @@ -102,6 +104,38 @@ class phpbb_extension_finder return $this; } + /** + * Sets a prefix all files found in extensions must match + * + * Automatically sets the default_prefix if its value does not differ from + * the current prefix. + * + * @param string $prefix A filename prefix + * @return phpbb_extension_finder This object for chaining calls + */ + public function prefix($prefix) + { + if ($this->query['default_prefix'] === $this->query['prefix']) + { + $this->query['default_prefix'] = $prefix; + } + + $this->query['prefix'] = $prefix; + return $this; + } + + /** + * Sets a prefix all files found in the default path must match + * + * @param string $default_prefix A filename prefix + * @return phpbb_extension_finder This object for chaining calls + */ + public function default_prefix($default_prefix) + { + $this->query['default_prefix'] = $default_prefix; + return $this; + } + /** * Sets a directory all files found in extensions must be contained in * @@ -202,16 +236,18 @@ class phpbb_extension_finder if ($name === '/') { - $prefix = $this->query['default_path']; + $location = $this->query['default_path']; $name = ''; $suffix = $this->query['default_suffix']; + $prefix = $this->query['default_prefix']; $directory = $this->query['default_directory']; } else { - $prefix = 'ext/'; + $location = 'ext/'; $name .= '/'; $suffix = $this->query['suffix']; + $prefix = $this->query['prefix']; $directory = $this->query['directory']; } @@ -226,10 +262,11 @@ class phpbb_extension_finder { $relative_path = $iterator->getInnerIterator()->getSubPathname(); - if ((!$suffix || substr($relative_path, -strlen($suffix)) == $suffix) && + if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) && + (!$prefix || substr($file_info->getFilename(), 0, strlen($prefix)) === $prefix) && (!$directory || preg_match($directory_pattern, DIRECTORY_SEPARATOR . $relative_path))) { - $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $prefix . $name . $relative_path); + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . $relative_path); } } } -- cgit v1.2.1 From 4844b007771f71973db2fa440d3c8ef9057d1b02 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 22 Aug 2011 03:19:17 -0400 Subject: [feature/extension-manager] Load (A/U/M)CP modules from extensions To avoid large bc breaking changes, modules in the old includes directory structure still follow the same naming conventions. Modules in extensions have to be placed in an xcp/ folder and need a _module suffix. The corresponding info file is in the same directory but with an _info suffix. PHPBB3-10323 --- phpBB/includes/acp/acp_modules.php | 85 +++++++++++++++++++++++-------------- phpBB/includes/functions_module.php | 84 ++++++++++++++++++------------------ 2 files changed, 94 insertions(+), 75 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 52033b590c..2a533056b4 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -316,7 +316,7 @@ class acp_modules } // Name options - $s_name_options .= ''; + $s_name_options .= ''; $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option))); @@ -480,7 +480,7 @@ class acp_modules foreach ($module_infos as $option => $values) { // Name options - $s_install_options .= ''; + $s_install_options .= ''; // Build module modes foreach ($values['modes'] as $m_mode => $m_values) @@ -539,57 +539,78 @@ class acp_modules if (!$module) { - $dh = @opendir($directory); + global $phpbb_extension_manager; - if (!$dh) - { - return $fileinfo; - } + $finder = $phpbb_extension_manager->get_finder(); + + $modules = $finder + ->suffix('_module') + ->directory("/$module_class") + ->default_path("includes/$module_class/info/") + ->default_suffix('') + ->default_prefix($module_class . '_') + ->default_directory('') + ->get_classes(); - while (($file = readdir($dh)) !== false) + foreach ($modules as $module) { - // Is module? - if (preg_match('/^' . $module_class . '_.+\.' . $phpEx . '$/', $file)) + // If the class does not exist it might be following the old + // format. phpbb_acp_info_acp_foo needs to be turned into + // acp_foo_info and the respective file has to be included + // manually because it does not support auto loading + if (!class_exists($module)) { - $class = str_replace(".$phpEx", '', $file) . '_info'; - - if (!class_exists($class)) + $info_class = str_replace("phpbb_{$module_class}_info_", '', $module) . '_info'; + if (file_exists($directory . $info_class . '.' . $phpEx)) { - include($directory . $file); + include($directory . $info_class . '.' . $phpEx); } + } + else + { + $info_class = preg_replace('/_module$/', '_info', $module); + } - // Get module title tag - if (class_exists($class)) - { - $c_class = new $class(); - $module_info = $c_class->module(); - $fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info; - } + if (class_exists($info_class)) + { + $info = new $info_class(); + $module_info = $info->module(); + + $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module; + + $fileinfo[$main_class] = $module_info; } } - closedir($dh); ksort($fileinfo); } else { - $filename = $module_class . '_' . basename($module); - $class = $module_class . '_' . basename($module) . '_info'; - - if (!class_exists($class)) + if (!class_exists($module)) { - include($directory . $filename . '.' . $phpEx); + if (file_exists($directory . $module . '.' . $phpEx)) + { + include($directory . $module . '.' . $phpEx); + } + $info_class = $module . '_info'; + } + else + { + $info_class = preg_replace('/_module$/', '_info', $module); } // Get module title tag - if (class_exists($class)) + if (class_exists($info_class)) { - $c_class = new $class(); - $module_info = $c_class->module(); - $fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info; + $info = new $info_class(); + $module_info = $info->module(); + + $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module; + + $fileinfo[$main_class] = $module_info; } } - + return $fileinfo; } diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 09c54422b0..1a6b57794a 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -440,7 +440,8 @@ class p_master trigger_error('Module not accessible', E_USER_ERROR); } - if (!class_exists("{$this->p_class}_$this->p_name")) + // new modules use the full class names, old ones are always called _, e.g. acp_board + if (!class_exists($this->p_name) && !class_exists("{$this->p_class}_$this->p_name")) { if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx")) { @@ -453,62 +454,59 @@ class p_master { trigger_error("Module file $module_path/{$this->p_class}_$this->p_name.$phpEx does not contain correct class [{$this->p_class}_$this->p_name]", E_USER_ERROR); } + } - if (!empty($mode)) - { - $this->p_mode = $mode; - } + if (!empty($mode)) + { + $this->p_mode = $mode; + } - // Create a new instance of the desired module ... if it has a - // constructor it will of course be executed - $instance = "{$this->p_class}_$this->p_name"; + // Create a new instance of the desired module ... + $class_name = (class_exists($this->p_name)) ? $this->p_name : "{$this->p_class}_$this->p_name"; - $this->module = new $instance($this); + $this->module = new $class_name($this); - // We pre-define the action parameter we are using all over the place - if (defined('IN_ADMIN')) + // We pre-define the action parameter we are using all over the place + if (defined('IN_ADMIN')) + { + // Is first module automatically enabled a duplicate and the category not passed yet? + if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate']) { - // Is first module automatically enabled a duplicate and the category not passed yet? - if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate']) - { - $icat = $this->module_ary[$this->active_module_row_id]['parent']; - } + $icat = $this->module_ary[$this->active_module_row_id]['parent']; + } - // Not being able to overwrite ;) - $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + // Not being able to overwrite ;) + $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + } + else + { + // If user specified the module url we will use it... + if ($module_url !== false) + { + $this->module->u_action = $module_url; } else { - // If user specified the module url we will use it... - if ($module_url !== false) - { - $this->module->u_action = $module_url; - } - else - { - $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name']; - } - - $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name']; } - // Add url_extra parameter to u_action url - if (!empty($this->module_ary) && $this->active_module !== false && $this->module_ary[$this->active_module_row_id]['url_extra']) - { - $this->module->u_action .= $this->module_ary[$this->active_module_row_id]['url_extra']; - } + $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + } - // Assign the module path for re-usage - $this->module->module_path = $module_path . '/'; + // Add url_extra parameter to u_action url + if (!empty($this->module_ary) && $this->active_module !== false && $this->module_ary[$this->active_module_row_id]['url_extra']) + { + $this->module->u_action .= $this->module_ary[$this->active_module_row_id]['url_extra']; + } - // Execute the main method for the new instance, we send the module id and mode as parameters - // Users are able to call the main method after this function to be able to assign additional parameters manually - if ($execute_module) - { - $this->module->main($this->p_name, $this->p_mode); - } + // Assign the module path for re-usage + $this->module->module_path = $module_path . '/'; - return; + // Execute the main method for the new instance, we send the module id and mode as parameters + // Users are able to call the main method after this function to be able to assign additional parameters manually + if ($execute_module) + { + $this->module->main($this->p_name, $this->p_mode); } } -- cgit v1.2.1 From ade496e0f7da84fb3035a811930792648a8ac442 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 22 Aug 2011 03:20:59 -0400 Subject: [feature/extension-manager] Fix whitespace in acp_modules PHPBB3-10323 --- phpBB/includes/acp/acp_modules.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 2a533056b4..367eea8e80 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -111,7 +111,7 @@ class acp_modules } break; - + case 'enable': case 'disable': if (!$module_id) @@ -170,7 +170,7 @@ class acp_modules add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name); $this->remove_cache_file(); } - + break; case 'quickadd': @@ -207,7 +207,7 @@ class acp_modules if (!sizeof($errors)) { $this->remove_cache_file(); - + trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } } @@ -231,7 +231,7 @@ class acp_modules { trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } - + $module_row = $this->get_module_row($module_id); // no break @@ -250,7 +250,7 @@ class acp_modules 'module_auth' => '', ); } - + $module_data = array(); $module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']); @@ -295,7 +295,7 @@ class acp_modules if (!sizeof($errors)) { $this->remove_cache_file(); - + trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } } @@ -327,7 +327,7 @@ class acp_modules { $s_mode_options .= ''; } - + $template->assign_block_vars('m_names.modes', array( 'OPTION' => $m_mode, 'VALUE' => $this->lang_name($m_values['title']), @@ -336,7 +336,7 @@ class acp_modules ); } } - + $s_cat_option = ''; $template->assign_vars(array_merge(array( @@ -349,7 +349,7 @@ class acp_modules 'U_EDIT_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'], - + 'MODULENAME' => $this->lang_name($module_data['module_langname']), 'ACTION' => $action, 'MODULE_ID' => $module_id, @@ -516,7 +516,7 @@ class acp_modules $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - + if (!$row) { trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); @@ -524,14 +524,14 @@ class acp_modules return $row; } - + /** * Get available module information from module files */ function get_module_infos($module = '', $module_class = false) { global $phpbb_root_path, $phpEx; - + $module_class = ($module_class === false) ? $this->module_class : $module_class; $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; @@ -742,7 +742,7 @@ class acp_modules // Sanitise for future path use, it's escaped as appropriate for queries $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class)); - + $cache->destroy('_modules_' . $p_class); // Additionally remove sql cache -- cgit v1.2.1 From d5a5cdd0d712ff7997f98659525ab98ee45fbe1f Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 22 Aug 2011 03:39:07 -0400 Subject: [feature/extension-manager] Avoid unecessary loading of acp classes PHPBB3-10323 --- phpBB/includes/acp/acp_modules.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 367eea8e80..a4e140ecfe 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -554,11 +554,13 @@ class acp_modules foreach ($modules as $module) { + $info_class = preg_replace('/_module$/', '_info', $module); + // If the class does not exist it might be following the old // format. phpbb_acp_info_acp_foo needs to be turned into // acp_foo_info and the respective file has to be included // manually because it does not support auto loading - if (!class_exists($module)) + if (!class_exists($info_class)) { $info_class = str_replace("phpbb_{$module_class}_info_", '', $module) . '_info'; if (file_exists($directory . $info_class . '.' . $phpEx)) @@ -566,10 +568,6 @@ class acp_modules include($directory . $info_class . '.' . $phpEx); } } - else - { - $info_class = preg_replace('/_module$/', '_info', $module); - } if (class_exists($info_class)) { @@ -586,7 +584,9 @@ class acp_modules } else { - if (!class_exists($module)) + $info_class = preg_replace('/_module$/', '_info', $module); + + if (!class_exists($info_class)) { if (file_exists($directory . $module . '.' . $phpEx)) { @@ -594,10 +594,6 @@ class acp_modules } $info_class = $module . '_info'; } - else - { - $info_class = preg_replace('/_module$/', '_info', $module); - } // Get module title tag if (class_exists($info_class)) -- cgit v1.2.1 From 61df8a87d19c062f5284f06047c1a9093c664cdf Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 22 Aug 2011 03:51:03 -0400 Subject: [feature/extension-manager] Allow extensions to define captcha plugins. The base class for captcha plugins has been renamed, but the old name continues to exist as an empty subclass of it for backwards compatability. PHPBB3-10323 --- phpBB/includes/acp/acp_captcha.php | 4 +- phpBB/includes/captcha/captcha_factory.php | 43 +++++++++++----------- .../includes/captcha/plugins/captcha_abstract.php | 9 ++++- 3 files changed, 32 insertions(+), 24 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index bef8ae0ea9..f051781547 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -104,13 +104,13 @@ class acp_captcha foreach ($captchas['available'] as $value => $title) { $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : ''; - $captcha_select .= ''; + $captcha_select .= ''; } foreach ($captchas['unavailable'] as $value => $title) { $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : ''; - $captcha_select .= ''; + $captcha_select .= ''; } $demo_captcha = phpbb_captcha_factory::get_instance($selected); diff --git a/phpBB/includes/captcha/captcha_factory.php b/phpBB/includes/captcha/captcha_factory.php index c2ec8c5bda..2779a23d34 100644 --- a/phpBB/includes/captcha/captcha_factory.php +++ b/phpBB/includes/captcha/captcha_factory.php @@ -59,38 +59,39 @@ class phpbb_captcha_factory */ function get_captcha_types() { - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_extension_manager; $captchas = array( 'available' => array(), 'unavailable' => array(), ); - $dp = @opendir($phpbb_root_path . 'includes/captcha/plugins'); + $finder = $phpbb_extension_manager->get_finder(); + $captcha_plugin_classes = $finder + ->directory('/captcha') + ->suffix('_plugin') + ->default_path('includes/captcha/plugins/') + ->default_directory('') + ->get_classes(); - if ($dp) + foreach ($captcha_plugin_classes as $class) { - while (($file = readdir($dp)) !== false) + // check if this class needs to be loaded in legacy mode + $old_class = preg_replace('/^phpbb_captcha_plugins_/', '', $class); + if (file_exists($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx") && !class_exists($old_class)) { - if ((preg_match('#_plugin\.' . $phpEx . '$#', $file))) - { - $name = preg_replace('#^(.*?)_plugin\.' . $phpEx . '$#', '\1', $file); - if (!class_exists($name)) - { - include($phpbb_root_path . "includes/captcha/plugins/$file"); - } + include($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx"); + $class = preg_replace('/_plugin$/', '', $old_class); + } - if (call_user_func(array($name, 'is_available'))) - { - $captchas['available'][$name] = call_user_func(array($name, 'get_name')); - } - else - { - $captchas['unavailable'][$name] = call_user_func(array($name, 'get_name')); - } - } + if (call_user_func(array($class, 'is_available'))) + { + $captchas['available'][$class] = call_user_func(array($class, 'get_name')); + } + else + { + $captchas['unavailable'][$class] = call_user_func(array($class, 'get_name')); } - closedir($dp); } return $captchas; diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php index aea39b3123..07a0ea1279 100644 --- a/phpBB/includes/captcha/plugins/captcha_abstract.php +++ b/phpBB/includes/captcha/plugins/captcha_abstract.php @@ -22,7 +22,7 @@ if (!defined('IN_PHPBB')) * * @package VC */ -class phpbb_default_captcha +class phpbb_captcha_plugins_captcha_abstract { var $confirm_id; var $confirm_code; @@ -364,3 +364,10 @@ class phpbb_default_captcha } } + +/** +* Old class name for legacy use. The new class name is auto loadable. +*/ +class phpbb_default_captcha extends phpbb_captcha_plugins_captcha_abstract +{ +} -- cgit v1.2.1 From 897063d3e269a7c11ef6d6602abc37ec30266a72 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 14:46:38 -0400 Subject: [feature/extension-manager] Add missing sql_freeresult call PHPBB3-10323 --- phpBB/includes/extension/manager.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB') diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 736c706e77..d167bc6847 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -63,6 +63,7 @@ class phpbb_extension_manager $result = $this->db->sql_query($sql); $extensions = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); $this->extensions = array(); foreach ($extensions as $extension) -- cgit v1.2.1 From c7a986eccdac183cc81b3da486092f4ab82109ba Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 17:17:40 -0400 Subject: [feature/extension-manager] Use an incremental process for enable and purge The enable or purge operation of an extension could take a long time if an expensive operation needs to be executed on a large set of data. To allow this to succeed from a web interface with max_execution_time set in the webserver's php configuration, subsequent requests must continue the operation started earlier. So individual enable and purge implementations must be able to spread their work across multiple steps. PHPBB3-10323 --- phpBB/develop/create_schema_files.php | 1 + phpBB/includes/extension/base.php | 22 +++++++- phpBB/includes/extension/interface.php | 39 +++++++++++++- phpBB/includes/extension/manager.php | 85 ++++++++++++++++++++++++++----- phpBB/install/database_update.php | 1 + phpBB/install/schemas/firebird_schema.sql | 3 +- phpBB/install/schemas/mssql_schema.sql | 3 +- phpBB/install/schemas/mysql_40_schema.sql | 1 + phpBB/install/schemas/mysql_41_schema.sql | 1 + phpBB/install/schemas/oracle_schema.sql | 1 + phpBB/install/schemas/postgres_schema.sql | 3 +- phpBB/install/schemas/sqlite_schema.sql | 3 +- 12 files changed, 141 insertions(+), 22 deletions(-) (limited to 'phpBB') diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index bc1e28572d..1828719570 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1035,6 +1035,7 @@ function get_schema_struct() 'COLUMNS' => array( 'ext_name' => array('VCHAR', ''), 'ext_active' => array('BOOL', 0), + 'ext_state' => array('TEXT', ''), ), 'KEYS' => array( 'ext_name' => array('UNIQUE', 'ext_name'), diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index 0e6c89491d..8228364d44 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -16,20 +16,38 @@ if (!defined('IN_PHPBB')) } /** +* A base class for extensions without custom enable/disbale/purge code. * * @package extension */ class phpbb_extension_base implements phpbb_extension_interface { - public function enable() + /** + * Single enable step that does nothing + * + * @return false Indicates no further steps are required + */ + public function enable_step($old_state) { + return false; } + /** + * Empty disable method + * + * @return null + */ public function disable() { } - public function purge() + /** + * Single purge step that does nothing + * + * @return false Indicates no further steps are required + */ + public function purge_step($old_state) { + return false; } } diff --git a/phpBB/includes/extension/interface.php b/phpBB/includes/extension/interface.php index 40a5a066a3..7d0ecd72c7 100644 --- a/phpBB/includes/extension/interface.php +++ b/phpBB/includes/extension/interface.php @@ -16,12 +16,47 @@ if (!defined('IN_PHPBB')) } /** +* The interface extension meta classes have to implement to run custom code +* on enable/disable/purge. * * @package extension */ interface phpbb_extension_interface { - public function enable(); + /** + * enable_step is executed on enabling an extension until it returns false. + * + * Calls to this function can be made in subsequent requests, when the + * function is invoked through a webserver with a too low max_execution_time. + * + * @param mixed $old_state The return value of the previous call + * of this method, or false on the first call + * @return mixed Returns false after last step, otherwise + * temporary state which is passed as an + * argument to the next step + */ + public function enable_step($old_state); + + /** + * Disables the extension. + * + * Must be a quick operation, that finishes within max_execution_time. + * + * @return null + */ public function disable(); - public function purge(); + + /** + * purge_step is executed on purging an extension until it returns false. + * + * Calls to this function can be made in subsequent requests, when the + * function is invoked through a webserver with a too low max_execution_time. + * + * @param mixed $old_state The return value of the previous call + * of this method, or false on the first call + * @return mixed Returns false after last step, otherwise + * temporary state which is passed as an + * argument to the next step + */ + public function purge_step($old_state); } diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index d167bc6847..a1863040d0 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -109,28 +109,34 @@ class phpbb_extension_manager } /** - * Enables an extension + * Runs a step of the extension enabling process. * - * Calls the enable method on the extension's meta class to allow it to - * make database changes and execute other initialisation code. + * Allows the exentension to enable in a long running script that works + * in multiple steps across requests. State is kept for the extension + * in the extensions table. * - * @param string $name The extension's name - * @return null + * @param string $name The extension's name + * @return bool Whether another run of enable_step is required */ - public function enable($name) + public function enable_step($name) { // ignore extensions that are already enabled if (isset($this->extensions[$name]) && $this->extensions[$name]['ext_active']) { - return; + return false; } + $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false; + $extension = $this->get_extension($name); - $extension->enable(); + $state = $extension->enable_step($old_state); + + $active = ($state === false); $extension_data = array( - 'ext_name' => $name, - 'ext_active' => true, + 'ext_name' => $name, + 'ext_active' => $active, + 'ext_state' => serialize($state), ); $this->extensions[$name] = $extension_data; @@ -148,6 +154,22 @@ class phpbb_extension_manager ' . $this->db->sql_build_array('INSERT', $extension_data); $this->db->sql_query($sql); } + + return !$active; + } + + /** + * Enables an extension + * + * This method completely enables an extension. But it could be long running + * so never call this in a script that has a max_execution time. + * + * @param string $name The extension's name + * @return null + */ + public function enable($name) + { + while ($this->enable_step($name)); } /** @@ -172,9 +194,10 @@ class phpbb_extension_manager $extension_data = array( 'ext_active' => false, + 'ext_state' => serialize(false), ); $this->extensions[$name]['ext_active'] = false; - ksort($this->extensions); + $this->extensions[$name]['ext_state'] = serialize(false); $sql = 'UPDATE ' . $this->extension_table . ' SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " @@ -191,12 +214,12 @@ class phpbb_extension_manager * @param string $name The extension's name * @return null */ - public function purge($name) + public function purge_step($name) { // ignore extensions that do not exist if (!isset($this->extensions[$name])) { - return; + return false; } // disable first if necessary @@ -205,14 +228,48 @@ class phpbb_extension_manager $this->disable($name); } + $old_state = unserialize($this->extensions[$name]['ext_state']); + $extension = $this->get_extension($name); - $extension->purge(); + $state = $extension->purge_step($old_state); + + // continue until the state is false + if ($state !== false) + { + $extension_data = array( + 'ext_state' => serialize($state), + ); + $this->extensions[$name]['ext_state'] = serialize($state); + + $sql = 'UPDATE ' . $this->extension_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " + WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + return true; + } unset($this->extensions[$name]); $sql = 'DELETE FROM ' . $this->extension_table . " WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); + + return false; + } + + /** + * Purge an extension + * + * Purges an extension completely at once. This process could run for a while + * so never call this in a script that has a max_execution time. + * + * @param string $name The extension's name + * @return null + */ + public function purge($name) + { + while ($this->purge_step($name)); } /** diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 45de19c918..9a7231040b 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1060,6 +1060,7 @@ function database_update_info() 'COLUMNS' => array( 'ext_name' => array('VCHAR', ''), 'ext_active' => array('BOOL', 0), + 'ext_state' => array('TEXT', ''), ), 'KEYS' => array( 'ext_name' => array('UNIQUE', 'ext_name'), diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 4952b6bbdf..9bebf11c4b 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -284,7 +284,8 @@ END;; # Table: 'phpbb_ext' CREATE TABLE phpbb_ext ( ext_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - ext_active INTEGER DEFAULT 0 NOT NULL + ext_active INTEGER DEFAULT 0 NOT NULL, + ext_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL );; CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext(ext_name);; diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 76f3fc6491..bf137b89f4 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -363,7 +363,8 @@ GO */ CREATE TABLE [phpbb_ext] ( [ext_name] [varchar] (255) DEFAULT ('') NOT NULL , - [ext_active] [int] DEFAULT (0) NOT NULL + [ext_active] [int] DEFAULT (0) NOT NULL , + [ext_state] [varchar] (8000) DEFAULT ('') NOT NULL ) ON [PRIMARY] GO diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index a1b282418d..54504beb1c 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -195,6 +195,7 @@ CREATE TABLE phpbb_drafts ( CREATE TABLE phpbb_ext ( ext_name varbinary(255) DEFAULT '' NOT NULL, ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + ext_state blob NOT NULL, UNIQUE ext_name (ext_name) ); diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 2f2de17dcb..139833b7b9 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -195,6 +195,7 @@ CREATE TABLE phpbb_drafts ( CREATE TABLE phpbb_ext ( ext_name varchar(255) DEFAULT '' NOT NULL, ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + ext_state text NOT NULL, UNIQUE ext_name (ext_name) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index f0a958d2f6..2f958b835b 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -413,6 +413,7 @@ END; CREATE TABLE phpbb_ext ( ext_name varchar2(255) DEFAULT '' , ext_active number(1) DEFAULT '0' NOT NULL, + ext_state clob DEFAULT '' , CONSTRAINT u_phpbb_ext_name UNIQUE (ext_name) ) / diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 956167ff39..86ee044913 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -317,7 +317,8 @@ CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); */ CREATE TABLE phpbb_ext ( ext_name varchar(255) DEFAULT '' NOT NULL, - ext_active INT2 DEFAULT '0' NOT NULL CHECK (ext_active >= 0) + ext_active INT2 DEFAULT '0' NOT NULL CHECK (ext_active >= 0), + ext_state varchar(8000) DEFAULT '' NOT NULL ); CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 223dbc3c02..94e192fc0c 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -189,7 +189,8 @@ CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); # Table: 'phpbb_ext' CREATE TABLE phpbb_ext ( ext_name varchar(255) NOT NULL DEFAULT '', - ext_active INTEGER UNSIGNED NOT NULL DEFAULT '0' + ext_active INTEGER UNSIGNED NOT NULL DEFAULT '0', + ext_state text(65535) NOT NULL DEFAULT '' ); CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); -- cgit v1.2.1 From 24ddef2230b63dd752e8b3bb33ae6b651f9e8b5e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:10:50 -0400 Subject: [feature/extension-manager] Remove 5.2 incompatible \ in front of SPL classname PHPBB-10323 --- phpBB/includes/cron/provider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/cron/provider.php b/phpBB/includes/cron/provider.php index 9936da3f55..ee0f93a308 100644 --- a/phpBB/includes/cron/provider.php +++ b/phpBB/includes/cron/provider.php @@ -22,7 +22,7 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_cron_provider implements \IteratorAggregate +class phpbb_cron_provider implements IteratorAggregate { /** * Array holding all found task class names. -- cgit v1.2.1 From 7435f344e20ae4dce875b46746f46ddc874e41f3 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:16:57 -0400 Subject: [feature/extension-manager] Add docblocks for query members of extension finder PHPBB3-10323 --- phpBB/includes/extension/finder.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index fbc8a3aefb..b3cdbd6ab9 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -27,7 +27,16 @@ class phpbb_extension_finder protected $cache; protected $phpEx; + /** + * @var array An associative array, containing all search parameters set in + * methods + */ protected $query; + + /** + * @var array A map from md5 hashes of serialized queries to their + * previously retrieved results. + */ protected $cached_queries; /** -- cgit v1.2.1 From 34f11a1039745ee1de48f1818f781ae1ee2b85ac Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:24:15 -0400 Subject: [feature/extension-manager] Correct usage of false cache return value PHPBB3-10323 --- phpBB/includes/extension/finder.php | 5 +++++ phpBB/includes/extension/manager.php | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index b3cdbd6ab9..d25823ca43 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -283,6 +283,11 @@ class phpbb_extension_finder if ($cache && $this->cache) { + if ($this->cached_queries === false) + { + $this->cached_queries = array(); + } + $this->cached_queries[$query] = $files; $this->cache->put('_extension_finder', $this->cached_queries); } diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index a1863040d0..e1e7571573 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -45,7 +45,9 @@ class phpbb_extension_manager $this->phpEx = $phpEx; $this->extension_table = $extension_table; - if (false === ($this->extensions = $this->cache->get('_extensions'))) + $this->extensions = $this->cache->get('_extensions'); + + if ($this->extensions === false) { $this->load_extensions(); } -- cgit v1.2.1 From 64827a6623c9a916d41c2ef5bf2c2092a3008722 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:43:45 -0400 Subject: [feature/extension-manager] Test creation of new extension finder cache PHPBB3-10323 --- phpBB/includes/extension/finder.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index d25823ca43..b3cdbd6ab9 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -283,11 +283,6 @@ class phpbb_extension_finder if ($cache && $this->cache) { - if ($this->cached_queries === false) - { - $this->cached_queries = array(); - } - $this->cached_queries[$query] = $files; $this->cache->put('_extension_finder', $this->cached_queries); } -- cgit v1.2.1 From bd1366d62d018c6b71ea24b1f9915d89d4a240a5 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:44:43 -0400 Subject: [feature/extension-manager] Use _ext for cache - avoids conflict with file ext PHPBB3-10323 --- phpBB/includes/extension/finder.php | 4 ++-- phpBB/includes/extension/manager.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index b3cdbd6ab9..7ba477582c 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -66,7 +66,7 @@ class phpbb_extension_finder 'directory' => false, ); - $this->cached_queries = ($this->cache) ? $this->cache->get('_extension_finder') : false; + $this->cached_queries = ($this->cache) ? $this->cache->get('_ext_finder') : false; } /** @@ -284,7 +284,7 @@ class phpbb_extension_finder if ($cache && $this->cache) { $this->cached_queries[$query] = $files; - $this->cache->put('_extension_finder', $this->cached_queries); + $this->cache->put('_ext_finder', $this->cached_queries); } return $files; diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index e1e7571573..45250e623a 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -45,7 +45,7 @@ class phpbb_extension_manager $this->phpEx = $phpEx; $this->extension_table = $extension_table; - $this->extensions = $this->cache->get('_extensions'); + $this->extensions = $this->cache->get('_ext'); if ($this->extensions === false) { @@ -75,7 +75,7 @@ class phpbb_extension_manager } ksort($this->extensions); - $this->cache->put('_extensions', $this->extensions); + $this->cache->put('_ext', $this->extensions); } /** -- cgit v1.2.1 From 739e9eb58e7e9b899955b714aa3fc8bbe6a30ebc Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 18:57:21 -0400 Subject: [feature/extension-manager] Make the cache variable name for extensions dynamic Allows multiple instances to use cache simultaneously. PHPBB3-10323 --- phpBB/includes/extension/finder.php | 10 +++++++--- phpBB/includes/extension/manager.php | 11 +++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 7ba477582c..e94a94c733 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -26,6 +26,7 @@ class phpbb_extension_finder protected $phpbb_root_path; protected $cache; protected $phpEx; + protected $cache_name; /** * @var array An associative array, containing all search parameters set in @@ -48,13 +49,16 @@ class phpbb_extension_finder * @param string $phpbb_root_path Path to the phpbb root directory * @param phpbb_cache_driver_interface $cache A cache instance or null * @param string $phpEx php file extension + * @param string $cache_name The name of the cache variable, defaults to + * _ext_finder */ - public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $phpEx = '.php') + public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $phpEx = '.php', $cache_name = '_ext_finder') { $this->extension_manager = $extension_manager; $this->phpbb_root_path = $phpbb_root_path; $this->cache = $cache; $this->phpEx = $phpEx; + $this->cache_name = $cache_name; $this->query = array( 'default_path' => false, @@ -66,7 +70,7 @@ class phpbb_extension_finder 'directory' => false, ); - $this->cached_queries = ($this->cache) ? $this->cache->get('_ext_finder') : false; + $this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false; } /** @@ -284,7 +288,7 @@ class phpbb_extension_finder if ($cache && $this->cache) { $this->cached_queries[$query] = $files; - $this->cache->put('_ext_finder', $this->cached_queries); + $this->cache->put($this->cache_name, $this->cached_queries); } return $files; diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 45250e623a..443eaf011b 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -27,6 +27,7 @@ class phpbb_extension_manager protected $extensions; protected $extension_table; protected $phpbb_root_path; + protected $cache_name; /** * Creates a manager and loads information from database @@ -36,16 +37,18 @@ class phpbb_extension_manager * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $phpEx php file extension * @param phpbb_cache_driver_interface $cache A cache instance or null + * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(dbal $db, $extension_table, $phpbb_root_path, $phpEx = '.php', phpbb_cache_driver_interface $cache = null) + public function __construct(dbal $db, $extension_table, $phpbb_root_path, $phpEx = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') { $this->phpbb_root_path = $phpbb_root_path; $this->db = $db; $this->cache = $cache; $this->phpEx = $phpEx; $this->extension_table = $extension_table; + $this->cache_name = $cache_name; - $this->extensions = $this->cache->get('_ext'); + $this->extensions = $this->cache->get($this->cache_name); if ($this->extensions === false) { @@ -75,7 +78,7 @@ class phpbb_extension_manager } ksort($this->extensions); - $this->cache->put('_ext', $this->extensions); + $this->cache->put($this->cache_name, $this->extensions); } /** @@ -356,6 +359,6 @@ class phpbb_extension_manager */ public function get_finder() { - return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx); + return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx, $this->cache_name . '_finder'); } } -- cgit v1.2.1 From 48391d2dde8f40e3c7e7d4a41b8ff1c32508ffc1 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 20:05:46 -0400 Subject: [feature/extension-manager] Create an extension manager on update and install It's required when adding modules PHPBB3-10323 --- phpBB/install/database_update.php | 8 +++++++- phpBB/install/install_install.php | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'phpBB') diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 9a7231040b..2635396af0 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -678,7 +678,13 @@ function _write_result($no_updates, $errored, $error_ary) function _add_modules($modules_to_install) { - global $phpbb_root_path, $phpEx, $db; + global $phpbb_root_path, $phpEx, $db, $phpbb_extension_manager; + + // modules require an extension manager + if (empty($phpbb_extension_manager)) + { + $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_root_path, ".$phpEx"); + } include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index f8c54678bf..c6b315ae6c 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1483,7 +1483,13 @@ class install_install extends module */ function add_modules($mode, $sub) { - global $db, $lang, $phpbb_root_path, $phpEx; + global $db, $lang, $phpbb_root_path, $phpEx, $phpbb_extension_manager; + + // modules require an extension manager + if (empty($phpbb_extension_manager)) + { + $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_root_path, ".$phpEx"); + } include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); -- cgit v1.2.1 From 018a8359974273b65a3e6bd8aeca75396fd36a5b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 20:06:17 -0400 Subject: [feature/extension-manager] The default fulltext native backend was renamed This was done to make it autoloadable. PHPBB3-10323 --- phpBB/install/install_install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index c6b315ae6c..5ea3525edd 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1465,7 +1465,7 @@ class install_install extends module set_config_count(null, null, null, $config); $error = false; - $search = new fulltext_native($error); + $search = new phpbb_search_fulltext_native($error); $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id FROM ' . POSTS_TABLE; -- cgit v1.2.1 From c785ef7aa7953c5e533e48b11ef13d6b1f344813 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 20:14:23 -0400 Subject: [feature/extension-manager] Make sure the extension manager works without cache Includes a test for manager without a cache PHPBB3-10323 --- phpBB/includes/extension/manager.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 443eaf011b..a6c8ebb3d0 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -48,7 +48,7 @@ class phpbb_extension_manager $this->extension_table = $extension_table; $this->cache_name = $cache_name; - $this->extensions = $this->cache->get($this->cache_name); + $this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false; if ($this->extensions === false) { @@ -78,7 +78,11 @@ class phpbb_extension_manager } ksort($this->extensions); - $this->cache->put($this->cache_name, $this->extensions); + + if ($this->cache) + { + $this->cache->put($this->cache_name, $this->extensions); + } } /** -- cgit v1.2.1 From fe4b8818ec1f448d5625534e5027cfbc1177ab9a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 20:54:42 -0400 Subject: [feature/extension-manager] Always store the full class name as module basename The updater swaps out all basenames. PHPBB3-10323 --- phpBB/includes/functions_module.php | 15 ++++++++------- phpBB/install/database_update.php | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 9 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 1a6b57794a..4d575a7e3a 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -441,18 +441,19 @@ class p_master } // new modules use the full class names, old ones are always called _, e.g. acp_board - if (!class_exists($this->p_name) && !class_exists("{$this->p_class}_$this->p_name")) + if (!class_exists($this->p_name)) { - if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx")) + if (!file_exists("$module_path/{$this->p_name}.$phpEx")) { - trigger_error("Cannot find module $module_path/{$this->p_class}_$this->p_name.$phpEx", E_USER_ERROR); + + trigger_error("Cannot find module $module_path/{$this->p_name}.$phpEx", E_USER_ERROR); } - include("$module_path/{$this->p_class}_$this->p_name.$phpEx"); + include("$module_path/{$this->p_name}.$phpEx"); - if (!class_exists("{$this->p_class}_$this->p_name")) + if (!class_exists($this->p_name)) { - trigger_error("Module file $module_path/{$this->p_class}_$this->p_name.$phpEx does not contain correct class [{$this->p_class}_$this->p_name]", E_USER_ERROR); + trigger_error("Module file $module_path/{$this->p_name}.$phpEx does not contain correct class [{$this->p_name}]", E_USER_ERROR); } } @@ -462,7 +463,7 @@ class p_master } // Create a new instance of the desired module ... - $class_name = (class_exists($this->p_name)) ? $this->p_name : "{$this->p_class}_$this->p_name"; + $class_name = $this->p_name; $this->module = new $class_name($this); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 2635396af0..221f6b1344 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2115,6 +2115,37 @@ function change_database_data(&$no_updates, $version) // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': + + // rename all module basenames to full classname + $sql = 'SELECT module_id, module_basename, module_class + FROM ' . MODULES_TABLE; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $module_id = (int) $row['module_id']; + unset($row['module_id']); + + if (!empty($row['module_basename']) && !empty($row['module_class'])) + { + // all the class names start with class name or with phpbb_ for auto loading + if (strpos($row['module_basename'], $row['module_class'] . '_') !== 0 && + strpos($row['module_basename'], 'phpbb_') !== 0) + { + $row['module_basename'] = $row['module_class'] . '_' . $row['module_basename']; + + $sql_update = $db->sql_build_array('UPDATE', $row); + + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET ' . $sql_update . ' + WHERE module_id = ' . $module_id; + _sql($sql, $errored, $error_ary); + } + } + } + + $db->sql_freeresult($result); + // try to guess the new auto loaded search class name // works for native and mysql fulltext set_config('search_type', 'phpbb_search_' . $config['search_type']); @@ -2159,14 +2190,14 @@ function change_database_data(&$no_updates, $version) // Install modules $modules_to_install = array( 'position' => array( - 'base' => 'groups', + 'base' => 'acp_groups', 'class' => 'acp', 'title' => 'ACP_GROUPS_POSITION', 'auth' => 'acl_a_group', 'cat' => 'ACP_GROUPS', ), 'manage' => array( - 'base' => 'attachments', + 'base' => 'acp_attachments', 'class' => 'acp', 'title' => 'ACP_MANAGE_ATTACHMENTS', 'auth' => 'acl_a_attach', -- cgit v1.2.1 From 0ea4de41711e1b4be601d01882ff52011cf9bf48 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 22:21:20 -0400 Subject: [feature/extension-manager] Add support for directories to the extension finder PHPBB3-10323 --- phpBB/includes/extension/finder.php | 51 ++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index e94a94c733..bcdcc61d76 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -216,14 +216,38 @@ class phpbb_extension_finder return $classes; } + /** + * Finds all directories matching the configured options + * + * @param bool $cache Whether the result should be cached + * @return array An array of paths to found directories + */ + public function get_directories($cache = true) + { + return $this->find($cache, true); + } + /** * Finds all files matching the configured options. * * @param bool $cache Whether the result should be cached - * @return array An array of found class names + * @return array An array of paths to found files */ public function get_files($cache = true) { + return $this->find($cache, false); + } + + /** + * Finds all file system entries matching the configured options + * + * @param bool $cache Whether the result should be cached + * @param bool $is_dir Whether the found items should be directories + * @return array An array of paths to found items + */ + protected function find($cache = true, $is_dir = false) + { + $this->query['is_dir'] = $is_dir; $query = md5(serialize($this->query)); if (!defined('DEBUG') && $cache && isset($this->cached_queries[$query])) @@ -265,18 +289,33 @@ class phpbb_extension_finder } // match only first directory if leading slash is given - $directory_pattern = ($directory && $directory[0] === '/') ? '#^' : '#' . DIRECTORY_SEPARATOR; - $directory_pattern .= preg_quote($directory . DIRECTORY_SEPARATOR, '#') . '#'; + if ($directory === '/') + { + $directory_pattern = '^' . preg_quote(DIRECTORY_SEPARATOR, '#'); + } + else if ($directory && $directory[0] === '/') + { + $directory_pattern = '^' . preg_quote($directory . DIRECTORY_SEPARATOR, '#'); + } + else + { + $directory_pattern = preg_quote(DIRECTORY_SEPARATOR . $directory . DIRECTORY_SEPARATOR, '#'); + } + $directory_pattern = '#' . $directory_pattern . '#'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); foreach ($iterator as $file_info) { - if (!$file_info->isDir()) + if ($file_info->isDir() == $is_dir) { - $relative_path = $iterator->getInnerIterator()->getSubPathname(); + $relative_path = ($is_dir) ? $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR: + $iterator->getInnerIterator()->getSubPathname(); + + $item_name = ($is_dir) ? basename($iterator->getInnerIterator()->getSubPath()) : + $file_info->getFilename(); if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) && - (!$prefix || substr($file_info->getFilename(), 0, strlen($prefix)) === $prefix) && + (!$prefix || substr($item_name, 0, strlen($prefix)) === $prefix) && (!$directory || preg_match($directory_pattern, DIRECTORY_SEPARATOR . $relative_path))) { $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . $relative_path); -- cgit v1.2.1 From fd4259919188df2d7e4667108bf86d9bd22a8e2b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 22:32:20 -0400 Subject: [feature/extension-manager] Correct formatting of documentation PHPBB3-10323 --- phpBB/includes/extension/finder.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index bcdcc61d76..1c1f150673 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -29,14 +29,15 @@ class phpbb_extension_finder protected $cache_name; /** - * @var array An associative array, containing all search parameters set in - * methods + * An associative array, containing all search parameters set in methods. + * @var array */ protected $query; /** - * @var array A map from md5 hashes of serialized queries to their - * previously retrieved results. + * A map from md5 hashes of serialized queries to their previously retrieved + * results. + * @var array */ protected $cached_queries; -- cgit v1.2.1 From 7d16007d6a1c042389039ab9ab59c073ecd7c933 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 29 Aug 2011 22:51:15 -0400 Subject: [feature/extension-manager] Prepend the phpbb_root_path if necessary. PHPBB3-10323 --- phpBB/includes/extension/finder.php | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 1c1f150673..ee08b0a82a 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -205,7 +205,7 @@ class phpbb_extension_finder $this->query['suffix'] .= $this->phpEx; $this->query['default_suffix'] .= $this->phpEx; - $files = $this->get_files($cache); + $files = $this->find($cache, false); $classes = array(); foreach ($files as $file) @@ -225,7 +225,7 @@ class phpbb_extension_finder */ public function get_directories($cache = true) { - return $this->find($cache, true); + return $this->find_with_root_path($cache, true); } /** @@ -236,7 +236,27 @@ class phpbb_extension_finder */ public function get_files($cache = true) { - return $this->find($cache, false); + return $this->find_with_root_path($cache, false); + } + + /** + * A wrapper around the general find which prepends a root path to results + * + * @param bool $cache Whether the result should be cached + * @param bool $is_dir Whether the found items should be directories + * @return array An array of paths to found items + */ + protected function find_with_root_path($cache = true, $is_dir = false) + { + $items = $this->find($cache, $is_dir); + + $result = array(); + foreach ($items as $item) + { + $result[] = $this->phpbb_root_path . $item; + } + + return $result; } /** -- cgit v1.2.1 From 6c6a7d7992460e301615bcc1e13bee92ecc65724 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 30 Aug 2011 00:06:15 -0400 Subject: [feature/extension-manager] Extract extension provider functionality from cron PHPBB3-10323 --- phpBB/includes/cron/provider.php | 50 +++------------------------ phpBB/includes/extension/provider.php | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 46 deletions(-) create mode 100644 phpBB/includes/extension/provider.php (limited to 'phpBB') diff --git a/phpBB/includes/cron/provider.php b/phpBB/includes/cron/provider.php index ee0f93a308..42552e1d8e 100644 --- a/phpBB/includes/cron/provider.php +++ b/phpBB/includes/cron/provider.php @@ -22,52 +22,20 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_cron_provider implements IteratorAggregate +class phpbb_cron_provider extends phpbb_extension_provider { - /** - * Array holding all found task class names. - * - * @var array - */ - protected $task_names = array(); - - /** - * An extension manager to search for cron tasks in extensions. - * @var phpbb_extension_manager - */ - protected $extension_manager; - - /** - * Constructor. Loads all available tasks. - * - * Tasks will be looked up in the core task directory located in - * includes/cron/task/core/ and in extensions. Task classes will be - * autoloaded and must be named according to autoloading naming conventions. - * - * Tasks in extensions must be located in a directory called cron or a subdir - * of a directory called cron. The class and filename must end in a _task - * suffix. - * - * @param phpbb_extension_manager $extension_manager phpBB extension manager - */ - public function __construct(phpbb_extension_manager $extension_manager) - { - $this->extension_manager = $extension_manager; - - $this->task_names = $this->find_cron_task_names(); - } - /** * Finds cron task names using the extension manager. * * All PHP files in includes/cron/task/core/ are considered tasks. Tasks * in extensions have to be located in a directory called cron or a subdir * of a directory called cron. The class and filename must end in a _task - * suffix. + * suffix. Additionally all PHP files in includes/cron/task/core/ are + * tasks. * * @return array List of task names */ - public function find_cron_task_names() + public function find() { $finder = $this->extension_manager->get_finder(); @@ -79,14 +47,4 @@ class phpbb_cron_provider implements IteratorAggregate ->default_directory('') ->get_classes(); } - - /** - * Retrieve an iterator over all task names - * - * @return ArrayIterator An iterator for the array of task names - */ - public function getIterator() - { - return new ArrayIterator($this->task_names); - } } diff --git a/phpBB/includes/extension/provider.php b/phpBB/includes/extension/provider.php new file mode 100644 index 0000000000..9b5ec56d30 --- /dev/null +++ b/phpBB/includes/extension/provider.php @@ -0,0 +1,65 @@ +extension_manager = $extension_manager; + + $this->items = $this->find(); + } + + /** + * Finds template paths using the extension manager. + * + * @return array List of task names + */ + abstract function find(); + + /** + * Retrieve an iterator over all items + * + * @return ArrayIterator An iterator for the array of template paths + */ + public function getIterator() + { + return new ArrayIterator($this->items); + } +} -- cgit v1.2.1 From 6ea6d50ccb9607429486a01d3144c7d32322e1b5 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 30 Aug 2011 01:15:43 -0400 Subject: [feature/extension-manager] Don't cache the phpbb_root_path in the ext manager Otherwise the paths are incorrect from e.g. adm/ PHPBB3-10323 --- phpBB/includes/extension/finder.php | 2 ++ phpBB/includes/extension/manager.php | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index ee08b0a82a..9a0727a50c 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -161,6 +161,8 @@ class phpbb_extension_finder */ public function directory($directory) { + $directory = preg_replace('#(?:^|/)\./#', '/', $directory); + if (strlen($directory) > 1 && $directory[strlen($directory) - 1] === '/') { $directory = substr($directory, 0, -1); diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index a6c8ebb3d0..ef714638c3 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -93,7 +93,7 @@ class phpbb_extension_manager */ public function get_extension_path($name) { - return $this->phpbb_root_path . 'ext/' . basename($name) . '/'; + return 'ext/' . basename($name) . '/'; } /** @@ -315,7 +315,13 @@ class phpbb_extension_manager */ public function all_configured() { - return $this->extensions; + $configured = array(); + foreach ($this->extensions as $name => $data) + { + $data['ext_path'] = $this->phpbb_root_path . $data['ext_path']; + $configured[$name] = $data; + } + return $configured; } /** @@ -331,7 +337,7 @@ class phpbb_extension_manager { if ($data['ext_active']) { - $enabled[$name] = $data['ext_path']; + $enabled[$name] = $this->phpbb_root_path . $data['ext_path']; } } return $enabled; @@ -350,7 +356,7 @@ class phpbb_extension_manager { if (!$data['ext_active']) { - $disabled[$name] = $data['ext_path']; + $disabled[$name] = $this->phpbb_root_path . $data['ext_path']; } } return $disabled; -- cgit v1.2.1 From ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 30 Aug 2011 01:32:11 -0400 Subject: [feature/extension-manager] Add support for templates in extensions. This commit adds a template path provider to separate the process of locating (cached) paths in extensions from the template engine. The locator is supplied with a list of paths from the path provider. Admin templates can now be created in ext//adm/style/ and regular templates go into ext//styles/