[ Index ]

PHP Cross Reference of phpBB-3.2.11-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 = (isset($_POST['submit'])) ? true : false;
  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 = array(
  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              'search_store_results'        => 'integer',
  73          );
  74  
  75          $search = null;
  76          $error = false;
  77          $search_options = '';
  78          foreach ($search_types as $type)
  79          {
  80              if ($this->init_search($type, $search, $error))
  81              {
  82                  continue;
  83              }
  84  
  85              $name = $search->get_name();
  86  
  87              $selected = ($config['search_type'] == $type) ? ' selected="selected"' : '';
  88              $identifier = substr($type, strrpos($type, '\\') + 1);
  89              $search_options .= "<option value=\"$type\"$selected data-toggle-setting=\"#search_{$identifier}_settings\">$name</option>";
  90  
  91              if (method_exists($search, 'acp'))
  92              {
  93                  $vars = $search->acp();
  94  
  95                  if (!$submit)
  96                  {
  97                      $template->assign_block_vars('backend', array(
  98                          'NAME'            => $name,
  99                          'SETTINGS'        => $vars['tpl'],
 100                          'IDENTIFIER'    => $identifier,
 101                      ));
 102                  }
 103                  else if (is_array($vars['config']))
 104                  {
 105                      $settings = array_merge($settings, $vars['config']);
 106                  }
 107              }
 108          }
 109          unset($search);
 110          unset($error);
 111  
 112          $cfg_array = (isset($_REQUEST['config'])) ? $request->variable('config', array('' => ''), true) : array();
 113          $updated = $request->variable('updated', false);
 114  
 115          foreach ($settings as $config_name => $var_type)
 116          {
 117              if (!isset($cfg_array[$config_name]))
 118              {
 119                  continue;
 120              }
 121  
 122              // e.g. integer:4:12 (min 4, max 12)
 123              $var_type = explode(':', $var_type);
 124  
 125              $config_value = $cfg_array[$config_name];
 126              settype($config_value, $var_type[0]);
 127  
 128              if (isset($var_type[1]))
 129              {
 130                  $config_value = max($var_type[1], $config_value);
 131              }
 132  
 133              if (isset($var_type[2]))
 134              {
 135                  $config_value = min($var_type[2], $config_value);
 136              }
 137  
 138              // only change config if anything was actually changed
 139              if ($submit && ($config[$config_name] != $config_value))
 140              {
 141                  $config->set($config_name, $config_value);
 142                  $updated = true;
 143              }
 144          }
 145  
 146          if ($submit)
 147          {
 148              $extra_message = '';
 149              if ($updated)
 150              {
 151                  $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_SEARCH');
 152              }
 153  
 154              if (isset($cfg_array['search_type']) && in_array($cfg_array['search_type'], $search_types, true) && ($cfg_array['search_type'] != $config['search_type']))
 155              {
 156                  $search = null;
 157                  $error = false;
 158  
 159                  if (!$this->init_search($cfg_array['search_type'], $search, $error))
 160                  {
 161                      if (confirm_box(true))
 162                      {
 163                          if (!method_exists($search, 'init') || !($error = $search->init()))
 164                          {
 165                              $config->set('search_type', $cfg_array['search_type']);
 166  
 167                              if (!$updated)
 168                              {
 169                                  $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_SEARCH');
 170                              }
 171                              $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>';
 172                          }
 173                          else
 174                          {
 175                              trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 176                          }
 177                      }
 178                      else
 179                      {
 180                          confirm_box(false, $user->lang['CONFIRM_SEARCH_BACKEND'], build_hidden_fields(array(
 181                              'i'            => $id,
 182                              'mode'        => $mode,
 183                              'submit'    => true,
 184                              'updated'    => $updated,
 185                              'config'    => array('search_type' => $cfg_array['search_type']),
 186                          )));
 187                      }
 188                  }
 189                  else
 190                  {
 191                      trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 192                  }
 193              }
 194  
 195              $search = null;
 196              $error = false;
 197              if (!$this->init_search($config['search_type'], $search, $error))
 198              {
 199                  if ($updated)
 200                  {
 201                      if (method_exists($search, 'config_updated'))
 202                      {
 203                          if ($search->config_updated())
 204                          {
 205                              trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 206                          }
 207                      }
 208                  }
 209              }
 210              else
 211              {
 212                  trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 213              }
 214  
 215              trigger_error($user->lang['CONFIG_UPDATED'] . $extra_message . adm_back_link($this->u_action));
 216          }
 217          unset($cfg_array);
 218  
 219          $this->tpl_name = 'acp_search';
 220          $this->page_title = 'ACP_SEARCH_SETTINGS';
 221  
 222          $template->assign_vars(array(
 223              'LIMIT_SEARCH_LOAD'        => (float) $config['limit_search_load'],
 224              'MIN_SEARCH_AUTHOR_CHARS'    => (int) $config['min_search_author_chars'],
 225              'SEARCH_INTERVAL'        => (float) $config['search_interval'],
 226              'SEARCH_GUEST_INTERVAL'    => (float) $config['search_anonymous_interval'],
 227              'SEARCH_STORE_RESULTS'    => (int) $config['search_store_results'],
 228              'MAX_NUM_SEARCH_KEYWORDS'    => (int) $config['max_num_search_keywords'],
 229  
 230              'S_SEARCH_TYPES'        => $search_options,
 231              'S_YES_SEARCH'            => (bool) $config['load_search'],
 232              'S_SETTINGS'            => true,
 233  
 234              'U_ACTION'                => $this->u_action . '&amp;hash=' . generate_link_hash('acp_search'))
 235          );
 236      }
 237  
 238  	function index($id, $mode)
 239      {
 240          global $db, $user, $template, $phpbb_log, $request;
 241          global $config, $phpbb_admin_path, $phpEx;
 242  
 243          $action = $request->variable('action', '');
 244          $this->state = explode(',', $config['search_indexing_state']);
 245  
 246          if (isset($_POST['cancel']))
 247          {
 248              $action = '';
 249              $this->state = array();
 250              $this->save_state();
 251          }
 252          $submit = $request->is_set_post('submit', false);
 253  
 254          if (!check_link_hash($request->variable('hash', ''), 'acp_search') && in_array($action, array('create', 'delete')))
 255          {
 256              trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 257          }
 258  
 259          if ($action)
 260          {
 261              switch ($action)
 262              {
 263                  case 'progress_bar':
 264                      $type = $request->variable('type', '');
 265                      $this->display_progress_bar($type);
 266                  break;
 267  
 268                  case 'delete':
 269                      $this->state[1] = 'delete';
 270                  break;
 271  
 272                  case 'create':
 273                      $this->state[1] = 'create';
 274                  break;
 275  
 276                  default:
 277                      trigger_error('NO_ACTION', E_USER_ERROR);
 278                  break;
 279              }
 280  
 281              if (empty($this->state[0]))
 282              {
 283                  $this->state[0] = $request->variable('search_type', '');
 284              }
 285  
 286              $this->search = null;
 287              $error = false;
 288              if ($this->init_search($this->state[0], $this->search, $error))
 289              {
 290                  trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
 291              }
 292              $name = $this->search->get_name();
 293  
 294              $action = &$this->state[1];
 295  
 296              $this->max_post_id = $this->get_max_post_id();
 297  
 298              $post_counter = (isset($this->state[2])) ? $this->state[2] : 0;
 299              $this->state[2] = &$post_counter;
 300              $this->save_state();
 301  
 302              switch ($action)
 303              {
 304                  case 'delete':
 305                      if (method_exists($this->search, 'delete_index'))
 306                      {
 307                          // pass a reference to myself so the $search object can make use of save_state() and attributes
 308                          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)))
 309                          {
 310                              $this->state = array('');
 311                              $this->save_state();
 312                              trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING);
 313                          }
 314                      }
 315                      else
 316                      {
 317                          $starttime = microtime(true);
 318                          $row_count = 0;
 319                          while (still_on_time() && $post_counter <= $this->max_post_id)
 320                          {
 321                              $sql = 'SELECT post_id, poster_id, forum_id
 322                                  FROM ' . POSTS_TABLE . '
 323                                  WHERE post_id >= ' . (int) ($post_counter + 1) . '
 324                                      AND post_id <= ' . (int) ($post_counter + $this->batch_size);
 325                              $result = $db->sql_query($sql);
 326  
 327                              $ids = $posters = $forum_ids = array();
 328                              while ($row = $db->sql_fetchrow($result))
 329                              {
 330                                  $ids[] = $row['post_id'];
 331                                  $posters[] = $row['poster_id'];
 332                                  $forum_ids[] = $row['forum_id'];
 333                              }
 334                              $db->sql_freeresult($result);
 335                              $row_count += count($ids);
 336  
 337                              if (count($ids))
 338                              {
 339                                  $this->search->index_remove($ids, $posters, $forum_ids);
 340                              }
 341  
 342                              $post_counter += $this->batch_size;
 343                          }
 344                          // save the current state
 345                          $this->save_state();
 346  
 347                          if ($post_counter <= $this->max_post_id)
 348                          {
 349                              $totaltime = microtime(true) - $starttime;
 350                              $rows_per_second = $row_count / $totaltime;
 351                              meta_refresh(1, append_sid($this->u_action . '&amp;action=delete&amp;skip_rows=' . $post_counter . '&amp;hash=' . generate_link_hash('acp_search')));
 352                              trigger_error($user->lang('SEARCH_INDEX_DELETE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_DELETE_REDIRECT_RATE', $rows_per_second));
 353                          }
 354                      }
 355  
 356                      $this->search->tidy();
 357  
 358                      $this->state = array('');
 359                      $this->save_state();
 360  
 361                      $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_SEARCH_INDEX_REMOVED', false, array($name));
 362                      trigger_error($user->lang['SEARCH_INDEX_REMOVED'] . adm_back_link($this->u_action) . $this->close_popup_js());
 363                  break;
 364  
 365                  case 'create':
 366                      if (method_exists($this->search, 'create_index'))
 367                      {
 368                          // pass a reference to acp_search so the $search object can make use of save_state() and attributes
 369                          if ($error = $this->search->create_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=create", false)))
 370                          {
 371                              $this->state = array('');
 372                              $this->save_state();
 373                              trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING);
 374                          }
 375                      }
 376                      else
 377                      {
 378                          $sql = 'SELECT forum_id, enable_indexing
 379                              FROM ' . FORUMS_TABLE;
 380                          $result = $db->sql_query($sql, 3600);
 381  
 382                          while ($row = $db->sql_fetchrow($result))
 383                          {
 384                              $forums[$row['forum_id']] = (bool) $row['enable_indexing'];
 385                          }
 386                          $db->sql_freeresult($result);
 387  
 388                          $starttime = microtime(true);
 389                          $row_count = 0;
 390                          while (still_on_time() && $post_counter <= $this->max_post_id)
 391                          {
 392                              $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
 393                                  FROM ' . POSTS_TABLE . '
 394                                  WHERE post_id >= ' . (int) ($post_counter + 1) . '
 395                                      AND post_id <= ' . (int) ($post_counter + $this->batch_size);
 396                              $result = $db->sql_query($sql);
 397  
 398                              $buffer = $db->sql_buffer_nested_transactions();
 399  
 400                              if ($buffer)
 401                              {
 402                                  $rows = $db->sql_fetchrowset($result);
 403                                  $rows[] = false; // indicate end of array for while loop below
 404  
 405                                  $db->sql_freeresult($result);
 406                              }
 407  
 408                              $i = 0;
 409                              while ($row = ($buffer ? $rows[$i++] : $db->sql_fetchrow($result)))
 410                              {
 411                                  // Indexing enabled for this forum
 412                                  if (isset($forums[$row['forum_id']]) && $forums[$row['forum_id']])
 413                                  {
 414                                      $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
 415                                  }
 416                                  $row_count++;
 417                              }
 418                              if (!$buffer)
 419                              {
 420                                  $db->sql_freeresult($result);
 421                              }
 422  
 423                              $post_counter += $this->batch_size;
 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 Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1