diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index b89c4e3779..71e9ed7a2e 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -652,16 +652,9 @@ class acp_main $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } if (!$search->index_created()) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 05ea03d446..d3ba635a16 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -206,6 +206,7 @@ function get_formatted_filesize($value, $string_only = true, $allowed_units = fa */ function still_on_time($extra_time = 15) { + // TODO: Check the bug with this, it should be possible to restart the start time static $max_execution_time, $start_time; $current_time = microtime(true); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index fa4dac7e57..27f9292ac5 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -1092,16 +1092,9 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } $search->index_remove($post_ids, $poster_ids, $forum_ids); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 770280195c..80f0e31e74 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2356,16 +2356,9 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } $search->index($mode, (int) $data_ary['post_id'], $data_ary['message'], $subject, $poster_id, (int) $data_ary['forum_id']); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index b5ad7ffc8c..7dab25074f 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1397,16 +1397,9 @@ function mcp_fork_topic($topic_ids) $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } $search_mode = 'post'; } diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index bb402b048d..8e7c0342e8 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -637,16 +637,9 @@ function change_poster(&$post_info, $userdata) $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } $search->index_remove([], [$post_info['user_id'], $userdata['user_id']], []); diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 69c7800b81..77f6bea757 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -680,16 +680,9 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } $search->index('edit', (int) $first_post_data['post_id'], $first_post_data['post_text'], $subject, (int) $first_post_data['poster_id'], (int) $first_post_data['forum_id']); diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index 85e778509e..168d7f36e1 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -147,6 +147,7 @@ $lang = array_merge($lang, array( 'CLI_REPARSER_REPARSE_SUCCESS' => 'Reparsing ended with success', 'CLI_SEARCHINDEX_SEARCH_BACKEND_NAME' => 'Backend class', + 'CLI_SEARCHINDEX_BACKEND_NOT_FOUND' => 'Search module not found', 'CLI_SEARCHINDEX_CREATE_SUCCESS' => 'Search index created successfully', 'CLI_SEARCHINDEX_CREATE_FAILURE' => 'Error creating search index', 'CLI_SEARCHINDEX_DELETE_SUCCESS' => 'Search index deleted successfully', diff --git a/phpBB/phpbb/console/command/searchindex/create.php b/phpBB/phpbb/console/command/searchindex/create.php index 410d00f625..d21e33466c 100644 --- a/phpBB/phpbb/console/command/searchindex/create.php +++ b/phpBB/phpbb/console/command/searchindex/create.php @@ -17,6 +17,7 @@ use phpbb\config\config; use phpbb\console\command\command; use phpbb\language\language; use phpbb\log\log; +use phpbb\search\exception\no_search_backend_found_exception; use phpbb\search\search_backend_factory; use phpbb\user; use Symfony\Component\Console\Input\InputArgument; @@ -70,7 +71,7 @@ class create extends command ->addArgument( 'search-backend', InputArgument::REQUIRED, - $this->user->lang('CLI_SEARCHINDEX_SEARCH_BACKEND_NAME') + $this->language->lang('CLI_SEARCHINDEX_SEARCH_BACKEND_NAME') ) ; } @@ -90,31 +91,47 @@ class create extends command $io = new SymfonyStyle($input, $output); $search_backend = $input->getArgument('search-backend'); - $search = $this->search_backend_factory->get($search_backend); - $name = $search->get_name(); + + try + { + $search = $this->search_backend_factory->get($search_backend); + $name = $search->get_name(); + } + catch (no_search_backend_found_exception $e) + { + $io->error($this->language->lang('CLI_SEARCHINDEX_BACKEND_NOT_FOUND', $search_backend)); + return command::FAILURE; + } try { $counter = 0; + + $progress = $this->create_progress_bar(1, $io, $output, true); + $progress->start(); + while (($status = $search->create_index($counter)) !== null) { - $this->config->set('search_indexing_state', implode(',', $this->state), true); + $progress->setMaxSteps($status['max_post_id']); + $progress->setProgress($status['post_counter']); + $progress->setMessage(round($status['rows_per_second'], 2) . ' rows/s'); - $io->success($counter); - $io->success(print_r($status, 1)); + $progress->advance(); } - $search->tidy(); + $progress->finish(); + + $io->newLine(2); } catch (\Exception $e) { - $io->error($this->user->lang('CLI_SEARCHINDEX_CREATE_FAILURE', $name)); - return 1; + $io->error($this->language->lang('CLI_SEARCHINDEX_CREATE_FAILURE', $name)); + return command::FAILURE; } $this->log->add('admin', ANONYMOUS, '', 'LOG_SEARCH_INDEX_CREATED', false, array($name)); - $io->success($this->user->lang('CLI_SEARCHINDEX_CREATE_SUCCESS', $name)); + $io->success($this->language->lang('CLI_SEARCHINDEX_CREATE_SUCCESS', $name)); - return 0; + return command::SUCCESS; } } diff --git a/phpBB/phpbb/console/command/searchindex/delete.php b/phpBB/phpbb/console/command/searchindex/delete.php index 927376902c..eff25bb475 100644 --- a/phpBB/phpbb/console/command/searchindex/delete.php +++ b/phpBB/phpbb/console/command/searchindex/delete.php @@ -17,6 +17,7 @@ use phpbb\config\config; use phpbb\console\command\command; use phpbb\language\language; use phpbb\log\log; +use phpbb\search\exception\no_search_backend_found_exception; use phpbb\search\search_backend_factory; use phpbb\user; use Symfony\Component\Console\Input\InputArgument; @@ -70,7 +71,7 @@ class delete extends command ->addArgument( 'search-backend', InputArgument::REQUIRED, - $this->user->lang('CLI_SEARCHINDEX_SEARCH_BACKEND_NAME') + $this->language->lang('CLI_SEARCHINDEX_SEARCH_BACKEND_NAME') ) ; } @@ -90,40 +91,32 @@ class delete extends command $io = new SymfonyStyle($input, $output); $search_backend = $input->getArgument('search-backend'); - $search = $this->search_backend_factory->get($search_backend); - $name = $search->get_name(); try { - $this->state = explode(',', $this->config['search_indexing_state']); - $this->max_post_id = $this->get_max_post_id(); + $search = $this->search_backend_factory->get($search_backend); + $name = $search->get_name(); + } + catch (no_search_backend_found_exception $e) + { + $io->error($this->language->lang('CLI_SEARCHINDEX_BACKEND_NOT_FOUND', $search_backend)); + return command::FAILURE; + } + try + { $search->delete_index($this, ''); $search->tidy(); } catch (\Exception $e) { - $io->error($this->user->lang('CLI_SEARCHINDEX_DELETE_FAILURE', $name)); - return 1; + $io->error($this->language->lang('CLI_SEARCHINDEX_DELETE_FAILURE', $name)); + return command::FAILURE; } $this->log->add('admin', ANONYMOUS, '', 'LOG_SEARCH_INDEX_REMOVED', false, array($name)); - $io->success($this->user->lang('CLI_SEARCHINDEX_DELETE_SUCCESS', $name)); + $io->success($this->language->lang('CLI_SEARCHINDEX_DELETE_SUCCESS', $name)); - return 0; - } - - function save_state($state = false) - { - global $config; - - if ($state) - { - $this->state = $state; - } - - ksort($this->state); - - $config->set('search_indexing_state', implode(',', $this->state), true); + return command::SUCCESS; } } diff --git a/phpBB/phpbb/search/backend/base.php b/phpBB/phpbb/search/backend/base.php index 4003e102ef..4b8ff6ebc5 100644 --- a/phpBB/phpbb/search/backend/base.php +++ b/phpBB/phpbb/search/backend/base.php @@ -1,15 +1,15 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\search\backend; @@ -19,9 +19,9 @@ use phpbb\db\driver\driver_interface; use phpbb\user; /** -* optional base class for search plugins providing simple caching based on ACM -* and functions to retrieve ignore_words and synonyms -*/ + * optional base class for search plugins providing simple caching based on ACM + * and functions to retrieve ignore_words and synonyms + */ abstract class base implements search_backend_interface { public const SEARCH_RESULT_NOT_IN_CACHE = 0; @@ -348,8 +348,17 @@ abstract class base implements search_backend_interface $row_count++; $post_counter = $row['post_id']; } + + // With cli process only one batch each time to be able to track progress + if (PHP_SAPI === 'cli') + { + break; + } } + // TODO: With cli if the previous bucle have stoped because of lack of time, launch an exception, because is an error + // cli commands should be executed in one step + // pretend the number of posts was as big as the number of ids we indexed so far // just an estimation as it includes deleted posts $num_posts = $this->config['num_posts']; @@ -399,6 +408,12 @@ abstract class base implements search_backend_interface $this->index_remove($ids, $posters, $forum_ids); $post_counter = $ids[count($ids) - 1]; } + + // With cli process only one batch each time to be able to track progress + if (PHP_SAPI === 'cli') + { + break; + } } if ($post_counter < $max_post_id) diff --git a/phpBB/phpbb/search/exception/no_search_backend_found_exception.php b/phpBB/phpbb/search/exception/no_search_backend_found_exception.php new file mode 100644 index 0000000000..237677db23 --- /dev/null +++ b/phpBB/phpbb/search/exception/no_search_backend_found_exception.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\search\exception; + +class no_search_backend_found_exception extends search_exception +{ + +} \ No newline at end of file diff --git a/phpBB/phpbb/search/exception/search_exception.php b/phpBB/phpbb/search/exception/search_exception.php new file mode 100644 index 0000000000..c63a679431 --- /dev/null +++ b/phpBB/phpbb/search/exception/search_exception.php @@ -0,0 +1,21 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\search\exception; + +use phpbb\exception\runtime_exception; + +class search_exception extends runtime_exception +{ + // TODO: Launch this exception from search instead of RuntimeException +} \ No newline at end of file diff --git a/phpBB/phpbb/search/search_backend_factory.php b/phpBB/phpbb/search/search_backend_factory.php index eac31885ed..deabbdaba7 100644 --- a/phpBB/phpbb/search/search_backend_factory.php +++ b/phpBB/phpbb/search/search_backend_factory.php @@ -16,6 +16,8 @@ namespace phpbb\search; use phpbb\config\config; use phpbb\di\service_collection; use phpbb\search\backend\search_backend_interface; +use phpbb\search\exception\no_search_backend_found_exception; +use RuntimeException; class search_backend_factory { @@ -46,16 +48,36 @@ class search_backend_factory * * @param string $class * + * @throws no_search_backend_found_exception + * * @return search_backend_interface */ public function get(string $class): search_backend_interface { - return $this->search_backends->get_by_class($class); + try + { + $search = $this->search_backends->get_by_class($class); + } + catch (RuntimeException $e) + { + if (strpos($e->getMessage(), 'No service found') === 0) + { + throw new no_search_backend_found_exception(); + } + else + { + throw $e; + } + } + + return $search; } /** * Obtains active search backend * + * @throws no_search_backend_found_exception + * * @return search_backend_interface */ public function get_active(): search_backend_interface diff --git a/phpBB/search.php b/phpBB/search.php index f786964620..68325bda7f 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -299,16 +299,9 @@ if ($keywords || $author || $author_id || $search_id || $submit) $search_backend_factory = $phpbb_container->get('search.backend_factory'); $search = $search_backend_factory->get_active(); } - catch (RuntimeException $e) + catch (\phpbb\search\exception\no_search_backend_found_exception $e) { - if (strpos($e->getMessage(), 'No service found') === 0) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } - else - { - throw $e; - } + trigger_error('NO_SUCH_SEARCH_MODULE'); } // let the search module split up the keywords