diff options
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acp/acp_extensions.php | 28 | ||||
-rw-r--r-- | phpBB/includes/db/db_tools.php | 2 | ||||
-rw-r--r-- | phpBB/includes/db/migration/data/310/remove_msnm.php | 43 | ||||
-rw-r--r-- | phpBB/includes/db/migration/exception.php | 24 | ||||
-rw-r--r-- | phpBB/includes/db/migration/tool/config.php | 2 | ||||
-rw-r--r-- | phpBB/includes/db/migration/tool/module.php | 6 | ||||
-rw-r--r-- | phpBB/includes/db/migration/tool/permission.php | 6 | ||||
-rw-r--r-- | phpBB/includes/db/migrator.php | 16 | ||||
-rw-r--r-- | phpBB/includes/extension/base.php | 15 | ||||
-rw-r--r-- | phpBB/includes/extension/manager.php | 81 | ||||
-rw-r--r-- | phpBB/includes/search/base.php | 15 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_mysql.php | 56 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_native.php | 51 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_postgres.php | 48 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_sphinx.php | 27 | ||||
-rw-r--r-- | phpBB/includes/session.php | 2 |
16 files changed, 315 insertions, 107 deletions
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index a0bcf62ecc..24211196bd 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -37,7 +37,7 @@ class acp_extensions $this->template = $template; $this->user = $user; - $user->add_lang(array('install', 'acp/extensions')); + $user->add_lang(array('install', 'acp/extensions', 'migrator')); $this->page_title = 'ACP_EXTENSIONS'; @@ -103,11 +103,18 @@ class acp_extensions trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); } - if ($phpbb_extension_manager->enable_step($ext_name)) + try { - $template->assign_var('S_NEXT_STEP', true); + if ($phpbb_extension_manager->enable_step($ext_name)) + { + $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + } + } + catch (phpbb_db_migration_exception $e) + { + $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); } $this->tpl_name = 'acp_ext_enable'; @@ -156,11 +163,18 @@ class acp_extensions break; case 'purge': - if ($phpbb_extension_manager->purge_step($ext_name)) + try { - $template->assign_var('S_NEXT_STEP', true); + if ($phpbb_extension_manager->purge_step($ext_name)) + { + $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + } + } + catch (phpbb_db_migration_exception $e) + { + $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); } $this->tpl_name = 'acp_ext_purge'; diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index e8c26fa502..983cdc18ea 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -303,7 +303,7 @@ class phpbb_db_tools * @param phpbb_db_driver $db Database connection * @param bool $return_statements True if only statements should be returned and no SQL being executed */ - function phpbb_db_tools(&$db, $return_statements = false) + function phpbb_db_tools(phpbb_db_driver $db, $return_statements = false) { $this->db = $db; $this->return_statements = $return_statements; diff --git a/phpBB/includes/db/migration/data/310/remove_msnm.php b/phpBB/includes/db/migration/data/310/remove_msnm.php deleted file mode 100644 index 521161df6b..0000000000 --- a/phpBB/includes/db/migration/data/310/remove_msnm.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** -* -* @package migration -* @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 -* -*/ - -class phpbb_db_migration_data_310_remove_msnm extends phpbb_db_migration -{ - public function effectively_installed() - { - return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_msnm'); - } - - static public function depends_on() - { - return array('phpbb_db_migration_data_30x_3_0_11'); - } - - public function update_schema() - { - return array( - 'drop_columns' => array( - $this->table_prefix . 'users' => array( - 'user_msnm', - ), - ), - ); - } - - public function revert_schema() - { - return array( - 'add_columns' => array( - $this->table_prefix . 'users' => array( - 'user_msnm' => array('VCHAR_UNI', ''), - ), - ), - ); - } -} diff --git a/phpBB/includes/db/migration/exception.php b/phpBB/includes/db/migration/exception.php index ffdcd97780..e84330dd71 100644 --- a/phpBB/includes/db/migration/exception.php +++ b/phpBB/includes/db/migration/exception.php @@ -52,4 +52,28 @@ class phpbb_db_migration_exception extends \Exception { return $this->message . ': ' . var_export($this->parameters, true); } + + /** + * Get the parameters + * + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Get localised message (with $user->lang()) + * + * @param phpbb_user $user + * @return string + */ + public function getLocalisedMessage(phpbb_user $user) + { + $parameters = $this->getParameters(); + array_unshift($parameters, $this->getMessage()); + + return call_user_func_array(array($user, 'lang'), $parameters); + } } diff --git a/phpBB/includes/db/migration/tool/config.php b/phpBB/includes/db/migration/tool/config.php index d9cc20053e..458a25fb66 100644 --- a/phpBB/includes/db/migration/tool/config.php +++ b/phpBB/includes/db/migration/tool/config.php @@ -49,7 +49,7 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac { if (isset($this->config[$config_name])) { - throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXISTS', $config_name); + throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXIST', $config_name); } $this->config->set($config_name, $config_value, !$is_dynamic); diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php index afe1f21ec5..4d7fae2bb0 100644 --- a/phpBB/includes/db/migration/tool/module.php +++ b/phpBB/includes/db/migration/tool/module.php @@ -242,14 +242,14 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if (!$module_id) { - throw new phpbb_db_migration_exception('MODULE_PARENT_NOT_EXIST', $parent); + throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', $parent); } $parent = $data['parent_id'] = $module_id; } else if (!$this->exists($class, false, $parent)) { - throw new phpbb_db_migration_exception('MODULE_PARENT_NOT_EXIST', $parent); + throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', $parent); } if ($this->exists($class, $parent, $data['module_langname'])) @@ -477,7 +477,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $result = $acp_modules->delete_module($module_id); if (!empty($result)) { - throw new phpbb_db_migration_exception('CANNOT_REMOVE_MODULE', $module_id); + throw new phpbb_db_migration_exception('MODULE_NOT_REMOVABLE', $module_id, $result); } } diff --git a/phpBB/includes/db/migration/tool/permission.php b/phpBB/includes/db/migration/tool/permission.php index 001d090f5a..4231fbe1dd 100644 --- a/phpBB/includes/db/migration/tool/permission.php +++ b/phpBB/includes/db/migration/tool/permission.php @@ -107,7 +107,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte { if ($this->exists($auth_option, $global)) { - throw new phpbb_db_migration_exception('PERMISSION_ALREADY_EXISTS', $auth_option); + throw new phpbb_db_migration_exception('PERMISSION_ALREADY_EXIST', $auth_option); } // We've added permissions, so set to true to notify the user. @@ -252,7 +252,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte if ($role_id) { - throw new phpbb_db_migration_exception('ROLE_ALREADY_EXISTS', $old_role_name); + return; } $sql = 'SELECT MAX(role_order) AS max_role_order @@ -290,7 +290,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte if (!$role_id) { - throw new phpbb_db_migration_exception('ROLE_NOT_EXISTS', $old_role_name); + throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $old_role_name); } $sql = 'UPDATE ' . ACL_ROLES_TABLE . " diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 4456600b0a..41d996b1e3 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -228,9 +228,10 @@ class phpbb_db_migrator { foreach ($this->migrations as $name) { - if ($this->unfulfillable($name)) + $unfulfillable = $this->unfulfillable($name); + if ($unfulfillable !== false) { - throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name); + throw new phpbb_db_migration_exception('MIGRATION_NOT_FULFILLABLE', $name, $unfulfillable); } } } @@ -674,7 +675,7 @@ class phpbb_db_migrator * Checks if a migration's dependencies can even theoretically be satisfied. * * @param string $name The class name of the migration - * @return bool Whether the migration cannot be fulfilled + * @return bool|string False if fulfillable, string of missing migration name if unfulfillable */ public function unfulfillable($name) { @@ -685,7 +686,7 @@ class phpbb_db_migrator if (!class_exists($name)) { - return true; + return $name; } $migration = $this->get_migration($name); @@ -693,9 +694,10 @@ class phpbb_db_migrator foreach ($depends as $depend) { - if ($this->unfulfillable($depend)) + $unfulfillable = $this->unfulfillable($depend); + if ($unfulfillable !== false) { - return true; + return $unfulfillable; } } @@ -715,7 +717,7 @@ class phpbb_db_migrator { // skip unfulfillable migrations, but fulfillables mean we // are not finished yet - if ($this->unfulfillable($name)) + if ($this->unfulfillable($name) !== false) { continue; } diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index 9d076eb6c5..d51589d719 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -15,6 +15,8 @@ if (!defined('IN_PHPBB')) exit; } +use Symfony\Component\DependencyInjection\ContainerInterface; + /** * A base class for extensions without custom enable/disable/purge code. * @@ -22,6 +24,19 @@ if (!defined('IN_PHPBB')) */ class phpbb_extension_base implements phpbb_extension_interface { + /** @var ContainerInterface */ + protected $container; + + /** + * Constructor + * + * @param ContainerInterface $container Container object + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + /** * Single enable step that does nothing * diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index de6f364320..21a9ec1370 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -15,6 +15,8 @@ if (!defined('IN_PHPBB')) exit; } +use Symfony\Component\DependencyInjection\ContainerInterface; + /** * The extension manager provides means to activate/deactivate extensions. * @@ -22,8 +24,12 @@ if (!defined('IN_PHPBB')) */ class phpbb_extension_manager { + /** @var ContainerInterface */ + protected $container; + protected $db; protected $config; + protected $migrator; protected $cache; protected $php_ext; protected $extensions; @@ -34,6 +40,7 @@ class phpbb_extension_manager /** * Creates a manager and loads information from database * + * @param ContainerInterface $container A container * @param phpbb_db_driver $db A database connection * @param phpbb_config $config phpbb_config * @param string $extension_table The name of the table holding extensions @@ -42,11 +49,13 @@ class phpbb_extension_manager * @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(phpbb_db_driver $db, phpbb_config $config, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') { + $this->container = $container; $this->phpbb_root_path = $phpbb_root_path; $this->db = $db; $this->config = $config; + $this->migrator = $migrator; $this->cache = $cache; $this->php_ext = $php_ext; $this->extension_table = $extension_table; @@ -126,11 +135,11 @@ class phpbb_extension_manager if (class_exists($extension_class_name)) { - return new $extension_class_name; + return new $extension_class_name($this->container); } else { - return new phpbb_extension_base; + return new phpbb_extension_base($this->container); } } @@ -166,6 +175,12 @@ class phpbb_extension_manager $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false; + // Returns false if not completed + if (!$this->handle_migrations($name, 'enable')) + { + return true; + } + $extension = $this->get_extension($name); $state = $extension->enable_step($old_state); @@ -317,6 +332,12 @@ class phpbb_extension_manager $old_state = unserialize($this->extensions[$name]['ext_state']); + // Returns false if not completed + if (!$this->handle_migrations($name, 'purge')) + { + return true; + } + $extension = $this->get_extension($name); $state = $extension->purge_step($old_state); @@ -490,4 +511,58 @@ class phpbb_extension_manager { return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); } + + /** + * Handle installing/reverting migrations + * + * @param string $extension_name Name of the extension + * @param string $mode enable or purge + * @return bool True if completed, False if not completed + */ + protected function handle_migrations($extension_name, $mode) + { + $migrations_path = $this->phpbb_root_path . $this->get_extension_path($extension_name) . 'migrations/'; + if (!file_exists($migrations_path) || !is_dir($migrations_path)) + { + return true; + } + + $migrations = $this->migrator->load_migrations($migrations_path); + + // What is a safe limit of execution time? Half the max execution time should be safe. + $safe_time_limit = (ini_get('max_execution_time') / 2); + $start_time = time(); + + if ($mode == 'enable') + { + while (!$this->migrator->finished()) + { + $this->migrator->update(); + + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $start_time) >= $safe_time_limit) + { + return false; + } + } + } + else if ($mode == 'purge') + { + foreach ($migrations as $migration) + { + while ($this->migrator->migration_state($migration) !== false) + { + $this->migrator->revert($migration); + + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $start_time) >= $safe_time_limit) + { + return false; + } + } + } + } + + return true; + } } diff --git a/phpBB/includes/search/base.php b/phpBB/includes/search/base.php index b364dead9a..914cef9167 100644 --- a/phpBB/includes/search/base.php +++ b/phpBB/includes/search/base.php @@ -94,7 +94,7 @@ class phpbb_search_base * * @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) + function obtain_ids($search_key, &$result_count, &$id_ary, &$start, $per_page, $sort_dir) { global $cache; @@ -109,6 +109,19 @@ class phpbb_search_base $reverse_ids = ($stored_ids[-2] != $sort_dir) ? true : false; $complete = true; + // Change start parameter in case out of bounds + if ($result_count) + { + if ($start < 0) + { + $start = 0; + } + else if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + } + } + // 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) diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 324c214e91..adaf025730 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -353,7 +353,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts if (!$this->search_query) @@ -375,6 +375,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base implode(',', $author_ary) ))); + if ($start < 0) + { + $start = 0; + } + // try reading the results from cache $result_count = 0; if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) @@ -488,16 +493,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $id_ary = array_unique($id_ary); - if (!sizeof($id_ary)) - { - return false; - } - // if the total result count is not cached yet, retrieve it from the db if (!$result_count) { - $sql = 'SELECT FOUND_ROWS() as result_count'; - $result = $this->db->sql_query($sql); + $sql_found_rows = 'SELECT FOUND_ROWS() as result_count'; + $result = $this->db->sql_query($sql_found_rows); $result_count = (int) $this->db->sql_fetchfield('result_count'); $this->db->sql_freeresult($result); @@ -507,6 +507,21 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } } + if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = (int) $row[$field]; + } + $this->db->sql_freeresult($result); + + $id_ary = array_unique($id_ary); + } + // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page $this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir); $id_ary = array_slice($id_ary, 0, (int) $per_page); @@ -533,7 +548,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No author? No posts if (!sizeof($author_ary)) @@ -557,6 +572,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $author_name, ))); + if ($start < 0) + { + $start = 0; + } + // try reading the results from cache $result_count = 0; if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) @@ -662,8 +682,8 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base // retrieve the total result count if needed if (!$result_count) { - $sql = 'SELECT FOUND_ROWS() as result_count'; - $result = $this->db->sql_query($sql); + $sql_found_rows = 'SELECT FOUND_ROWS() as result_count'; + $result = $this->db->sql_query($sql_found_rows); $result_count = (int) $this->db->sql_fetchfield('result_count'); $this->db->sql_freeresult($result); @@ -673,6 +693,20 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } } + if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = (int) $row[$field]; + } + $this->db->sql_freeresult($result); + + $id_ary = array_unique($id_ary); + } + if (sizeof($id_ary)) { $this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir); diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 53df8348ae..c9f33054fc 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -516,7 +516,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts. if (empty($this->search_query)) @@ -855,10 +855,6 @@ class phpbb_search_fulltext_native extends phpbb_search_base } $this->db->sql_freeresult($result); - if (!sizeof($id_ary)) - { - return false; - } // if we use mysql and the total result count is not cached yet, retrieve it from the db if (!$total_results && $is_mysql) @@ -867,14 +863,14 @@ class phpbb_search_fulltext_native extends phpbb_search_base $sql_array_copy = $sql_array; $sql_array_copy['SELECT'] = 'SQL_CALC_FOUND_ROWS p.post_id '; - $sql = $this->db->sql_build_query('SELECT', $sql_array_copy); + $sql_calc = $this->db->sql_build_query('SELECT', $sql_array_copy); unset($sql_array_copy); - $this->db->sql_query($sql); + $this->db->sql_query($sql_calc); $this->db->sql_freeresult($result); - $sql = 'SELECT FOUND_ROWS() as total_results'; - $result = $this->db->sql_query($sql); + $sql_count = 'SELECT FOUND_ROWS() as total_results'; + $result = $this->db->sql_query($sql_count); $total_results = (int) $this->db->sql_fetchfield('total_results'); $this->db->sql_freeresult($result); @@ -884,6 +880,20 @@ class phpbb_search_fulltext_native extends phpbb_search_base } } + if ($start >= $total_results) + { + $start = floor(($total_results - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = (int) $row[(($type == 'posts') ? 'post_id' : 'topic_id')]; + } + $this->db->sql_freeresult($result); + + } + // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page $this->save_ids($search_key, $this->search_query, $author_ary, $total_results, $id_ary, $start, $sort_dir); $id_ary = array_slice($id_ary, 0, (int) $per_page); @@ -910,7 +920,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No author? No posts if (!sizeof($author_ary)) @@ -1096,13 +1106,13 @@ class phpbb_search_fulltext_native extends phpbb_search_base if (!$total_results && $is_mysql) { // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it. - $sql = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql); + $sql_calc = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql); - $this->db->sql_query($sql); + $this->db->sql_query($sql_calc); $this->db->sql_freeresult($result); - $sql = 'SELECT FOUND_ROWS() as total_results'; - $result = $this->db->sql_query($sql); + $sql_count = 'SELECT FOUND_ROWS() as total_results'; + $result = $this->db->sql_query($sql_count); $total_results = (int) $this->db->sql_fetchfield('total_results'); $this->db->sql_freeresult($result); @@ -1112,6 +1122,19 @@ class phpbb_search_fulltext_native extends phpbb_search_base } } + if ($start >= $total_results) + { + $start = floor(($total_results - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = (int) $row[$field]; + } + $this->db->sql_freeresult($result); + } + if (sizeof($id_ary)) { $this->save_ids($search_key, '', $author_ary, $total_results, $id_ary, $start, $sort_dir); diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index 1475cc31d0..eeb628b18f 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -343,7 +343,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts if (!$this->search_query) @@ -371,6 +371,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base implode(',', $author_ary) ))); + if ($start < 0) + { + $start = 0; + } + // try reading the results from cache $result_count = 0; if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) @@ -495,11 +500,6 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $id_ary = array_unique($id_ary); - if (!sizeof($id_ary)) - { - return false; - } - // if the total result count is not cached yet, retrieve it from the db if (!$result_count) { @@ -518,6 +518,21 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $this->db->sql_transaction('commit'); + if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = $row[$field]; + } + $this->db->sql_freeresult($result); + + $id_ary = array_unique($id_ary); + } + // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page $this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir); $id_ary = array_slice($id_ary, 0, (int) $per_page); @@ -544,7 +559,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No author? No posts if (!sizeof($author_ary)) @@ -568,6 +583,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $author_name, ))); + if ($start < 0) + { + $start = 0; + } + // try reading the results from cache $result_count = 0; if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) @@ -710,6 +730,20 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $this->db->sql_transaction('commit'); + if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + + $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); + while ($row = $this->db->sql_fetchrow($result)) + { + $id_ary[] = (int) $row[$field]; + } + $this->db->sql_freeresult($result); + + $id_ary = array_unique($id_ary); + } + if (sizeof($id_ary)) { $this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir); diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php index 4bacf74f93..48445d0794 100644 --- a/phpBB/includes/search/fulltext_sphinx.php +++ b/phpBB/includes/search/fulltext_sphinx.php @@ -454,7 +454,7 @@ class phpbb_search_fulltext_sphinx * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts. if (!strlen($this->search_query) && !sizeof($author_ary)) @@ -609,6 +609,25 @@ class phpbb_search_fulltext_sphinx } } + $result_count = $result['total_found']; + + if ($start >= $result_count) + { + $start = floor(($result_count - 1) / $per_page) * $per_page; + + $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES); + $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + + // Could be connection to localhost:9312 failed (errno=111, + // msg=Connection refused) during rotate, retry if so + $retries = SPHINX_CONNECT_RETRIES; + while (!$result && (strpos($this->sphinx->GetLastError(), "errno=111,") !== false) && $retries--) + { + usleep(SPHINX_CONNECT_WAIT_TIME); + $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + } + } + $id_ary = array(); if (isset($result['matches'])) { @@ -629,8 +648,6 @@ class phpbb_search_fulltext_sphinx return false; } - $result_count = $result['total_found']; - $id_ary = array_slice($id_ary, 0, (int) $per_page); return $result_count; @@ -878,8 +895,8 @@ class phpbb_search_fulltext_sphinx <dd><input id="fulltext_sphinx_indexer_mem_limit" type="text" size="4" maxlength="10" name="config[fulltext_sphinx_indexer_mem_limit]" value="' . $this->config['fulltext_sphinx_indexer_mem_limit'] . '" /> ' . $this->user->lang['MIB'] . '</dd> </dl> <dl> - <dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</dt> - <dd>' . (($this->config_generate()) ? '<textarea readonly="readonly" rows="6">' . $this->config_file_data . '</textarea>' : $this->config_file_data) . '</dd> + <dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</span></dt> + <dd>' . (($this->config_generate()) ? '<textarea readonly="readonly" rows="6" id="sphinx_config_data">' . htmlspecialchars($this->config_file_data) . '</textarea>' : $this->config_file_data) . '</dd> <dl> '; diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index ee8a4094c7..6bc71da0c1 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -346,7 +346,7 @@ class phpbb_session $session_id = $request->variable('sid', ''); if (defined('NEED_SID') && (empty($session_id) || $this->session_id !== $session_id)) { - send_status_line(401, 'Not authorized'); + send_status_line(401, 'Unauthorized'); redirect(append_sid("{$phpbb_root_path}index.$phpEx")); } |