[ Index ]

PHP Cross Reference of phpBB-3.1.12-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 $db, $user, $auth, $template, $cache, $request;
  54          global $config, $phpbb_root_path, $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_var('config', array('' => ''), true) : array();
 113          $updated = request_var('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                  set_config($config_name, $config_value);
 142                  $updated = true;
 143              }
 144          }
 145  
 146          if ($submit)
 147          {
 148              $extra_message = '';
 149              if ($updated)
 150              {
 151                  add_log('admin', '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                              set_config('search_type', $cfg_array['search_type']);
 166  
 167                              if (!$updated)
 168                              {
 169                                  add_log('admin', '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, $auth, $template, $cache, $request;
 241          global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
 242  
 243          $action = request_var('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_var('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_var('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 = explode(' ', microtime());
 318                          $starttime = $starttime[1] + $starttime[0];
 319                          $row_count = 0;
 320                          while (still_on_time() && $post_counter <= $this->max_post_id)
 321                          {
 322                              $sql = 'SELECT post_id, poster_id, forum_id
 323                                  FROM ' . POSTS_TABLE . '
 324                                  WHERE post_id >= ' . (int) ($post_counter + 1) . '
 325                                      AND post_id <= ' . (int) ($post_counter + $this->batch_size);
 326                              $result = $db->sql_query($sql);
 327  
 328                              $ids = $posters = $forum_ids = array();
 329                              while ($row = $db->sql_fetchrow($result))
 330                              {
 331                                  $ids[] = $row['post_id'];
 332                                  $posters[] = $row['poster_id'];
 333                                  $forum_ids[] = $row['forum_id'];
 334                              }
 335                              $db->sql_freeresult($result);
 336                              $row_count += sizeof($ids);
 337  
 338                              if (sizeof($ids))
 339                              {
 340                                  $this->search->index_remove($ids, $posters, $forum_ids);
 341                              }
 342  
 343                              $post_counter += $this->batch_size;
 344                          }
 345                          // save the current state
 346                          $this->save_state();
 347  
 348                          if ($post_counter <= $this->max_post_id)
 349                          {
 350                              $mtime = explode(' ', microtime());
 351                              $totaltime = $mtime[0] + $mtime[1] - $starttime;
 352                              $rows_per_second = $row_count / $totaltime;
 353                              meta_refresh(1, append_sid($this->u_action . '&amp;action=delete&amp;skip_rows=' . $post_counter . '&amp;hash=' . generate_link_hash('acp_search')));
 354                              trigger_error($user->lang('SEARCH_INDEX_DELETE_REDIRECT', (int) $row_count, $post_counter, $rows_per_second));
 355                          }
 356                      }
 357  
 358                      $this->search->tidy();
 359  
 360                      $this->state = array('');
 361                      $this->save_state();
 362  
 363                      add_log('admin', 'LOG_SEARCH_INDEX_REMOVED', $name);
 364                      trigger_error($user->lang['SEARCH_INDEX_REMOVED'] . adm_back_link($this->u_action) . $this->close_popup_js());
 365                  break;
 366  
 367                  case 'create':
 368                      if (method_exists($this->search, 'create_index'))
 369                      {
 370                          // pass a reference to acp_search so the $search object can make use of save_state() and attributes
 371                          if ($error = $this->search->create_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=create", false)))
 372                          {
 373                              $this->state = array('');
 374                              $this->save_state();
 375                              trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING);
 376                          }
 377                      }
 378                      else
 379                      {
 380                          $sql = 'SELECT forum_id, enable_indexing
 381                              FROM ' . FORUMS_TABLE;
 382                          $result = $db->sql_query($sql, 3600);
 383  
 384                          while ($row = $db->sql_fetchrow($result))
 385                          {
 386                              $forums[$row['forum_id']] = (bool) $row['enable_indexing'];
 387                          }
 388                          $db->sql_freeresult($result);
 389  
 390                          $starttime = explode(' ', microtime());
 391                          $starttime = $starttime[1] + $starttime[0];
 392                          $row_count = 0;
 393                          while (still_on_time() && $post_counter <= $this->max_post_id)
 394                          {
 395                              $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
 396                                  FROM ' . POSTS_TABLE . '
 397                                  WHERE post_id >= ' . (int) ($post_counter + 1) . '
 398                                      AND post_id <= ' . (int) ($post_counter + $this->batch_size);
 399                              $result = $db->sql_query($sql);
 400  
 401                              $buffer = $db->sql_buffer_nested_transactions();
 402  
 403                              if ($buffer)
 404                              {
 405                                  $rows = $db->sql_fetchrowset($result);
 406                                  $rows[] = false; // indicate end of array for while loop below
 407  
 408                                  $db->sql_freeresult($result);
 409                              }
 410  
 411                              $i = 0;
 412                              while ($row = ($buffer ? $rows[$i++] : $db->sql_fetchrow($result)))
 413                              {
 414                                  // Indexing enabled for this forum
 415                                  if (isset($forums[$row['forum_id']]) && $forums[$row['forum_id']])
 416                                  {
 417                                      $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
 418                                  }
 419                                  $row_count++;
 420                              }
 421                              if (!$buffer)
 422                              {
 423                                  $db->sql_freeresult($result);
 424                              }
 425  
 426                              $post_counter += $this->batch_size;
 427                          }
 428                          // save the current state
 429                          $this->save_state();
 430  
 431                          // pretend the number of posts was as big as the number of ids we indexed so far
 432                          // just an estimation as it includes deleted posts
 433                          $num_posts = $config['num_posts'];
 434                          $config['num_posts'] = min($config['num_posts'], $post_counter);
 435                          $this->search->tidy();
 436                          $config['num_posts'] = $num_posts;
 437  
 438                          if ($post_counter <= $this->max_post_id)
 439                          {
 440                              $mtime = explode(' ', microtime());
 441                              $totaltime = $mtime[0] + $mtime[1] - $starttime;
 442                              $rows_per_second = $row_count / $totaltime;
 443                              meta_refresh(1, append_sid($this->u_action . '&amp;action=create&amp;skip_rows=' . $post_counter . '&amp;hash=' . generate_link_hash('acp_search')));
 444                              trigger_error($user->lang('SEARCH_INDEX_CREATE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_CREATE_REDIRECT_RATE', $rows_per_second));
 445                          }
 446                      }
 447  
 448                      $this->search->tidy();
 449  
 450                      $this->state = array('');
 451                      $this->save_state();
 452  
 453                      add_log('admin', 'LOG_SEARCH_INDEX_CREATED', $name);
 454                      trigger_error($user->lang['SEARCH_INDEX_CREATED'] . adm_back_link($this->u_action) . $this->close_popup_js());
 455                  break;
 456              }
 457          }
 458  
 459          $search_types = $this->get_search_types();
 460  
 461          $search = null;
 462          $error = false;
 463          foreach ($search_types as $type)
 464          {
 465              if ($this->init_search($type, $search, $error) || !method_exists($search, 'index_created'))
 466              {
 467                  continue;
 468              }
 469  
 470              $name = $search->get_name();
 471  
 472              $data = array();
 473              if (method_exists($search, 'index_stats'))
 474              {
 475                  $data = $search->index_stats();
 476              }
 477  
 478              $statistics = array();
 479              foreach ($data as $statistic => $value)
 480              {
 481                  $n = sizeof($statistics);
 482                  if ($n && sizeof($statistics[$n - 1]) < 3)
 483                  {
 484                      $statistics[$n - 1] += array('statistic_2' => $statistic, 'value_2' => $value);
 485                  }
 486                  else
 487                  {
 488                      $statistics[] = array('statistic_1' => $statistic, 'value_1' => $value);
 489                  }
 490              }
 491  
 492              $template->assign_block_vars('backend', array(
 493                  'L_NAME'            => $name,
 494                  'NAME'                => $type,
 495  
 496                  'S_ACTIVE'            => ($type == $config['search_type']) ? true : false,
 497                  'S_HIDDEN_FIELDS'    => build_hidden_fields(array('search_type' => $type)),
 498                  'S_INDEXED'            => (bool) $search->index_created(),
 499                  'S_STATS'            => (bool) sizeof($statistics))
 500              );
 501  
 502              foreach ($statistics as $statistic)
 503              {
 504                  $template->assign_block_vars('backend.data', array(
 505                      'STATISTIC_1'    => $statistic['statistic_1'],
 506                      'VALUE_1'        => $statistic['value_1'],
 507                      'STATISTIC_2'    => (isset($statistic['statistic_2'])) ? $statistic['statistic_2'] : '',
 508                      'VALUE_2'        => (isset($statistic['value_2'])) ? $statistic['value_2'] : '')
 509                  );
 510              }
 511          }
 512          unset($search);
 513          unset($error);
 514          unset($statistics);
 515          unset($data);
 516  
 517          $this->tpl_name = 'acp_search';
 518          $this->page_title = 'ACP_SEARCH_INDEX';
 519  
 520          $template->assign_vars(array(
 521              'S_INDEX'                => true,
 522              'U_ACTION'                => $this->u_action . '&amp;hash=' . generate_link_hash('acp_search'),
 523              'U_PROGRESS_BAR'        => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;mode=$mode&amp;action=progress_bar"),
 524              'UA_PROGRESS_BAR'        => addslashes(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;mode=$mode&amp;action=progress_bar")),
 525          ));
 526  
 527          if (isset($this->state[1]))
 528          {
 529              $template->assign_vars(array(
 530                  'S_CONTINUE_INDEXING'    => $this->state[1],
 531                  'U_CONTINUE_INDEXING'    => $this->u_action . '&amp;action=' . $this->state[1] . '&amp;hash=' . generate_link_hash('acp_search'),
 532                  'L_CONTINUE'            => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING'] : $user->lang['CONTINUE_DELETING_INDEX'],
 533                  'L_CONTINUE_EXPLAIN'    => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING_EXPLAIN'] : $user->lang['CONTINUE_DELETING_INDEX_EXPLAIN'])
 534              );
 535          }
 536      }
 537  
 538  	function display_progress_bar($type)
 539      {
 540          global $template, $user;
 541  
 542          $l_type = ($type == 'create') ? 'INDEXING_IN_PROGRESS' : 'DELETING_INDEX_IN_PROGRESS';
 543  
 544          adm_page_header($user->lang[$l_type]);
 545  
 546          $template->set_filenames(array(
 547              'body'    => 'progress_bar.html')
 548          );
 549  
 550          $template->assign_vars(array(
 551              'L_PROGRESS'            => $user->lang[$l_type],
 552              'L_PROGRESS_EXPLAIN'    => $user->lang[$l_type . '_EXPLAIN'])
 553          );
 554  
 555          adm_page_footer();
 556      }
 557  
 558  	function close_popup_js()
 559      {
 560          return "<script type=\"text/javascript\">\n" .
 561              "// <![CDATA[\n" .
 562              "    close_waitscreen = 1;\n" .
 563              "// ]]>\n" .
 564              "</script>\n";
 565      }
 566  
 567  	function get_search_types()
 568      {
 569          global $phpbb_root_path, $phpEx, $phpbb_extension_manager;
 570  
 571          $finder = $phpbb_extension_manager->get_finder();
 572  
 573          return $finder
 574              ->extension_suffix('_backend')
 575              ->extension_directory('/search')
 576              ->core_path('phpbb/search/')
 577              ->get_classes();
 578      }
 579  
 580  	function get_max_post_id()
 581      {
 582          global $db;
 583  
 584          $sql = 'SELECT MAX(post_id) as max_post_id
 585              FROM '. POSTS_TABLE;
 586          $result = $db->sql_query($sql);
 587          $max_post_id = (int) $db->sql_fetchfield('max_post_id');
 588          $db->sql_freeresult($result);
 589  
 590          return $max_post_id;
 591      }
 592  
 593  	function save_state($state = false)
 594      {
 595          if ($state)
 596          {
 597              $this->state = $state;
 598          }
 599  
 600          ksort($this->state);
 601  
 602          set_config('search_indexing_state', implode(',', $this->state), true);
 603      }
 604  
 605      /**
 606      * Initialises a search backend object
 607      *
 608      * @return false if no error occurred else an error message
 609      */
 610  	function init_search($type, &$search, &$error)
 611      {
 612          global $phpbb_root_path, $phpEx, $user, $auth, $config, $db, $phpbb_dispatcher;
 613  
 614          if (!class_exists($type) || !method_exists($type, 'keyword_search'))
 615          {
 616              $error = $user->lang['NO_SUCH_SEARCH_MODULE'];
 617              return $error;
 618          }
 619  
 620          $error = false;
 621          $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
 622  
 623          return $error;
 624      }
 625  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1