[ Index ]

PHP Cross Reference of phpBB-3.3.10-deutsch

title

Body

[close]

/includes/acp/ -> acp_search.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  /**
  15  * @ignore
  16  */
  17  if (!defined('IN_PHPBB'))
  18  {
  19      exit;
  20  }
  21  
  22  class acp_search
  23  {
  24      var $u_action;
  25      var $state;
  26      var $search;
  27      var $max_post_id;
  28      var $batch_size = 100;
  29  
  30  	function main($id, $mode)
  31      {
  32          global $user;
  33  
  34          $user->add_lang('acp/search');
  35  
  36          // For some this may be of help...
  37          @ini_set('memory_limit', '128M');
  38  
  39          switch ($mode)
  40          {
  41              case 'settings':
  42                  $this->settings($id, $mode);
  43              break;
  44  
  45              case 'index':
  46                  $this->index($id, $mode);
  47              break;
  48          }
  49      }
  50  
  51  	function settings($id, $mode)
  52      {
  53          global $user, $template, $phpbb_log, $request;
  54          global $config, $phpbb_admin_path, $phpEx;
  55  
  56          $submit = $request->is_set_post('submit');
  57  
  58          if ($submit && !check_link_hash($request->variable('hash', ''), 'acp_search'))
  59          {
  60              trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
  61          }
  62  
  63          $search_types = $this->get_search_types();
  64  
  65          $settings = [
  66              'search_interval'                => 'float',
  67              'search_anonymous_interval'        => 'float',
  68              'load_search'                    => 'bool',
  69              'limit_search_load'                => 'float',
  70              'min_search_author_chars'        => 'integer',
  71              'max_num_search_keywords'        => 'integer',
  72              'default_search_return_chars'    => 'integer',
  73              'search_store_results'            => 'integer',
  74          ];
  75  
  76          $search = null;
  77          $error = false;
  78          $search_options = '';
  79          foreach ($search_types as $type)
  80          {
  81              if ($this->init_search($type, $search, $error))
  82              {
  83                  continue;
  84              }
  85  
  86              $name = $search->get_name();
  87  
  88              $selected = ($config['search_type'] == $type) ? ' selected="selected"' : '';
  89              $identifier = substr($type, strrpos($type, '\\') + 1);
  90              $search_options .= "<option value=\"$type\"$selected data-toggle-setting=\"#search_{$identifier}_settings\">$name</option>";
  91  
  92              if (method_exists($search, 'acp'))
  93              {
  94                  $vars = $search->acp();
  95  
  96                  if (!$submit)
  97                  {
  98                      $template->assign_block_vars('backend', array(
  99                          'NAME'            => $name,
 100                          'SETTINGS'        => $vars['tpl'],
 101                          'IDENTIFIER'    => $identifier,
 102                      ));
 103                  }
 104                  else if (is_array($vars['config']))
 105                  {
 106                      $settings = array_merge($settings, $vars['config']);
 107                  }
 108              }
 109          }
 110          unset($search);
 111          unset($error);
 112  
 113          $cfg_array = (isset($_REQUEST['config'])) ? $request->variable('config', array('' => ''), true) : array();
 114          $updated = $request->variable('updated', false);
 115  
 116          foreach ($settings as $config_name => $var_type)
 117          {
 118              if (!isset($cfg_array[$config_name]))
 119              {
 120                  continue;
 121              }
 122  
 123              // e.g. integer:4:12 (min 4, max 12)
 124              $var_type = explode(':', $var_type);
 125  
 126              $config_value = $cfg_array[$config_name];
 127              settype($config_value, $var_type[0]);
 128  
 129              if (isset($var_type[1]))
 130              {
 131                  $config_value = max($var_type[1], $config_value);
 132              }
 133  
 134              if (isset($var_type[2]))
 135              {
 136                  $config_value = min($var_type[2], $config_value);
 137              }
 138  
 139              // only change config if anything was actually changed
 140              if ($submit && ($config[$config_name] != $config_value))
 141              {
 142                  $config->set($config_name, $config_value);
 143                  $updated = true;
 144              }
 145          }
 146  
 147          if ($submit)
 148          {
 149              $extra_message = '';
 150              if ($updated)
 151              {
 152                  $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_SEARCH');
 153              }
 154  
 155              if (isset($cfg_array['search_type']) && in_array($cfg_array['search_type'], $search_types, true) && ($cfg_array['search_type'] != $config['search_type']))
 156              {
 157                  $search = null;
 158                  $error = false;
 159  
 160                  if (!$this->init_search($cfg_array['search_type'], $search, $error))
 161                  {
 162                      if (confirm_box(true))
 163                      {
 164                          if (!method_exists($search, 'init') || !($error = $search->init()))
 165                          {
 166                              $config->set('search_type', $cfg_array['search_type']);
 167  
 168                              if (!$updated)
 169                              {
 170                                  $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_SEARCH');
 171                              }
 172                              $extra_message = '<br />' . $user->lang['SWITCHED_SEARCH_BACKEND'] . '<br /><a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=search&amp;mode=index') . '">&raquo; ' . $user->lang['GO_TO_SEARCH_INDEX'] . '</a>';
 173                          }
 174                          else
 175                          {
 176                              trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 177                          }
 178                      }
 179                      else
 180                      {
 181                          confirm_box(false, $user->lang['CONFIRM_SEARCH_BACKEND'], build_hidden_fields(array(
 182                              'i'            => $id,
 183                              'mode'        => $mode,
 184                              'submit'    => true,
 185                              'updated'    => $updated,
 186                              'config'    => array('search_type' => $cfg_array['search_type']),
 187                          )));
 188                      }
 189                  }
 190                  else
 191                  {
 192                      trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 193                  }
 194              }
 195  
 196              $search = null;
 197              $error = false;
 198              if (!$this->init_search($config['search_type'], $search, $error))
 199              {
 200                  if ($updated)
 201                  {
 202                      if (method_exists($search, 'config_updated'))
 203                      {
 204                          if ($search->config_updated())
 205                          {
 206                              trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 207                          }
 208                      }
 209                  }
 210              }
 211              else
 212              {
 213                  trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 214              }
 215  
 216              trigger_error($user->lang['CONFIG_UPDATED'] . $extra_message . adm_back_link($this->u_action));
 217          }
 218          unset($cfg_array);
 219  
 220          $this->tpl_name = 'acp_search';
 221          $this->page_title = 'ACP_SEARCH_SETTINGS';
 222  
 223          $template->assign_vars([
 224              'DEFAULT_SEARCH_RETURN_CHARS'    => (int) $config['default_search_return_chars'],
 225              'LIMIT_SEARCH_LOAD'                => (float) $config['limit_search_load'],
 226              'MIN_SEARCH_AUTHOR_CHARS'        => (int) $config['min_search_author_chars'],
 227              'SEARCH_INTERVAL'                => (float) $config['search_interval'],
 228              'SEARCH_GUEST_INTERVAL'            => (float) $config['search_anonymous_interval'],
 229              'SEARCH_STORE_RESULTS'            => (int) $config['search_store_results'],
 230              'MAX_NUM_SEARCH_KEYWORDS'        => (int) $config['max_num_search_keywords'],
 231  
 232              'S_SEARCH_TYPES'        => $search_options,
 233              'S_YES_SEARCH'            => (bool) $config['load_search'],
 234              'S_SETTINGS'            => true,
 235  
 236              'U_ACTION'                => $this->u_action . '&amp;hash=' . generate_link_hash('acp_search'),
 237          ]);
 238      }
 239  
 240  	function index($id, $mode)
 241      {
 242          global $db, $user, $template, $phpbb_log, $request;
 243          global $config, $phpbb_admin_path, $phpEx;
 244  
 245          $action = $request->variable('action', '');
 246          $this->state = explode(',', $config['search_indexing_state']);
 247  
 248          if ($request->is_set_post('cancel'))
 249          {
 250              $action = '';
 251              $this->state = array();
 252              $this->save_state();
 253          }
 254          $submit = $request->is_set_post('submit');
 255  
 256          if (!check_link_hash($request->variable('hash', ''), 'acp_search') && in_array($action, array('create', 'delete')))
 257          {
 258              trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 259          }
 260  
 261          if ($action)
 262          {
 263              switch ($action)
 264              {
 265                  case 'progress_bar':
 266                      $type = $request->variable('type', '');
 267                      $this->display_progress_bar($type);
 268                  break;
 269  
 270                  case 'delete':
 271                      $this->state[1] = 'delete';
 272                  break;
 273  
 274                  case 'create':
 275                      $this->state[1] = 'create';
 276                  break;
 277  
 278                  default:
 279                      trigger_error('NO_ACTION', E_USER_ERROR);
 280                  break;
 281              }
 282  
 283              if (empty($this->state[0]))
 284              {
 285                  $this->state[0] = $request->variable('search_type', '');
 286              }
 287  
 288              $this->search = null;
 289              $error = false;
 290              if ($this->init_search($this->state[0], $this->search, $error))
 291              {
 292                  trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 293              }
 294              $name = $this->search->get_name();
 295  
 296              $action = &$this->state[1];
 297  
 298              $this->max_post_id = $this->get_max_post_id();
 299  
 300              $post_counter = (isset($this->state[2])) ? $this->state[2] : 0;
 301              $this->state[2] = &$post_counter;
 302              $this->save_state();
 303  
 304              switch ($action)
 305              {
 306                  case 'delete':
 307                      if (method_exists($this->search, 'delete_index'))
 308                      {
 309                          // pass a reference to myself so the $search object can make use of save_state() and attributes
 310                          if ($error = $this->search->delete_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=delete&hash=" . generate_link_hash('acp_search'), false)))
 311                          {
 312                              $this->state = array('');
 313                              $this->save_state();
 314                              trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING);
 315                          }
 316                      }
 317                      else
 318                      {
 319                          $starttime = microtime(true);
 320                          $row_count = 0;
 321                          while (still_on_time() && $post_counter <= $this->max_post_id)
 322                          {
 323                              $sql = 'SELECT post_id, poster_id, forum_id
 324                                  FROM ' . POSTS_TABLE . '
 325                                  WHERE post_id > ' . (int) $post_counter . '
 326                                  ORDER BY post_id ASC';
 327                              $result = $db->sql_query_limit($sql, $this->batch_size);
 328  
 329                              $ids = $posters = $forum_ids = array();
 330                              while ($row = $db->sql_fetchrow($result))
 331                              {
 332                                  $ids[] = $row['post_id'];
 333                                  $posters[] = $row['poster_id'];
 334                                  $forum_ids[] = $row['forum_id'];
 335                              }
 336                              $db->sql_freeresult($result);
 337                              $row_count += count($ids);
 338  
 339                              if (count($ids))
 340                              {
 341                                  $this->search->index_remove($ids, $posters, $forum_ids);
 342                                  $post_counter = $ids[count($ids) - 1];
 343                              }
 344                          }
 345                          // save the current state
 346                          $this->save_state();
 347  
 348                          if ($post_counter < $this->max_post_id)
 349                          {
 350                              $totaltime = microtime(true) - $starttime;
 351                              $rows_per_second = $row_count / $totaltime;
 352                              meta_refresh(1, append_sid($this->u_action . '&amp;action=delete&amp;skip_rows=' . $post_counter . '&amp;hash=' . generate_link_hash('acp_search')));
 353                              trigger_error($user->lang('SEARCH_INDEX_DELETE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_DELETE_REDIRECT_RATE', $rows_per_second));
 354                          }
 355                      }
 356  
 357                      $this->search->tidy();
 358  
 359                      $this->state = array('');
 360                      $this->save_state();
 361  
 362                      $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_SEARCH_INDEX_REMOVED', false, array($name));
 363                      trigger_error($user->lang['SEARCH_INDEX_REMOVED'] . adm_back_link($this->u_action) . $this->close_popup_js());
 364                  break;
 365  
 366                  case 'create':
 367                      if (method_exists($this->search, 'create_index'))
 368                      {
 369                          // pass a reference to acp_search so the $search object can make use of save_state() and attributes
 370                          if ($error = $this->search->create_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=create", false)))
 371                          {
 372                              $this->state = array('');
 373                              $this->save_state();
 374                              trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING);
 375                          }
 376                      }
 377                      else
 378                      {
 379                          $sql = 'SELECT forum_id, enable_indexing
 380                              FROM ' . FORUMS_TABLE;
 381                          $result = $db->sql_query($sql, 3600);
 382  
 383                          while ($row = $db->sql_fetchrow($result))
 384                          {
 385                              $forums[$row['forum_id']] = (bool) $row['enable_indexing'];
 386                          }
 387                          $db->sql_freeresult($result);
 388  
 389                          $starttime = microtime(true);
 390                          $row_count = 0;
 391                          while (still_on_time() && $post_counter <= $this->max_post_id)
 392                          {
 393                              $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
 394                                  FROM ' . POSTS_TABLE . '
 395                                  WHERE post_id > ' . (int) $post_counter . '
 396                                  ORDER BY post_id ASC';
 397                              $result = $db->sql_query_limit($sql, $this->batch_size);
 398  
 399                              $buffer = $db->sql_buffer_nested_transactions();
 400  
 401                              if ($buffer)
 402                              {
 403                                  $rows = $db->sql_fetchrowset($result);
 404                                  $rows[] = false; // indicate end of array for while loop below
 405  
 406                                  $db->sql_freeresult($result);
 407                              }
 408  
 409                              $i = 0;
 410                              while ($row = ($buffer ? $rows[$i++] : $db->sql_fetchrow($result)))
 411                              {
 412                                  // Indexing enabled for this forum
 413                                  if (isset($forums[$row['forum_id']]) && $forums[$row['forum_id']])
 414                                  {
 415                                      $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
 416                                  }
 417                                  $row_count++;
 418                                  $post_counter = $row['post_id'];
 419                              }
 420                              if (!$buffer)
 421                              {
 422                                  $db->sql_freeresult($result);
 423                              }
 424                          }
 425                          // save the current state
 426                          $this->save_state();
 427  
 428                          // pretend the number of posts was as big as the number of ids we indexed so far
 429                          // just an estimation as it includes deleted posts
 430                          $num_posts = $config['num_posts'];
 431                          $config['num_posts'] = min($config['num_posts'], $post_counter);
 432                          $this->search->tidy();
 433                          $config['num_posts'] = $num_posts;
 434  
 435                          if ($post_counter < $this->max_post_id)
 436                          {
 437                              $totaltime = microtime(true) - $starttime;
 438                              $rows_per_second = $row_count / $totaltime;
 439                              meta_refresh(1, append_sid($this->u_action . '&amp;action=create&amp;skip_rows=' . $post_counter . '&amp;hash=' . generate_link_hash('acp_search')));
 440                              trigger_error($user->lang('SEARCH_INDEX_CREATE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_CREATE_REDIRECT_RATE', $rows_per_second));
 441                          }
 442                      }
 443  
 444                      $this->search->tidy();
 445  
 446                      $this->state = array('');
 447                      $this->save_state();
 448  
 449                      $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_SEARCH_INDEX_CREATED', false, array($name));
 450                      trigger_error($user->lang['SEARCH_INDEX_CREATED'] . adm_back_link($this->u_action) . $this->close_popup_js());
 451                  break;
 452              }
 453          }
 454  
 455          $search_types = $this->get_search_types();
 456  
 457          $search = null;
 458          $error = false;
 459          foreach ($search_types as $type)
 460          {
 461              if ($this->init_search($type, $search, $error) || !method_exists($search, 'index_created'))
 462              {
 463                  continue;
 464              }
 465  
 466              $name = $search->get_name();
 467  
 468              $data = array();
 469              if (method_exists($search, 'index_stats'))
 470              {
 471                  $data = $search->index_stats();
 472              }
 473  
 474              $statistics = array();
 475              foreach ($data as $statistic => $value)
 476              {
 477                  $n = count($statistics);
 478                  if ($n && count($statistics[$n - 1]) < 3)
 479                  {
 480                      $statistics[$n - 1] += array('statistic_2' => $statistic, 'value_2' => $value);
 481                  }
 482                  else
 483                  {
 484                      $statistics[] = array('statistic_1' => $statistic, 'value_1' => $value);
 485                  }
 486              }
 487  
 488              $template->assign_block_vars('backend', array(
 489                  'L_NAME'            => $name,
 490                  'NAME'                => $type,
 491  
 492                  'S_ACTIVE'            => ($type == $config['search_type']) ? true : false,
 493                  'S_HIDDEN_FIELDS'    => build_hidden_fields(array('search_type' => $type)),
 494                  'S_INDEXED'            => (bool) $search->index_created(),
 495                  'S_STATS'            => (bool) count($statistics))
 496              );
 497  
 498              foreach ($statistics as $statistic)
 499              {
 500                  $template->assign_block_vars('backend.data', array(
 501                      'STATISTIC_1'    => $statistic['statistic_1'],
 502                      'VALUE_1'        => $statistic['value_1'],
 503                      'STATISTIC_2'    => (isset($statistic['statistic_2'])) ? $statistic['statistic_2'] : '',
 504                      'VALUE_2'        => (isset($statistic['value_2'])) ? $statistic['value_2'] : '')
 505                  );
 506              }
 507          }
 508          unset($search);
 509          unset($error);
 510          unset($statistics);
 511          unset($data);
 512  
 513          $this->tpl_name = 'acp_search';
 514          $this->page_title = 'ACP_SEARCH_INDEX';
 515  
 516          $template->assign_vars(array(
 517              'S_INDEX'                => true,
 518              'U_ACTION'                => $this->u_action . '&amp;hash=' . generate_link_hash('acp_search'),
 519              'U_PROGRESS_BAR'        => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;mode=$mode&amp;action=progress_bar"),
 520              'UA_PROGRESS_BAR'        => addslashes(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;mode=$mode&amp;action=progress_bar")),
 521          ));
 522  
 523          if (isset($this->state[1]))
 524          {
 525              $template->assign_vars(array(
 526                  'S_CONTINUE_INDEXING'    => $this->state[1],
 527                  'U_CONTINUE_INDEXING'    => $this->u_action . '&amp;action=' . $this->state[1] . '&amp;hash=' . generate_link_hash('acp_search'),
 528                  'L_CONTINUE'            => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING'] : $user->lang['CONTINUE_DELETING_INDEX'],
 529                  'L_CONTINUE_EXPLAIN'    => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING_EXPLAIN'] : $user->lang['CONTINUE_DELETING_INDEX_EXPLAIN'])
 530              );
 531          }
 532      }
 533  
 534  	function display_progress_bar($type)
 535      {
 536          global $template, $user;
 537  
 538          $l_type = ($type == 'create') ? 'INDEXING_IN_PROGRESS' : 'DELETING_INDEX_IN_PROGRESS';
 539  
 540          adm_page_header($user->lang[$l_type]);
 541  
 542          $template->set_filenames(array(
 543              'body'    => 'progress_bar.html')
 544          );
 545  
 546          $template->assign_vars(array(
 547              'L_PROGRESS'            => $user->lang[$l_type],
 548              'L_PROGRESS_EXPLAIN'    => $user->lang[$l_type . '_EXPLAIN'])
 549          );
 550  
 551          adm_page_footer();
 552      }
 553  
 554  	function close_popup_js()
 555      {
 556          return "<script type=\"text/javascript\">\n" .
 557              "// <![CDATA[\n" .
 558              "    close_waitscreen = 1;\n" .
 559              "// ]]>\n" .
 560              "</script>\n";
 561      }
 562  
 563  	function get_search_types()
 564      {
 565          global $phpbb_extension_manager;
 566  
 567          $finder = $phpbb_extension_manager->get_finder();
 568  
 569          return $finder
 570              ->extension_suffix('_backend')
 571              ->extension_directory('/search')
 572              ->core_path('phpbb/search/')
 573              ->get_classes();
 574      }
 575  
 576  	function get_max_post_id()
 577      {
 578          global $db;
 579  
 580          $sql = 'SELECT MAX(post_id) as max_post_id
 581              FROM '. POSTS_TABLE;
 582          $result = $db->sql_query($sql);
 583          $max_post_id = (int) $db->sql_fetchfield('max_post_id');
 584          $db->sql_freeresult($result);
 585  
 586          return $max_post_id;
 587      }
 588  
 589  	function save_state($state = false)
 590      {
 591          global $config;
 592  
 593          if ($state)
 594          {
 595              $this->state = $state;
 596          }
 597  
 598          ksort($this->state);
 599  
 600          $config->set('search_indexing_state', implode(',', $this->state), true);
 601      }
 602  
 603      /**
 604      * Initialises a search backend object
 605      *
 606      * @return false if no error occurred else an error message
 607      */
 608  	function init_search($type, &$search, &$error)
 609      {
 610          global $phpbb_root_path, $phpEx, $user, $auth, $config, $db, $phpbb_dispatcher;
 611  
 612          if (!class_exists($type) || !method_exists($type, 'keyword_search'))
 613          {
 614              $error = $user->lang['NO_SUCH_SEARCH_MODULE'];
 615              return $error;
 616          }
 617  
 618          $error = false;
 619          $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
 620  
 621          return $error;
 622      }
 623  }


Generated: Wed Feb 22 20:16:20 2023 Cross-referenced by PHPXref 0.7.1