Version 3.3.4

This commit is contained in:
Neo committed 2025-12-19 00:35:52 -08:00
1 parent 78706903a2
commit fb6b5baabc
2206 files changed
+409828 -382984

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -1,10 +1,10 @@
<html>
<head><title>IP.Board - Bulletin Board System</title></head>
<body>
<h1>403: IP.Board -&gt; Forbidden</h1>
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
<html>
<head><title>IP.Board - Bulletin Board System</title></head>
<body>
<h1>403: IP.Board -&gt; Forbidden</h1>
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
</html>
@@ -1,333 +1,357 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2011-08-08 07:05:57 -0400 (Mon, 08 Aug 2011) $
* </pre>
*
* @author $Author: mmecham $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://hatynka.in
* @version $Rev: 9376 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_engine
{
/**
* Date range restriction start
*
* @access protected
* @var integer
*/
protected $search_begin_timestamp = 0;
/**
* Date range restriction end
*
* @access protected
* @var integer
*/
protected $search_end_timestamp = 0;
/**
* Array of conditions for this search
*
* @access protected
* @var array
*/
protected $whereConditions = array();
/**
* Sphinx client object
*
* @access public
* @var object
*/
public $sphinxClient;
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
/* Do we have the sphinxes? */
if( ! is_file( 'sphinxapi.php' ) )
{
$registry->output->showError( 'sphinx_api_missing', 10182 );
}
/* Load Sphinx */
require( 'sphinxapi.php' );/*noLibHook*/
$this->sphinxClient = new SphinxClient();
$this->sphinxClient->SetServer( $this->settings['search_sphinx_server'], intval( $this->settings['search_sphinx_port'] ) );
$this->sphinxClient->SetMatchMode( SPH_MATCH_EXTENDED );
$this->sphinxClient->SetLimits( 0, 1000 );
}
/**
* Perform a search.
* Returns an array of a total count (total number of matches)
* and an array of IDs matching the required number based on pagination. The ids returned would be based on the filters and type of search
*
* So if we had 1000 replies, and we are on page 2 of 25 per page, we'd return 25 items offset by 25
*
* @access public
* @return array
*/
public function search()
{
/* Per app class handles this */
throw new Exception("NO_SEARCH_AVAILABLE");
}
/**
* Perform the viewNewContent search
* Generic version
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewUserContent( $member )
{
$app = IPSSearchRegistry::get('in.search_app');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
IPSSearchRegistry::set('opt.searchTitleOnly', IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
$this->setCondition( 'member_id', '=', $member['member_id'] );
/* Cut by date for efficiency? */
if ( $this->settings['search_ucontent_days'] )
{
$begin = ( $member['last_post'] ? $member['last_post'] : time() ) - 86400 * intval( $this->settings['search_ucontent_days'] );
$this->setDateRange( $begin, time() );
}
return $this->search();
}
/**
* Can handle boolean searching
*
* @access public
* @return boolean
*/
public function isBoolean()
{
return TRUE;
}
/**
* Formats search term for SQL
*
* @access private
* @param string Raw IPB santized form input
* @return array array( 'search_term' => Safe string to use in SQL, 'removed' => array of removed search terms )
*/
public function formatSearchTerm( $search_term )
{
$isBoolean = $this->isBoolean();
$andor = isset( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$removedTerms = array();
/* Fix up some sanitized HTML */
$search_term = str_replace( "&amp;" , '&' , IPSText::parseCleanValue( rawurldecode( $search_term ) ) );
$search_term = str_replace( "&quot;" , '"' , $search_term );
$search_term = IPSText::mbstrtolower( $search_term );
/* Check for disallowed search terms */
while( preg_match_all( '/(?:^|\s+)(img|quote|code|html|javascript|a href|color|span|div|border|style)(?:\s+|$)/', $search_term, $removed_search_terms ) )
{
$removedTerms[] = $removed_search_terms[0][0];
$search_term = preg_replace( '/(^|\s+)(?:img|quote|code|html|javascript|a href|color|span|div|border|style)(\s+|$)/', str_replace( " ", " ", "$1$2" ), $search_term );
}
/* Remove some formatting */
//$search_term = str_replace( array( '|', '\\', '/' ), '', $search_term );
// | is an OR operator for sphinx - don't want to block globally
$search_term = str_replace( array( '\\', '/' ), '', $search_term );
/* Sphinx chars are not allowed */
$search_term = str_replace( array( '.', ')', '(', '!', '@', '[', ']', '-', '~', '^' ), '', $search_term );
if ( $andor == 'or' )
{
$search_term = preg_replace( '/\s+/', " | ", $search_term );
}
return array( 'search_term' => $search_term, 'removed' => $removedTerms );
}
/**
* Restrict the date range that the search is performed on
*
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
$begin = ( $begin < 1000000000 ) ? 1000000000 : $begin;
$this->search_begin_timestamp = $begin;
$this->search_end_timestamp = $end;
}
/**
* Remap standard columns (Apps can override )
*
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return @e void
*/
public function remapColumn( $column )
{
return $column;
}
/**
* mySQL function for adding special search conditions
*
* @access public
* @param string $column sql table column for this condition
* @param string $operator Operation to perform for this condition, ex: =, <>, IN, NOT IN
* @param mixed $value Value to check with
* @param string $comp Comparison type
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
/* This is restricted by the indexes searched */
if( $column == 'app' )
{
return;
}
$column = $this->remapColumn( $column );
if( !$column )
{
return;
}
/* Build the condition based on operator */
switch( strtoupper( $operator ) )
{
case 'IN':
$this->sphinxClient->setFilter( $column, explode( ',', $value ) );
break;
case 'NOT IN':
$this->sphinxClient->setFilter( $column, explode( ',', $value ), TRUE );
break;
case '=':
$this->sphinxClient->setFilter( $column, array( $value ) );
break;
case '!=':
case '<>':
$this->sphinxClient->setFilter( $column, array( $value ), TRUE );
break;
default:
echo "<b>Unhandled sphinx search operator: {$operator}</b><br />";
break;
}
}
/**
* Allows you to specify multiple conditions that are chained together
*
* @access public
* @param array $conditions Array of conditions, each element has 3 keys: column, operator, value, see the setCondition function for information on each
* @param string $inner_comp Comparison operator to use inside the chain
* @param string $outer_comp Comparison operator to use outside the chain
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
/* Loop through the conditions to build the statement */
return;
}
/**
* Checks and logs any errors
*
* @access public
* @return @e void
*/
public function logSphinxWarnings()
{
$error = $this->sphinxClient->GetLastError();
$warning = $this->sphinxClient->GetLastWarning();
if ( $error )
{
IPSDebug::addLogMessage( "Sphinx Error: $error", 'sphinx_error_' . date('m_d_y'), $error, TRUE );
}
if ( $warning )
{
IPSDebug::addLogMessage( "Sphinx Warning: $warning", 'sphinx_warning_' . date('m_d_y'), $warning, TRUE );
}
}
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* Global Search
* Last Updated: $Date: 2012-06-21 12:05:17 -0400 (Thu, 21 Jun 2012) $
* </pre>
*
* @author $Author: AndyMillne $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 10967 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_engine
{
/**
* Date range restriction start
*
* @access protected
* @var integer
*/
protected $search_begin_timestamp = 0;
/**
* Date range restriction end
*
* @access protected
* @var integer
*/
protected $search_end_timestamp = 0;
/**
* Array of conditions for this search
*
* @access protected
* @var array
*/
protected $whereConditions = array();
/**
* Sphinx client object
*
* @access public
* @var object
*/
public $sphinxClient;
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
/* Do we have the sphinxes? */
if( ! is_file( DOC_IPS_ROOT_PATH . 'sphinxapi.php' ) )
{
$registry->output->showError( 'sphinx_api_missing', 10182 );
}
/* Load Sphinx */
require_once( DOC_IPS_ROOT_PATH . 'sphinxapi.php' );/*noLibHook*/
$this->sphinxClient = new SphinxClient();
$this->sphinxClient->SetServer( $this->settings['search_sphinx_server'], intval( $this->settings['search_sphinx_port'] ) );
$this->sphinxClient->SetMatchMode( SPH_MATCH_EXTENDED );
$this->sphinxClient->SetLimits( 0, 1000 );
}
/**
* Perform a search.
* Returns an array of a total count (total number of matches)
* and an array of IDs matching the required number based on pagination. The ids returned would be based on the filters and type of search
*
* So if we had 1000 replies, and we are on page 2 of 25 per page, we'd return 25 items offset by 25
*
* @access public
* @return array
*/
public function search()
{
/* Per app class handles this */
throw new Exception("NO_SEARCH_AVAILABLE");
}
/**
* Perform the viewNewContent search
* Generic version
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewUserContent( $member )
{
$app = IPSSearchRegistry::get('in.search_app');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
IPSSearchRegistry::set('opt.searchTitleOnly', IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
$this->setCondition( 'member_id', '=', $member['member_id'] );
/* Cut by date for efficiency? */
if ( $this->settings['search_ucontent_days'] )
{
$begin = ( $member['last_post'] ? $member['last_post'] : time() ) - 86400 * intval( $this->settings['search_ucontent_days'] );
$this->setDateRange( $begin, time() );
}
return $this->search();
}
/**
* Can handle boolean searching
*
* @access public
* @return boolean
*/
public function isBoolean()
{
return TRUE;
}
/**
* Formats search term for SQL
*
* @access private
* @param string Raw IPB santized form input
* @return array array( 'search_term' => Safe string to use in SQL, 'removed' => array of removed search terms )
*/
public function formatSearchTerm( $search_term )
{
$isBoolean = $this->isBoolean();
$andor = isset( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$removedTerms = array();
/* Fix up some sanitized HTML */
$search_term = str_replace( "&amp;" , '&' , IPSText::parseCleanValue( rawurldecode( $search_term ) ) );
$search_term = str_replace( "&quot;" , '"' , $search_term );
$search_term = IPSText::mbstrtolower( $search_term );
/* Check for disallowed search terms */
while( preg_match_all( '/(?:^|\s+)(img|quote|code|html|javascript|a href|color|span|div|border|style)(?:\s+|$)/', $search_term, $removed_search_terms ) )
{
$removedTerms[] = $removed_search_terms[0][0];
$search_term = preg_replace( '/(^|\s+)(?:img|quote|code|html|javascript|a href|color|span|div|border|style)(\s+|$)/', str_replace( " ", " ", "$1$2" ), $search_term );
}
/* remove < min char words */
if ( substr_count( $search_term, '"' ) != 2 )
{
$_words = explode( ' ', $search_term );
$search_term = '';
foreach( $_words as $_w )
{
if ( IPSText::mbstrlen( $_w ) >= $this->settings['min_search_word'] )
{
$search_term .= $_w . ' ';
}
else
{
$removedTerms[] = $_w;
}
}
}
/* Remove some formatting */
//$search_term = str_replace( array( '|', '\\', '/' ), '', $search_term );
// | is an OR operator for sphinx - don't want to block globally
if ( $search_term )
{
$search_term = str_replace( array( '\\', '/' ), '', trim( $search_term ) );
/* Sphinx chars are not allowed */
$search_term = str_replace( array( '.', ')', '(', '!', '@', '[', ']', '~', '^' ), '', $search_term );
$search_term = preg_replace('#(?!\s)-#', '\1&#8208', $search_term );
if ( $andor == 'and' AND ! ( substr_count( $search_term, '"' ) == 2 ) )
{
$search_term = '+' . preg_replace( '/\s+(?!-|~)/', " +", $search_term );
}
}
return array( 'search_term' => $search_term, 'removed' => $removedTerms );
}
/**
* Restrict the date range that the search is performed on
*
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
$begin = ( $begin < 1000000000 ) ? 1000000000 : $begin;
$this->search_begin_timestamp = $begin;
$this->search_end_timestamp = $end;
}
/**
* Remap standard columns (Apps can override )
*
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return @e void
*/
public function remapColumn( $column )
{
return $column;
}
/**
* mySQL function for adding special search conditions
*
* @access public
* @param string $column sql table column for this condition
* @param string $operator Operation to perform for this condition, ex: =, <>, IN, NOT IN
* @param mixed $value Value to check with
* @param string $comp Comparison type
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
/* This is restricted by the indexes searched */
if( $column == 'app' )
{
return;
}
$column = $this->remapColumn( $column );
if( !$column )
{
return;
}
/* Build the condition based on operator */
switch( strtoupper( $operator ) )
{
case 'IN':
$this->sphinxClient->setFilter( $column, explode( ',', $value ) );
break;
case 'NOT IN':
$this->sphinxClient->setFilter( $column, explode( ',', $value ), TRUE );
break;
case '=':
$this->sphinxClient->setFilter( $column, array( $value ) );
break;
case '!=':
case '<>':
$this->sphinxClient->setFilter( $column, array( $value ), TRUE );
break;
default:
echo "<b>Unhandled sphinx search operator: {$operator}</b><br />";
break;
}
}
/**
* Allows you to specify multiple conditions that are chained together
*
* @access public
* @param array $conditions Array of conditions, each element has 3 keys: column, operator, value, see the setCondition function for information on each
* @param string $inner_comp Comparison operator to use inside the chain
* @param string $outer_comp Comparison operator to use outside the chain
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
/* Loop through the conditions to build the statement */
return;
}
/**
* Checks and logs any errors
*
* @access public
* @return @e void
*/
public function logSphinxWarnings()
{
$error = $this->sphinxClient->GetLastError();
$warning = $this->sphinxClient->GetLastWarning();
if ( $error )
{
IPSDebug::addLogMessage( "Sphinx Error: $error", 'sphinx_error_' . date('m_d_y'), $error, TRUE );
}
if ( $warning )
{
IPSDebug::addLogMessage( "Sphinx Warning: $warning", 'sphinx_warning_' . date('m_d_y'), $warning, TRUE );
}
}
}
@@ -1,305 +1,324 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2011-05-05 07:03:47 -0400 (Thu, 05 May 2011) $
* </pre>
*
* @author $Author: ips_terabyte $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://hatynka.in
* @version $Rev: 8644 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_engine
{
/**
* Date range restriction start
*
* @access protected
* @var integer
*/
protected $search_begin_timestamp = 0;
/**
* Date range restriction end
*
* @access protected
* @var integer
*/
protected $search_end_timestamp = 0;
/**
* Array of conditions for this search
*
* @access protected
* @var array
*/
protected $whereConditions = array();
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
}
/**
* Perform a search.
* Returns an array of a total count (total number of matches)
* and an array of IDs matching the required number based on pagination. The ids returned would be based on the filters and type of search
*
* So if we had 1000 replies, and we are on page 2 of 25 per page, we'd return 25 items offset by 25
*
* @access public
* @return array
*/
public function search()
{
/* Per app class handles this */
throw new Exception("NO_SEARCH_AVAILABLE");
}
/**
* Perform the viewNewContent search
* Generic version
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewUserContent( $member )
{
$app = IPSSearchRegistry::get('in.search_app');
//IPSSearchRegistry::set('in.search_sort_by' , 'date' );
//IPSSearchRegistry::set('in.search_sort_order', 'desc' );
IPSSearchRegistry::set('opt.searchTitleOnly', IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
$this->setCondition( 'member_id', '=', $member['member_id'] );
/* Cut by date for efficiency? */
if ( $this->settings['search_ucontent_days'] )
{
$begin = time() - ( 86400 * intval( $this->settings['search_ucontent_days'] ) );
$this->setDateRange( $begin, time() );
}
return $this->search();
}
/**
* Can handle boolean searching
*
* @access public
* @return boolean
*/
public function isBoolean()
{
return ( $this->settings['use_fulltext'] AND $this->DB->checkBooleanFulltextSupport() ) ? TRUE : FALSE;
}
/**
* Formats search term for SQL
*
* @access private
* @param string Raw IPB santized form input
* @return array array( 'search_term' => Safe string to use in SQL, 'removed' => array of removed search terms )
*/
public function formatSearchTerm( $search_term )
{
$isBoolean = $this->isBoolean();
$andor = !empty( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$removedTerms = array();
/* Fix up some sanitized HTML */
$search_term = str_replace( "&amp;" , '&' , IPSText::parseCleanValue( rawurldecode( $search_term ) ) );
if( $isBoolean )
{
$search_term = str_replace( "&quot;" , '"' , $search_term );
}
else
{
$search_term = str_replace( "&quot;" , '' , $search_term );
}
$search_term = IPSText::mbstrtolower( $search_term );
/* Check for disallowed search terms */
while( preg_match_all( '/(?:^|\s+)(img|quote|code|html|javascript|a href|color|span|div|border|style)(?:\s+|$)/', $search_term, $removed_search_terms ) )
{
$removedTerms[] = $removed_search_terms[0][0];
$search_term = preg_replace( '/(^|\s+)(?:img|quote|code|html|javascript|a href|color|span|div|border|style)(\s+|$)/', str_replace( " ", " ", "$1$2" ), $search_term );
}
/* Remove some formatting */
//$search_term = str_replace( array( '|', '\\', '/' ), '', $search_term );
// | is an OR operator for sphinx - don't want to block globally
$search_term = str_replace( array( '\\', '/' ), '', $search_term );
/* got some bullean to do? */
if ( $isBoolean AND strstr( $search_term, ' ' ) AND ! strstr( $search_term, '"' ) )
{
if ( $andor == 'and' )
{
$search_term = '+' . preg_replace( '/\s+(?!-|~)/', " +", $search_term );
}
}
return array( 'search_term' => $search_term, 'removed' => $removedTerms );
}
/**
* Restrict the date range that the search is performed on
*
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
$this->search_begin_timestamp = $begin;
$this->search_end_timestamp = $end;
}
/**
* mySQL function for adding special search conditions
*
* @access public
* @param string $column sql table column for this condition
* @param string $operator Operation to perform for this condition, ex: =, <>, IN, NOT IN
* @param mixed $value Value to check with
* @param string $comp Comparison type
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
$column = $this->remapColumn( $column );
if ( $column == 'app' OR ! $column )
{
return;
}
/* Build the condition based on operator */
switch( strtoupper( $operator ) )
{
case 'IN':
case 'NOT IN':
$this->whereConditions[$comp][] = "{$column} {$operator} ( {$value} )";
break;
default:
$this->whereConditions[$comp][] = "{$column} {$operator} {$value}";
break;
}
}
/**
* Remap standard columns (Apps can override )
*
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return @e void
*/
public function remapColumn( $column )
{
return $column;
}
/**
* Allows you to specify multiple conditions that are chained together
*
* @access public
* @param array $conditions Array of conditions, each element has 3 keys: column, operator, value, see the setCondition function for information on each
* @param string $inner_comp Comparison operator to use inside the chain
* @param string $outer_comp Comparison operator to use outside the chain
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
/* Loop through the conditions to build the statement */
$_temp = array();
foreach( $conditions as $r )
{
/* REMAP */
$r['column'] = $r['column'] == 'type_id' ? 't.forum_id' : $r['column'];
if( $r['column'] == 'app' )
{
continue;
}
switch( strtoupper( $r['operator'] ) )
{
case 'IN':
case 'NOT IN':
$_temp[] = "{$r['column']} {$r['operator']} ( {$r['value']} )";
break;
default:
$_temp[] = "{$r['column']} {$r['operator']} {$r['value']}";
break;
}
}
$this->whereConditions[$outer_comp][] = '( ' . implode( $_temp, ' ' . $inner_comp . ' ' ) . ' ) ';
}
}
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* Global Search
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 10914 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_engine
{
/**
* Date range restriction start
*
* @access protected
* @var integer
*/
protected $search_begin_timestamp = 0;
/**
* Date range restriction end
*
* @access protected
* @var integer
*/
protected $search_end_timestamp = 0;
/**
* Array of conditions for this search
*
* @access protected
* @var array
*/
protected $whereConditions = array();
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
}
/**
* Perform a search.
* Returns an array of a total count (total number of matches)
* and an array of IDs matching the required number based on pagination. The ids returned would be based on the filters and type of search
*
* So if we had 1000 replies, and we are on page 2 of 25 per page, we'd return 25 items offset by 25
*
* @access public
* @return array
*/
public function search()
{
/* Per app class handles this */
throw new Exception("NO_SEARCH_AVAILABLE");
}
/**
* Perform the viewNewContent search
* Generic version
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewUserContent( $member )
{
$app = IPSSearchRegistry::get('in.search_app');
//IPSSearchRegistry::set('in.search_sort_by' , 'date' );
//IPSSearchRegistry::set('in.search_sort_order', 'desc' );
IPSSearchRegistry::set('opt.searchTitleOnly', IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
$this->setCondition( 'member_id', '=', $member['member_id'] );
/* Cut by date for efficiency? */
if ( $this->settings['search_ucontent_days'] )
{
$begin = time() - ( 86400 * intval( $this->settings['search_ucontent_days'] ) );
$this->setDateRange( $begin, time() );
}
return $this->search();
}
/**
* Can handle boolean searching
*
* @access public
* @return boolean
*/
public function isBoolean()
{
return ( $this->settings['use_fulltext'] AND $this->DB->checkBooleanFulltextSupport() ) ? TRUE : FALSE;
}
/**
* Formats search term for SQL
*
* @access private
* @param string Raw IPB santized form input
* @return array array( 'search_term' => Safe string to use in SQL, 'removed' => array of removed search terms )
*/
public function formatSearchTerm( $search_term )
{
$isBoolean = $this->isBoolean();
$andor = !empty( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$removedTerms = array();
/* Fix up some sanitized HTML */
$search_term = str_replace( "&amp;" , '&' , IPSText::parseCleanValue( rawurldecode( $search_term ) ) );
if( $isBoolean )
{
$search_term = str_replace( "&quot;" , '"' , $search_term );
}
else
{
$search_term = str_replace( "&quot;" , '' , $search_term );
}
$search_term = IPSText::mbstrtolower( $search_term );
/* Check for disallowed search terms */
while( preg_match_all( '/(?:^|\s+)(img|quote|code|html|javascript|a href|color|span|div|border|style)(?:\s+|$)/', $search_term, $removed_search_terms ) )
{
$removedTerms[] = $removed_search_terms[0][0];
$search_term = preg_replace( '/(^|\s+)(?:img|quote|code|html|javascript|a href|color|span|div|border|style)(\s+|$)/', str_replace( " ", " ", "$1$2" ), $search_term );
}
/* remove < min char words */
if ( substr_count( $search_term, '"' ) != 2 )
{
$_words = explode( ' ', $search_term );
$search_term = '';
foreach( $_words as $_w )
{
if ( IPSText::mbstrlen( $_w ) >= $this->settings['min_search_word'] )
{
$search_term .= $_w . ' ';
}
else
{
$removedTerms[] = $_w;
}
}
}
/* Remove some formatting */
//$search_term = str_replace( array( '|', '\\', '/' ), '', $search_term );
// | is an OR operator for sphinx - don't want to block globally
$search_term = str_replace( array( '\\', '/' ), '', trim( $search_term ) );
/* got some bullean to do? */
if ( $isBoolean AND strstr( $search_term, ' ' ) AND ! strstr( $search_term, '"' ) )
{
if ( $andor == 'and' )
{
$search_term = '+' . preg_replace( '/\s+(?!-|~)/', " +", $search_term );
}
}
return array( 'search_term' => $search_term, 'removed' => $removedTerms );
}
/**
* Restrict the date range that the search is performed on
*
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
$this->search_begin_timestamp = $begin;
$this->search_end_timestamp = $end;
}
/**
* mySQL function for adding special search conditions
*
* @access public
* @param string $column sql table column for this condition
* @param string $operator Operation to perform for this condition, ex: =, <>, IN, NOT IN
* @param mixed $value Value to check with
* @param string $comp Comparison type
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
$column = $this->remapColumn( $column );
if ( $column == 'app' OR ! $column )
{
return;
}
/* Build the condition based on operator */
switch( strtoupper( $operator ) )
{
case 'IN':
case 'NOT IN':
$this->whereConditions[$comp][] = "{$column} {$operator} ( {$value} )";
break;
default:
$this->whereConditions[$comp][] = "{$column} {$operator} {$value}";
break;
}
}
/**
* Remap standard columns (Apps can override )
*
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return @e void
*/
public function remapColumn( $column )
{
return $column;
}
/**
* Allows you to specify multiple conditions that are chained together
*
* @access public
* @param array $conditions Array of conditions, each element has 3 keys: column, operator, value, see the setCondition function for information on each
* @param string $inner_comp Comparison operator to use inside the chain
* @param string $outer_comp Comparison operator to use outside the chain
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
/* Loop through the conditions to build the statement */
$_temp = array();
foreach( $conditions as $r )
{
/* REMAP */
$r['column'] = $r['column'] == 'type_id' ? 't.forum_id' : $r['column'];
if( $r['column'] == 'app' )
{
continue;
}
switch( strtoupper( $r['operator'] ) )
{
case 'IN':
case 'NOT IN':
$_temp[] = "{$r['column']} {$r['operator']} ( {$r['value']} )";
break;
default:
$_temp[] = "{$r['column']} {$r['operator']} {$r['value']}";
break;
}
}
$this->whereConditions[$outer_comp][] = '( ' . implode( $_temp, ' ' . $inner_comp . ' ' ) . ' ) ';
}
}
+250 -250
View File
@@ -1,250 +1,250 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2011-07-08 15:07:09 -0400 (Fri, 08 Jul 2011) $
* </pre>
*
* @author $Author: ips_terabyte $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://hatynka.in
* @version $Rev: 9189 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_format
{
/**
* Search templates to use
*
* @access protected
* @var array
*/
protected $templates = array();
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
/* Set up default wrapper */
$this->templates = array( 'group' => 'search', 'template' => 'searchResults' );
// Need to setup this manually here, won't work in the template..
$this->registry->templateStriping['searchResults'] = array( FALSE, "row1", "row2" );
}
/**
* Fetch templates to use
*
* @access public
* @return array
*/
public function fetchTemplates()
{
return $this->templates;
}
/**
* Wrapper for processResults() when called from 'Content I follow' view
*
* @param array $ids Ids
* @param array $followData Retrieve the follow meta data
* @return array
*/
public function processFollowedResults( $ids, $followData=array() )
{
/* Per app class handles this */
throw new Exception("NO_FORMAT_AVAILABLE");
}
/**
* Formats / grabs extra data for results
* Takes an array of IDS (can be IDs from anything) and returns an array of expanded data.
*
* @param array $ids Ids
* @return array
*/
public function processResults( $ids )
{
/* Per app class handles this */
throw new Exception("NO_FORMAT_AVAILABLE");
}
/**
* Reassigns fields in a generic way for results output
* DEFAULT METHOD: Just return data. This should be overriden in the apps
*
* @param array $r
* @return array
*/
public function genericizeResults( $r )
{
return $r;
}
/**
* Parse common search results
*
* @access private
* @param array $r Search result
* @return array $html Blocks of HTML
*/
public function parseAndFetchHtmlBlocks( $rows )
{
/* Forum stuff */
$sub = false;
$isVnc = false;
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$results = array();
/* loop and process */
if( is_array($rows) AND count($rows) )
{
foreach( $rows as $id => $r )
{
/* If basic search, strip the content - process only if we have content though */
if ( $r['content'] )
{
IPSText::getTextClass('bbcode')->parse_bbcode = 0;
IPSText::getTextClass('bbcode')->strip_quotes = 1;
IPSText::getTextClass('bbcode')->parsing_section = 'topics';
IPSText::getTextClass('bbcode')->parsing_mgroup = $r['member_group_id'];
IPSText::getTextClass('bbcode')->parsing_mgroup_others = $r['mgroup_others'];
$r['content'] = strip_tags( IPSText::getTextClass( 'bbcode' )->stripAllTags( $r['content'] ) );
$r['content'] = str_replace( array( '&lt;br&gt;', '&lt;br /&gt;' ), '', $r['content'] );
$r['content'] = trim( str_replace( array( "\n\n\n", "\n\n" ), "\n", str_replace( "\r", '', $r['content'] ) ) );
/* Highlight */
$r['content'] = IPSText::searchHighlight( $this->searchTruncate( $r['content'], $search_term ), $search_term );
}
/* Format title */
$r['content_title'] = IPSText::searchHighlight( $r['content_title'], $search_term );
/* Format content */
list( $html, $sub ) = $this->formatContent( $r );
$results[ $id ] = array( 'html' => $html, 'app' => $r['app'], 'type' => $r['type'], 'sub' => $sub, '_followData' => !empty($r['_followData']) ? $r['_followData'] : array() );
}
}
return $results;
}
/**
* Formats the forum search result for display
*
* @access public
* @param array $search_row Array of data
* @return mixed Formatted content, ready for display, or array containing a $sub section flag, and content
*/
public function formatContent( $data )
{
return array( $this->registry->output->getTemplate('search')->searchRowGenericFormat( $data ), 0 );
}
/**
* Function to trim the search result display around the the hit
*
* @access private
* @param string $haystack Full search result
* @param string $needle The search term
* @return string
*/
public function searchTruncate( $haystack, $needle )
{
/* Base on words */
$haystack = explode( " ", $haystack );
if( count( $haystack ) > 21 )
{
$_term_at = $this->searchInArray( $needle, $haystack );
if( $_term_at - 11 > 0 )
{
$begin = array_splice( $haystack, 0, $_term_at - 11 );
/* The term position will have changed now */
$_term_at = $this->searchInArray( $needle, $haystack );
}
if( $_term_at + 11 < count( $haystack ) )
{
$end = array_splice( $haystack, $_term_at + 11, count( $haystack ) );
}
}
else
{
$begin = array();
$end = array();
}
$haystack = implode( " ", $haystack );
if( is_array( $begin ) && count( $begin ) )
{
$haystack = '...' . $haystack;
}
if( is_array( $end ) && count( $end ) )
{
$haystack = $haystack . '...';
}
return $haystack;
}
/**
* Search array (array_search only finds exact instances)
*
* @access protected
* @param string "Needle"
* @param array Array of entries to search
* @return mixed Key of array, or false on failure
*/
public function searchInArray( $needle, $haystack )
{
if( !is_array( $haystack ) OR !count($haystack) OR ! $needle )
{
return false;
}
foreach( $haystack as $k => $v )
{
if( $v AND strpos( $v, $needle ) !== false )
{
return $k;
}
}
return false;
}
}
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* Global Search
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 10914 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class search_format
{
/**
* Search templates to use
*
* @access protected
* @var array
*/
protected $templates = array();
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
/* Make object */
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
$this->cache = $this->registry->cache();
$this->caches =& $this->registry->cache()->fetchCaches();
/* Set up default wrapper */
$this->templates = array( 'group' => 'search', 'template' => 'searchResults' );
// Need to setup this manually here, won't work in the template..
$this->registry->templateStriping['searchResults'] = array( FALSE, "row1", "row2" );
}
/**
* Fetch templates to use
*
* @access public
* @return array
*/
public function fetchTemplates()
{
return $this->templates;
}
/**
* Wrapper for processResults() when called from 'Content I follow' view
*
* @param array $ids Ids
* @param array $followData Retrieve the follow meta data
* @return array
*/
public function processFollowedResults( $ids, $followData=array() )
{
/* Per app class handles this */
throw new Exception("NO_FORMAT_AVAILABLE");
}
/**
* Formats / grabs extra data for results
* Takes an array of IDS (can be IDs from anything) and returns an array of expanded data.
*
* @param array $ids Ids
* @return array
*/
public function processResults( $ids )
{
/* Per app class handles this */
throw new Exception("NO_FORMAT_AVAILABLE");
}
/**
* Reassigns fields in a generic way for results output
* DEFAULT METHOD: Just return data. This should be overriden in the apps
*
* @param array $r
* @return array
*/
public function genericizeResults( $r )
{
return $r;
}
/**
* Parse common search results
*
* @access private
* @param array $r Search result
* @return array $html Blocks of HTML
*/
public function parseAndFetchHtmlBlocks( $rows )
{
/* Forum stuff */
$sub = false;
$isVnc = false;
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$results = array();
/* loop and process */
if( is_array($rows) AND count($rows) )
{
foreach( $rows as $id => $r )
{
/* If basic search, strip the content - process only if we have content though */
if ( $r['content'] )
{
IPSText::getTextClass('bbcode')->parse_bbcode = 0;
IPSText::getTextClass('bbcode')->strip_quotes = 1;
IPSText::getTextClass('bbcode')->parsing_section = 'topics';
IPSText::getTextClass('bbcode')->parsing_mgroup = $r['member_group_id'];
IPSText::getTextClass('bbcode')->parsing_mgroup_others = $r['mgroup_others'];
$r['content'] = strip_tags( IPSText::getTextClass( 'bbcode' )->stripAllTags( $r['content'] ) );
$r['content'] = str_replace( array( '&lt;br&gt;', '&lt;br /&gt;' ), '', $r['content'] );
$r['content'] = trim( str_replace( array( "\n\n\n", "\n\n" ), "\n", str_replace( "\r", '', $r['content'] ) ) );
/* Highlight */
$r['content'] = IPSText::searchHighlight( $this->searchTruncate( $r['content'], $search_term ), $search_term );
}
/* Format title */
$r['content_title'] = IPSText::searchHighlight( $r['content_title'], $search_term );
/* Format content */
list( $html, $sub ) = $this->formatContent( $r );
$results[ $id ] = array( 'html' => $html, 'app' => $r['app'], 'type' => $r['type'], 'sub' => $sub, '_followData' => !empty($r['_followData']) ? $r['_followData'] : array() );
}
}
return $results;
}
/**
* Formats the forum search result for display
*
* @access public
* @param array $search_row Array of data
* @return mixed Formatted content, ready for display, or array containing a $sub section flag, and content
*/
public function formatContent( $data )
{
return array( $this->registry->output->getTemplate('search')->searchRowGenericFormat( $data ), 0 );
}
/**
* Function to trim the search result display around the the hit
*
* @access private
* @param string $haystack Full search result
* @param string $needle The search term
* @return string
*/
public function searchTruncate( $haystack, $needle )
{
/* Base on words */
$haystack = explode( " ", $haystack );
if( count( $haystack ) > 21 )
{
$_term_at = $this->searchInArray( $needle, $haystack );
if( $_term_at - 11 > 0 )
{
$begin = array_splice( $haystack, 0, $_term_at - 11 );
/* The term position will have changed now */
$_term_at = $this->searchInArray( $needle, $haystack );
}
if( $_term_at + 11 < count( $haystack ) )
{
$end = array_splice( $haystack, $_term_at + 11, count( $haystack ) );
}
}
else
{
$begin = array();
$end = array();
}
$haystack = implode( " ", $haystack );
if( is_array( $begin ) && count( $begin ) )
{
$haystack = '...' . $haystack;
}
if( is_array( $end ) && count( $end ) )
{
$haystack = $haystack . '...';
}
return $haystack;
}
/**
* Search array (array_search only finds exact instances)
*
* @access protected
* @param string "Needle"
* @param array Array of entries to search
* @return mixed Key of array, or false on failure
*/
public function searchInArray( $needle, $haystack )
{
if( !is_array( $haystack ) OR !count($haystack) OR ! $needle )
{
return false;
}
foreach( $haystack as $k => $v )
{
if( $v AND strpos( $v, $needle ) !== false )
{
return $k;
}
}
return false;
}
}
@@ -1,10 +1,10 @@
<html>
<head><title>IP.Board - Bulletin Board System</title></head>
<body>
<h1>403: IP.Board -&gt; Forbidden</h1>
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
<html>
<head><title>IP.Board - Bulletin Board System</title></head>
<body>
<h1>403: IP.Board -&gt; Forbidden</h1>
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
</html>