Version 3.2.3

This commit is contained in:
Neo committed 2025-12-19 00:34:03 -08:00
1 parent ae5c01cc78
commit 78706903a2
2641 files changed
+228363 -201264

No files matched your search

+124 -122
View File
@@ -2,18 +2,18 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2010-02-22 17:06:11 +0000 (Mon, 22 Feb 2010) $
* Last Updated: $Date: 2011-09-09 08:14:40 -0400 (Fri, 09 Sep 2011) $
* </pre>
*
* @author $Author: matt $
* @author $Author: mmecham $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 5859 $
* @link http://hatynka.in
* @version $Rev: 9474 $
*/
if ( ! defined( 'IN_IPB' ) )
@@ -32,7 +32,7 @@ class IPSSearchRegistry {
* Registry vars
* @var array
*/
static private $_vars = array();
static protected $_vars = array();
/**
* Set var
@@ -60,6 +60,36 @@ class IPSSearchRegistry {
return null;
}
/**
* Get is title only
*
*/
static public function searchTitleOnly()
{
if ( self::get('opt.searchType') == 'titles' )
{
return true;
}
if ( self::get('opt.searchType') == 'both' )
{
return false;
}
if ( self::get('opt.searchType') == 'content' )
{
return false;
}
if ( self::get('opt.noPostPreview') )
{
return true;
}
return false;
}
}
/**
@@ -81,7 +111,9 @@ class IPSSearch
protected $request;
protected $lang;
protected $member;
protected $memberData;
protected $cache;
protected $caches;
/**#@-*/
/**
@@ -89,42 +121,42 @@ class IPSSearch
*
* @var object
*/
private $SEARCH;
protected $SEARCH;
/**
* Plug in for formatting results
*
* @var object
*/
private $FORMAT;
protected $FORMAT;
/**
* App
*
* @var string
*/
private $_app;
protected $_app;
/**
* Engine
*
* @var string
*/
private $_engine;
protected $_engine;
/**
* Result count
*
* @param int
*/
private $_count;
protected $_count;
/**
* Result array
*
* @param array
*/
private $_results;
protected $_results;
static public $aso;
static public $ask;
@@ -134,7 +166,7 @@ class IPSSearch
* Setup registry objects
*
* @param object ipsRegistry $registry
* @return void
* @return @e void
*/
public function __construct( ipsRegistry $registry, $engine, $app )
{
@@ -156,14 +188,14 @@ class IPSSearch
$this->_app = IPSText::alphanumericalClean( $app );
/* Quick check */
if ( ! file_exists( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' ) )
if ( ! is_file( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' ) )
{
/* Try SQL */
if ( ! $this->_engine != 'sql' )
{
$this->_engine = 'sql';
if ( ! file_exists( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' ) )
if ( ! is_file( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' ) )
{
throw new Exception( "NO_SUCH_ENGINE" );
}
@@ -184,43 +216,34 @@ class IPSSearch
IPSSearchRegistry::set( 'global.app' , $this->_app );
/* Load up the relevant engines */
$_className = 'search_' . $this->_engine;
require_once( IPS_ROOT_PATH . 'sources/classes/search/format.php' );
require_once( IPS_ROOT_PATH . 'sources/classes/search/format.php' );/*noLibHook*/
/* Got an app specific file? Lets hope so */
if ( file_exists( IPSLib::getAppDir( $this->_app ) . '/extensions/search/format.php' ) )
{
if ( is_file( IPSLib::getAppDir( $this->_app ) . '/extensions/search/format.php' ) )
{
/* We may not have sphinx specific stuff, so... */
if ( ! file_exists( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php' ) )
if ( ! is_file( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php' ) )
{
$this->_engine = 'sql';
if ( ! file_exists( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php' ) )
if ( ! is_file( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php' ) )
{
throw new Exception( "NO_SUCH_APP_ENGINE" );
}
}
require_once( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' );
require_once( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php' );
/* SEARCH classname */
$_className = 'search_engine_' . $this->_app;
$this->SEARCH = new $_className( $registry );
/* SEARCH file */
require_once( IPS_ROOT_PATH . 'sources/classes/search/engines/' . $this->_engine . '.php' );/*noLibHook*/
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $this->_app ) . '/extensions/search/engines/' . $this->_engine . '.php', 'search_engine_' . $this->_app, $this->_app );
$this->SEARCH = new $classToLoad( $registry );
/* FORMAT file */
require_once( IPSLib::getAppDir( $this->_app ) . '/extensions/search/format.php' );
/* FORMAT classname */
$_className = 'search_format_' . $this->_app;
$this->FORMAT = new $_className( $registry );
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $this->_app ) . '/extensions/search/format.php', 'search_format_' . $this->_app, $this->_app );
$this->FORMAT = new $classToLoad( $registry );
/* Grab config */
$CONFIG = array();
require( IPSLib::getAppDir( $this->_app ) . '/extensions/search/config.php' );
require( IPSLib::getAppDir( $this->_app ) . '/extensions/search/config.php' );/*noLibHook*/
if ( is_array( $CONFIG ) && count( $CONFIG ) )
{
@@ -239,7 +262,7 @@ class IPSSearch
if ( IPSSearchRegistry::get( 'config.contentTypes' ) )
{
$c = IPSSearchRegistry::get( 'config.contentTypes' );
if ( is_array( $c ) AND count( $c ) )
{
/* Set up default content type if supported */
@@ -281,6 +304,11 @@ class IPSSearch
case 'fetchSortDropDown':
return $this->SEARCH->fetchSortDropDown();
break;
/* Primarily shortcuts for 'Content I follow' */
case 'fetchFollowedContentOutput':
return $this->FORMAT->parseFollowedContentOutput( $args[0], $args[1] );
break;
}
}
@@ -297,14 +325,13 @@ class IPSSearch
/* results page? */
$filter = ( ! IPSSearchRegistry::get('view.search_form') AND IPSSearchRegistry::get( $app . '.searchInKey' ) ) ? IPSSearchRegistry::get( $app . '.searchInKey' ) : '';
if ( file_exists( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' ) )
if ( is_file( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' ) )
{
require_once( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' );
$_class = 'search_form_' . $app;
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $app ) . '/extensions/search/form.php', 'search_form_' . $app, $app );
if ( class_exists( $_class ) )
if ( class_exists( $classToLoad ) )
{
$_obj = new $_class();
$_obj = new $classToLoad();
$_dd = $_obj->fetchSortDropDown();
if ( $filter )
@@ -331,14 +358,13 @@ class IPSSearch
{
$app = ( $app ) ? $app : $this->_app;
if ( file_exists( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' ) )
if ( is_file( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' ) )
{
require_once( IPSLib::getAppDir( $app ) . '/extensions/search/form.php' );
$_class = 'search_form_' . $app;
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $app ) . '/extensions/search/form.php', 'search_form_' . $app, $app );
if ( class_exists( $_class ) )
if ( class_exists( $classToLoad ) )
{
$_obj = new $_class();
$_obj = new $classToLoad();
if ( method_exists( $_obj, 'fetchSortIn' ) )
{
@@ -370,17 +396,16 @@ class IPSSearch
continue;
}
if( IPSLib::appisSearchable( $app['app_directory'] ) )
if( IPSLib::appIsSearchable( $app['app_directory'] ) )
{
/* got custom filter? */
if ( file_exists( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/search/form.php' ) )
if ( is_file( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/search/form.php' ) )
{
require_once( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/search/form.php' );
$_class = 'search_form_' . $app['app_directory'];
if ( class_exists( $_class ) and method_exists( $_class, 'getHtml' ) )
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/search/form.php', 'search_form_' . $app['app_directory'], $app['app_directory'] );
if ( class_exists( $classToLoad ) and method_exists( $classToLoad, 'getHtml' ) )
{
$_obj = new $_class();
$_obj = new $classToLoad();
$filtersHtml[ $app['app_directory'] ] = $_obj->getHtml();
}
@@ -508,14 +533,53 @@ class IPSSearch
*/
public function viewNewContent()
{
IPSSearchRegistry::set('display.onlyTitles', true);
IPSSearchRegistry::set('opt.searchTitleOnly', true);
IPSSearchRegistry::set('in.period_in_seconds', false );
/* Hard fix mobile app users to VNC based on unread content */
/* Hard fix mobile app users to VNC based on ACP default VNC method */
if ( $this->member->isMobileApp )
{
$this->memberData['bw_vnc_type'] = 1;
IPSSearchRegistry::set( 'in.period', $this->settings['default_vnc_method'] );
}
/* Do we have a period? */
switch( IPSSearchRegistry::get('in.period') )
{
case 'today':
default:
$date = 86400; // 24 hours
break;
case 'week':
$date = 604800; // 1 week
break;
case 'weeks':
$date = 1209600; // 2 weeks
break;
case 'month':
$date = 2592000; // 30 days
break;
case 'months':
$date = 15552000; // 6 months
break;
case 'year':
$date = 31536000; // 365 days
break;
case 'lastvisit':
$date = time() - intval( $this->memberData['last_visit'] );
break;
case 'unread':
$date = false;
break;
}
/* Set date up */
IPSSearchRegistry::set('in.period_in_seconds', $date );
/* Run the search */
$results = $this->SEARCH->viewNewContent();
@@ -558,74 +622,12 @@ class IPSSearch
}
}
/**
* Perform the search
*
* @return nothin'
*/
public function viewActiveContent()
{
/* Bit 'o set up */
IPSSearchRegistry::set('opt.searchTitleOnly', IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('display.onlyTitles', true);
IPSSearchRegistry::set('opt.searchTitleOnly', true);
/* Do we have a period? */
switch( IPSSearchRegistry::get('in.period') )
{
case 'today':
default:
$date = 86400; // 24 hours
break;
case 'week':
$date = 604800; // 1 week
break;
case 'weeks':
$date = 1209600; // 2 weeks
break;
case 'month':
$date = 2592000; // 30 days
break;
case 'months':
$date = 15552000; // 6 months
break;
case 'year':
$date = 31536000; // 365 days
break;
}
/* Set date up */
IPSSearchRegistry::set('in.period_in_seconds', $date );
/* Run the search */
$results = $this->SEARCH->viewActiveContent();
/* Set data */
$this->_count = intval( $results['count'] );
$this->_results = $results['resultSet'];
/* Now format results */
if ( count( $this->_results ) )
{
$this->_results = $this->FORMAT->processResults( $this->_results );
/* Now generate HTML */
$this->_results = $this->FORMAT->parseAndFetchHtmlBlocks( $this->_results );
}
}
/**
* Flag a search session
*
* @return int Process ID
*/
private function _startSession()
protected function _startSession()
{
/**
* If we've already run a search and it's not clear, kill it now
@@ -655,7 +657,7 @@ class IPSSearch
*
* @return void
*/
private function _endSession( $processId )
protected function _endSession( $processId )
{
if ( $processId )
{
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionboard.com/">IP.Board</a>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
</html>
@@ -2,18 +2,18 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2010-02-19 01:29:54 +0000 (Fri, 19 Feb 2010) $
* Last Updated: $Date: 2011-08-08 07:05:57 -0400 (Mon, 08 Aug 2011) $
* </pre>
*
* @author $Author: josh $
* @author $Author: mmecham $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 5855 $
* @link http://hatynka.in
* @version $Rev: 9376 $
*/
if ( ! defined( 'IN_IPB' ) )
@@ -61,7 +61,7 @@ class search_engine
*
* @access public
* @param object ipsRegistry $registry
* @return void
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
@@ -77,13 +77,13 @@ class search_engine
$this->caches =& $this->registry->cache()->fetchCaches();
/* Do we have the sphinxes? */
if( ! file_exists( 'sphinxapi.php' ) )
if( ! is_file( 'sphinxapi.php' ) )
{
$registry->output->showError( 'sphinx_api_missing', 10182 );
}
/* Load Sphinx */
require( 'sphinxapi.php' );
require( 'sphinxapi.php' );/*noLibHook*/
$this->sphinxClient = new SphinxClient();
$this->sphinxClient->SetServer( $this->settings['search_sphinx_server'], intval( $this->settings['search_sphinx_port'] ) );
@@ -117,13 +117,14 @@ class search_engine
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$lastActive = IPSLib::fetchHighestNumber( array( intval( $this->memberData['_cache']['gb_mark__' . $app] ), intval( $this->memberData['last_visit'] ) ) );
$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' );
$this->setDateRange( $lastActive, time() );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
@@ -145,7 +146,6 @@ class search_engine
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('display.onlyTitles' , IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
@@ -162,23 +162,6 @@ class search_engine
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewActiveContent()
{
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
/* Set time stamp */
$this->setDateRange( time() - $seconds, time() );
return $this->search();
}
/**
* Can handle boolean searching
*
@@ -209,10 +192,10 @@ class search_engine
$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 ) )
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 );
$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 */
@@ -221,11 +204,11 @@ class search_engine
$search_term = str_replace( array( '\\', '/' ), '', $search_term );
/* Sphinx chars are not allowed */
$search_term = str_replace( array( '.', ')', '(', '!', '@', '[', ']' ), '', $search_term );
$search_term = str_replace( array( '.', ')', '(', '!', '@', '[', ']', '-', '~', '^' ), '', $search_term );
if ( $andor == 'or' )
{
$search_term = preg_replace( "/\s+(?!-|~)/", " | ", $search_term );
$search_term = preg_replace( '/\s+/', " | ", $search_term );
}
return array( 'search_term' => $search_term, 'removed' => $removedTerms );
@@ -237,10 +220,12 @@ class search_engine
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return void
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
$begin = ( $begin < 1000000000 ) ? 1000000000 : $begin;
$this->search_begin_timestamp = $begin;
$this->search_end_timestamp = $end;
}
@@ -251,7 +236,7 @@ class search_engine
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return void
* @return @e void
*/
public function remapColumn( $column )
{
@@ -266,7 +251,7 @@ class search_engine
* @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 void
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
@@ -316,7 +301,7 @@ class search_engine
* @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 void
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
@@ -328,7 +313,7 @@ class search_engine
* Checks and logs any errors
*
* @access public
* @return void
* @return @e void
*/
public function logSphinxWarnings()
{
@@ -2,18 +2,18 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2010-02-22 17:06:11 +0000 (Mon, 22 Feb 2010) $
* Last Updated: $Date: 2011-05-05 07:03:47 -0400 (Thu, 05 May 2011) $
* </pre>
*
* @author $Author: matt $
* @author $Author: ips_terabyte $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 5859 $
* @link http://hatynka.in
* @version $Rev: 8644 $
*/
if ( ! defined( 'IN_IPB' ) )
@@ -53,7 +53,7 @@ class search_engine
*
* @access public
* @param object ipsRegistry $registry
* @return void
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
@@ -95,13 +95,14 @@ class search_engine
*/
public function viewNewContent()
{
$app = IPSSearchRegistry::get('in.search_app');
$lastActive = IPSLib::fetchHighestNumber( array( intval( $this->memberData['_cache']['gb_mark__' . $app] ), intval( $this->memberData['last_visit'] ) ) );
$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' );
$this->setDateRange( $lastActive, time() );
/* Set time stamp */
$this->setDateRange( intval( time() - $seconds ), time() );
/* Force title search only */
IPSSearchRegistry::set('opt.searchTitleOnly', true);
@@ -120,10 +121,9 @@ class search_engine
{
$app = IPSSearchRegistry::get('in.search_app');
IPSSearchRegistry::set('in.search_sort_by' , 'date' );
IPSSearchRegistry::set('in.search_sort_order', 'desc' );
//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('display.onlyTitles' , IPSSearchRegistry::get('in.view_by_title') );
IPSSearchRegistry::set('opt.noPostPreview' , IPSSearchRegistry::get('in.view_by_title') );
/* Set the member_id */
@@ -140,23 +140,6 @@ class search_engine
return $this->search();
}
/**
* Perform the search
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewActiveContent()
{
$seconds = IPSSearchRegistry::get('in.period_in_seconds');
/* Set time stamp */
$this->setDateRange( time() - $seconds, time() );
return $this->search();
}
/**
* Can handle boolean searching
*
@@ -178,7 +161,7 @@ class search_engine
public function formatSearchTerm( $search_term )
{
$isBoolean = $this->isBoolean();
$andor = isset( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$andor = !empty( $this->request['andor_type'] ) ? $this->request['andor_type'] : $this->settings['s_andor_type'];
$removedTerms = array();
/* Fix up some sanitized HTML */
@@ -196,23 +179,23 @@ class search_engine
$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 ) )
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 );
$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 );
$search_term = '+' . preg_replace( '/\s+(?!-|~)/', " +", $search_term );
}
}
@@ -225,7 +208,7 @@ class search_engine
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return void
* @return @e void
*/
public function setDateRange( $begin, $end=0 )
{
@@ -241,7 +224,7 @@ class search_engine
* @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 void
* @return @e void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
@@ -272,7 +255,7 @@ class search_engine
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return void
* @return @e void
*/
public function remapColumn( $column )
{
@@ -286,7 +269,7 @@ class search_engine
* @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 void
* @return @e void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
+58 -37
View File
@@ -2,18 +2,18 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* IP.Board v3.2.3
* Global Search
* Last Updated: $Date: 2010-02-22 17:06:11 +0000 (Mon, 22 Feb 2010) $
* Last Updated: $Date: 2011-07-08 15:07:09 -0400 (Fri, 08 Jul 2011) $
* </pre>
*
* @author $Author: matt $
* @author $Author: ips_terabyte $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @license This is NULLED!
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 5859 $
* @link http://hatynka.in
* @version $Rev: 9189 $
*/
if ( ! defined( 'IN_IPB' ) )
@@ -37,7 +37,7 @@ class search_format
*
* @access public
* @param object ipsRegistry $registry
* @return void
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
@@ -54,6 +54,9 @@ class search_format
/* 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" );
}
/**
@@ -67,11 +70,24 @@ class search_format
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.
*
* @access public
* @param array $ids Ids
* @return array
*/
public function processResults( $ids )
@@ -86,7 +102,7 @@ class search_format
*
* @param array $r
* @return array
**/
*/
public function genericizeResults( $r )
{
return $r;
@@ -102,36 +118,41 @@ class search_format
public function parseAndFetchHtmlBlocks( $rows )
{
/* Forum stuff */
$sub = false;
$isVnc = false;
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$results = array();
$sub = false;
$isVnc = false;
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$results = array();
/* loop and process */
foreach( $rows as $id => $r )
if( is_array($rows) AND count($rows) )
{
/* If basic search, strip the content */
IPSText::getTextClass( 'bbcode' )->parse_wordwrap = 0;
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 );
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'];
/* Format title */
$r['content_title'] = IPSText::searchHighlight( $r['content_title'], $search_term );
$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'] ) ) );
/* Format content */
list( $html, $sub ) = $this->formatContent( $r );
$results[ $id ] = array( 'html' => $html, 'app' => $r['app'], 'type' => $r['type'], 'sub' => $sub );
/* 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;
@@ -143,10 +164,10 @@ class search_format
* @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 );
return array( $this->registry->output->getTemplate('search')->searchRowGenericFormat( $data ), 0 );
}
/**
@@ -156,7 +177,7 @@ class search_format
* @param string $haystack Full search result
* @param string $needle The search term
* @return string
**/
*/
public function searchTruncate( $haystack, $needle )
{
/* Base on words */
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionboard.com/">IP.Board</a>
<a href="http://www.invisionpower.com">IP.Board</a>
</body>
</html>
@@ -1,511 +0,0 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* Global Search
* Last Updated: $Date: 2010-09-27 18:18:35 -0400 (Mon, 27 Sep 2010) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @package IP.Board
* @subpackage Core
* @link http://www.invisionpower.com
* @version $Rev: 6917 $
*/
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 searchPluginSphinxIndex implements iSearchIndexPlugin
{
/**
* Database object
*
* @access private
* @var object
*/
private $DB;
/**
* Date range restriction start
*
* @access private
* @var integer
*/
private $search_begin_timestamp = 0;
/**
* Date range restriction end
*
* @access private
* @var integer
*/
private $search_end_timestamp = 0;
/**
* Array of conditions for this search
*
* @access private
* @var array
*/
private $whereConditions = array();
/**
* Apps to exclude
*
* @access public
* @var array
*/
public $exclude_apps = array();
/**
* Sphinx client object
*
* @access public
* @var object
*/
public $sphinxClient;
/**
* Don't show post preview
*
* @access public
* @var boolean
*/
public $noPostPreview = false;
/**
* Do not join posts table on
*
* @access public
* @var boolean
*/
public $onlyTitles = false;
/**
* Search plugin for the application
*
* @access public
* @var object
*/
public $appSearchPlugin;
/**
* Setup registry objects
*
* @access public
* @param object ipsRegistry $registry
* @return void
*/
public function __construct( ipsRegistry $registry )
{
$this->DB = $registry->DB();
$this->member = $registry->member();
$this->memberData =& $registry->member()->fetchMemberData();
$this->settings = $registry->settings();
$this->request = $registry->request();
/* Do we have the sphinxes? */
if( ! file_exists( 'sphinxapi.php' ) )
{
$registry->output->showError( 'sphinx_api_missing', 10182 );
}
/* Load Sphinx */
require( 'sphinxapi.php' );
$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 );
/* We're going to need the regular app index plugin also */
require_once( IPSLib::getAppDir( ipsRegistry::$request[ 'search_app' ] ) . '/extensions/searchPlugin.php' );
$searchApp = 'search' . ucfirst( $this->request['search_app'] ) . 'Plugin';
$this->appSearchPlugin = new $searchApp( $registry );
}
/**
* Performs search and returns an array of results
*
* @access public
* @param string $search_term
* @param array $limit_clause The erray should be array( begin, end )
* @param string $sort_by Column to sort by
* @param string $group_by Column to group by
* @param bool $content_title_only Only search title records
* @return array
*/
public function getSearchResults( $search_term, $limit_clause, $sort_by, $group_by='', $content_title_only=false )
{
$search_term = str_replace( '&quot;', '"', $search_term );
$search_term = str_replace( '&amp;', '&', $search_term );
$search_term = str_replace( '&#33;', '!', $search_term );
/* Do the search */
$results = $this->_searchQuery( $search_term, $limit_clause, $sort_by, $group_by, false, $content_title_only );
/* Build result array */
$rows = array();
if( is_array( $results ) && count( $results ) )
{
$q = $this->appSearchPlugin->getResultsForSphinx( $results );
while( $r = $this->DB->fetch( $q ) )
{
$rows[] = $this->appSearchPlugin->formatFieldsForIndex( $r );
}
}
return $rows;
}
/**
* Performs live search and returns an array of results
* NOT AVAILABLE IN BASIC SEARCH
*
* @access public
* @param string $search_term
* @return array
*/
public function getLiveSearchResults( $search_term )
{
if( ipsRegistry::$settings['live_search_disable'] )
{
return array();
}
}
/**
* Returns the total number of results the search will return
*
* @access public
* @param string $search_term Search term
* @param string $group_by Column to group by
* @param bool $content_title_only Only search title records
* @return integer
*/
public function getSearchCount( $search_term, $group_by='', $content_title_only=false )
{
$search_term = str_replace( '&quot;', '"', $search_term );
$search_term = str_replace( '&amp;', '&', $search_term );
$search_term = str_replace( '&#33;', '!', $search_term );
/* Return the count */
return $this->_searchQuery( $search_term, array(), '', '', true, $content_title_only );
}
/**
* Restrict the date range that the search is performed on
*
* @access public
* @param int $begin Start timestamp
* @param int [$end] End timestamp
* @return void
*/
public function setDateRange( $begin, $end=0 )
{
$this->sphinxClient->SetFilterRange( $this->appSearchPlugin->getDateField(), $begin, $end );
}
/**
* Set search conditions for "View unread content"
*
* @access public
* @return void
*/
public function setUnreadConditions()
{
$this->setDateRange( intval( $this->memberData['last_visit'] ), time() );
}
/**
* 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 void
*/
public function setCondition( $column, $operator, $value, $comp='AND' )
{
/* This is restricted by the indexes searched */
if( $column == 'app' )
{
return;
}
$column = $this->appSearchPlugin->getConditionField( $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>Не существующий оператор: {$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 void
*/
public function setMultiConditions( $conditions, $inner_comp='OR', $outer_comp='AND' )
{
//echo "<b>setMultiCondidion</b> should not be used in sphinx<br />";
return;
}
/**
* Does search
*
* @access private
* @param string $search_term
* @param array $limit_clause The erray should be array( begin, end )
* @param string $sort_by Either relevance or date
* @param string [$group_by] Field to group on
* @param bool [$count_only] Set to true for a count(*) query
* @param bool [$content_title_only] Only search titles
* @return array
**/
private function _searchQuery( $search_term, $limit_clause, $sort_by, $group_by='', $count_only=false, $content_title_only=false )
{
/* Do we only need to count results? */
if( ! $count_only )
{
if( $limit_clause[1] )
{
/* Limit Results */
$this->sphinxClient->SetLimits( intval($limit_clause[0]), intval($limit_clause[1]) );
}
else if( $limit_clause[0] )
{
$this->sphinxClient->SetLimits( 0, intval($limit_clause[0]) );
}
/* Sort By */
if( isset( $sort_by ) && in_array( $sort_by, array( 'date', 'relevance' ) ) )
{
if( $sort_by == 'date' )
{
if( $this->request['search_sort_order'] == 0 )
{
$this->sphinxClient->SetSortMode( SPH_SORT_ATTR_DESC, $this->appSearchPlugin->getDateField() /* Sigh */ );
}
else
{
$this->sphinxClient->SetSortMode( SPH_SORT_ATTR_ASC, $this->appSearchPlugin->getDateField() /* Sigh */ );
}
}
else
{
$this->sphinxClient->SetSortMode( SPH_SORT_RELEVANCE );
}
}
else
{
$this->sphinxClient->SetSortMode( SPH_SORT_RELEVANCE );
}
}
/* Exclude Apps */
if( count( $this->exclude_apps ) )
{
$app_id_exclude = array();
foreach( $this->exclude_apps as $app_dir )
{
$app_id_exclude[] = ipsRegistry::$applications[$app_dir]['app_id'];
}
$this->sphinxClient->SetFilter( 'app', $app_id_exclude, TRUE );
}
/* Permissions */
$perm_array = $this->member->perm_id_array;
$perm_array[] = 0;
/* Need to remove empty values... */
$final_perms = array();
foreach( $perm_array as $perm_id )
{
if( is_numeric( $perm_id ) )
{
$final_perms[] = intval($perm_id);
}
}
$this->sphinxClient->SetFilter( 'perm_view', $final_perms );
/* Exclude some items */
if( ! $this->memberData['g_is_supmod'] )
{
/* Owner only */
$this->sphinxClient->SetFilter( 'owner_only', array( 0, intval($this->memberData['member_id']) ) );
/* Friend only */
$this->DB->build( array(
'select' => 'friends_member_id',
'from' => 'profile_friends',
'where' => "friends_friend_id={$this->memberData['member_id']}"
) );
$this->DB->execute();
$friends_ids = array( 0 );
while( $r = $this->DB->fetch() )
{
$friends_ids[] = intval($r['friends_member_id']);
}
$this->sphinxClient->SetFilter( 'friend_only', $friends_ids );
/* Authorized users only */
$this->sphinxClient->SetFilter( 'authorized_users', array( 0, intval($this->memberData['member_id']) ) );
}
//-----------------------------------------
// Allow app to modify query
//-----------------------------------------
if( ! isset( $this->display_plugins[ $this->request['search_app'] ] ) || ! $this->display_plugins[ $this->request['search_app'] ] )
{
if( file_exists( IPSLib::getAppDir( $this->request['search_app'] ) . '/extensions/searchDisplay.php' ) )
{
require_once( IPSLib::getAppDir( $this->request['search_app'] ) . '/extensions/searchDisplay.php' );
$_class = strtolower($this->request['search_app']) . 'SearchDisplay';
$this->display_plugins[ $this->request['search_app'] ] = new $_class();
}
else
{
return false;
}
}
$this->appSearchPlugin->onlyTitles = $this->onlyTitles;
$this->appSearchPlugin->noPostPreview = $this->noPostPreview;
$this->display_plugins[ $this->request['search_app'] ]->search_plugin = $this->appSearchPlugin;
if( method_exists( $this->display_plugins[ $this->request['search_app'] ], 'modifySearchQuery' ) )
{
/* Get the modified query */
$this->display_plugins[ $this->request['search_app'] ]->modifySearchQuery( $this->sphinxClient, $count_only );
}
$groupby = $this->onlyTitles ? true : false;
/* Perform the search */
if( method_exists( $this->display_plugins[ $this->request['search_app'] ], 'runSearchQuery' ) )
{
$result = $this->display_plugins[ $this->request['search_app'] ]->runSearchQuery( $this->sphinxClient, $search_term, $groupby );
}
else
{
if( $groupby )
{
$this->sphinxClient->SetGroupBy( 'search_id', SPH_GROUPBY_ATTR, '@group DESC');
}
$result = $this->sphinxClient->Query( $search_term, $this->request['search_app'] . '_search_main,' . $this->request['search_app'] . '_search_delta' );
}
/* Return the total number of results */
if( $count_only )
{
return $result['total'];
}
/* Return the results */
else
{
$search_ids = array();
if( is_array( $result['matches'] ) && count( $result['matches'] ) )
{
foreach( $result['matches'] as $res )
{
$search_ids[] = $res['attrs']['search_id'];
}
}
return $search_ids;
}
}
/**
* Reassigns fields in a way the index exepcts
*
* @param array $r
* @return array
**/
public function formatFieldsForIndex( $r )
{
// Blank
}
/**
* This function grabs the actual results for display
*
* @param array $ids
* @return query result
**/
public function getResultsForSphinx( $ids )
{
// Blank
}
/**
* Get whether or not we're showing as forum or not
*
* @param public
* @return bool
*/
public function getShowAsForum()
{
if( method_exists( $this->appSearchPlugin, 'getShowAsForum' ) )
{
return $this->appSearchPlugin->getShowAsForum();
}
else
{
return false;
}
}
}