Version 3.0.5
This commit is contained in:
1 parent
19b38c7c74
commit
1d4720f3e2
3755 files changed
+508378
-664541
No files matched your search
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Global Search
|
||||
* Last Updated: $Date: 2009-03-04 07:36:56 -0500 (Wed, 04 Mar 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Board
|
||||
* @subpackage Core
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @version $Rev: 4135 $
|
||||
*/
|
||||
|
||||
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 searchPluginIndexIndex 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();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
/* Do the search */
|
||||
$this->DB->build( $this->_buildSearchQueryArray( $search_term, $limit_clause, $sort_by, $group_by, false, $content_title_only ) );
|
||||
$this->DB->execute();
|
||||
|
||||
/* Build result array */
|
||||
$rows = array();
|
||||
|
||||
while( $r = $this->DB->fetch() )
|
||||
{
|
||||
$rows[] = $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();
|
||||
}
|
||||
|
||||
/* Do the search */
|
||||
$this->DB->build( $this->_buildSearchQueryArray( $search_term, array( 0, 10 ), 'date' ) );
|
||||
$this->DB->execute();
|
||||
|
||||
/* Build result array */
|
||||
$rows = array();
|
||||
|
||||
while( $r = $this->DB->fetch() )
|
||||
{
|
||||
$rows[] = $r;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
/* Query the count */
|
||||
$this->DB->build( $this->_buildSearchQueryArray( $search_term, array(), '', $group_by, true, $content_title_only ) );
|
||||
$this->DB->execute();
|
||||
|
||||
/* Return the count */
|
||||
if( $group_by )
|
||||
{
|
||||
return $this->DB->getTotalRows();
|
||||
}
|
||||
else
|
||||
{
|
||||
$r = $this->DB->fetch();
|
||||
return $r['total_results'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->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 void
|
||||
*/
|
||||
public function setCondition( $column, $operator, $value, $comp='AND' )
|
||||
{
|
||||
/* Build the condition based on operator */
|
||||
switch( strtoupper( $operator ) )
|
||||
{
|
||||
case 'IN':
|
||||
case 'NOT IN':
|
||||
$this->whereConditions[$comp][] = "i.{$column} {$operator} ( {$value} )";
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->whereConditions[$comp][] = "i.{$column} {$operator} {$value}";
|
||||
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' )
|
||||
{
|
||||
/* Loop through the conditions to build the statement */
|
||||
$_temp = array();
|
||||
|
||||
foreach( $conditions as $r )
|
||||
{
|
||||
switch( strtoupper( $r['operator'] ) )
|
||||
{
|
||||
case 'IN':
|
||||
case 'NOT IN':
|
||||
$_temp[] = "i.{$r['column']} {$r['operator']} ( {$r['value']} )";
|
||||
break;
|
||||
|
||||
default:
|
||||
$_temp[] = "i.{$r['column']} {$r['operator']} {$r['value']}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->whereConditions[$outer_comp][] = '( ' . implode( $_temp, ' ' . $inner_comp . ' ' ) . ' ) ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reassigns fields in a way the index exepcts
|
||||
*
|
||||
* @param array $r
|
||||
* @return array
|
||||
**/
|
||||
public function formatFieldsForIndex( $r )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function grabs the actual results for display
|
||||
*
|
||||
* @param array $ids
|
||||
* @return query result
|
||||
**/
|
||||
public function getResultsForSphinx( $ids )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an array that can be used in build
|
||||
*
|
||||
* @access public
|
||||
* @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] Set to true to only search titles
|
||||
* @return array
|
||||
*/
|
||||
private function _buildSearchQueryArray( $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( $group_by )
|
||||
{
|
||||
$group_by = 'i.' . $group_by;
|
||||
}
|
||||
|
||||
$search_query_array = array(
|
||||
'select' => 'COUNT(*) as total_results',
|
||||
'from' => array( 'search_index' => 'i' ),
|
||||
'where' => $this->_buildWhereStatement( $search_term, $content_title_only ),
|
||||
'group' => $group_by,
|
||||
'add_join' => array(
|
||||
array(
|
||||
'from' => array( 'permission_index' => 'p' ),
|
||||
'where' => 'p.perm_type_id=i.type_id AND p.perm_type=i.type',
|
||||
'type' => 'left',
|
||||
),
|
||||
array(
|
||||
'from' => array( 'profile_friends' => 'friend' ),
|
||||
'where' => 'friend.friends_member_id=i.member_id AND friend.friends_friend_id=' . $this->memberData['member_id'],
|
||||
'type' => 'left',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sort By */
|
||||
if( isset( $sort_by ) && in_array( $sort_by, array( 'date', 'relevance', 'ascdate' ) ) )
|
||||
{
|
||||
$_ord = strstr( $sort_by, 'asc' ) ? 'ASC' : 'DESC';
|
||||
$order = $sort_by == 'date' ? 'i.updated ' . $_ord : 'ranking' . $_ord;
|
||||
}
|
||||
else
|
||||
{
|
||||
$order = 'ranking DESC';
|
||||
}
|
||||
|
||||
/* If there is no search term, we need to force search by updated */
|
||||
if( ! $search_term )
|
||||
{
|
||||
$order = 'i.updated DESC';
|
||||
}
|
||||
|
||||
if( $group_by )
|
||||
{
|
||||
$group_by = 'i.' . $group_by;
|
||||
}
|
||||
|
||||
if( $content_title_only )
|
||||
{
|
||||
$ranking_select = $search_term ? ", MATCH( i.content_title ) AGAINST( '{$search_term}' IN BOOLEAN MODE ) as ranking" : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ranking_select = $search_term ? ", MATCH( i.content, i.content_title ) AGAINST( '{$search_term}' IN BOOLEAN MODE ) as ranking" : '';
|
||||
}
|
||||
|
||||
/* Build the search query array */
|
||||
$search_query_array = array(
|
||||
'select' => "i.*{$ranking_select}",
|
||||
'from' => array( 'search_index' => 'i' ),
|
||||
'where' => $this->_buildWhereStatement( $search_term, $content_title_only ),
|
||||
'limit' => $limit_clause,
|
||||
'group' => $group_by,
|
||||
'order' => $order,
|
||||
'add_join' => array(
|
||||
array(
|
||||
'select' => 'p.perm_view',
|
||||
'from' => array( 'permission_index' => 'p' ),
|
||||
'where' => 'p.perm_type_id=i.type_id AND p.perm_type=i.type',
|
||||
'type' => 'left',
|
||||
),
|
||||
array(
|
||||
'select' => 'm.members_display_name, m.member_group_id, m.mgroup_others',
|
||||
'from' => array( 'members' => 'm' ),
|
||||
'where' => 'i.member_id=m.member_id',
|
||||
'type' => 'left',
|
||||
),
|
||||
array(
|
||||
'from' => array( 'profile_friends' => 'friend' ),
|
||||
'where' => 'friend.friends_member_id=i.member_id AND friend.friends_friend_id=' . $this->memberData['member_id'],
|
||||
'type' => 'left',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/* Loop through all the search plugins and let them modify the search query */
|
||||
foreach( ipsRegistry::$applications as $app )
|
||||
{
|
||||
if( IPSSearchIndex::appisSearchable( $app['app_directory'] ) )
|
||||
{
|
||||
if( ! isset( $this->display_plugins[ $app['app_directory'] ] ) || ! $this->display_plugins[ $app['app_directory'] ] )
|
||||
{
|
||||
require_once( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/searchDisplay.php' );
|
||||
$_class = $app['app_directory'] . 'SearchDisplay';
|
||||
|
||||
$this->display_plugins[ $app['app_directory'] ] = new $_class();
|
||||
}
|
||||
|
||||
if( method_exists( $this->display_plugins[ $app['app_directory'] ] , 'modifySearchQuery' ) )
|
||||
{
|
||||
/* Get the modified query */
|
||||
$new_query = $this->display_plugins[ $app['app_directory'] ]->modifySearchQuery( $search_query_array, $count_only );
|
||||
|
||||
/* Simple check to prevent accidentaly breaking the query, clearly not fool proof :) */
|
||||
$search_query_array = is_array( $new_query ) && count( $new_query ) ? $new_query : $search_query_array;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $search_query_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the where portion of a search string
|
||||
*
|
||||
* @access private
|
||||
* @param string $search_term The string to use in the search
|
||||
* @param bool $content_title_only Search only title records
|
||||
* @return string
|
||||
**/
|
||||
private function _buildWhereStatement( $search_term, $content_title_only=false )
|
||||
{
|
||||
/* INI */
|
||||
$where_clause = array();
|
||||
if( $search_term )
|
||||
{
|
||||
/* Main Search Statement */
|
||||
if( $content_title_only )
|
||||
{
|
||||
$where_clause[] = "MATCH( i.content_title ) AGAINST( '$search_term' IN BOOLEAN MODE )";
|
||||
}
|
||||
else
|
||||
{
|
||||
$where_clause[] = "MATCH( i.content, i.content_title ) AGAINST( '$search_term' IN BOOLEAN MODE )";
|
||||
}
|
||||
}
|
||||
|
||||
/* Exclude Apps */
|
||||
if( count( $this->exclude_apps ) )
|
||||
{
|
||||
$where_clause[] = 'i.app NOT IN ( ' . implode( ',', $this->exclude_apps ) . ' )';
|
||||
}
|
||||
|
||||
/* Exclude some items */
|
||||
if( !$this->memberData['g_is_supmod'] )
|
||||
{
|
||||
/* Owner only */
|
||||
$where_clause[] = '(p.owner_only=0 OR i.member_id=' . $this->memberData['member_id'] . ')';
|
||||
|
||||
/* Friend only */
|
||||
$where_clause[] = '(p.friend_only=0 OR friend.friends_id ' . $this->DB->buildIsNull( false ) . ')';
|
||||
|
||||
/* Authorized users only */
|
||||
$where_clause[] = '(p.authorized_users ' . $this->DB->buildIsNull() . ' OR i.member_id=' . $this->memberData['member_id'] . " OR p.authorized_users LIKE '%," . $this->memberData['member_id'] . ",%')";
|
||||
}
|
||||
|
||||
/* Date Restrict */
|
||||
if( $this->search_begin_timestamp && $this->search_end_timestamp )
|
||||
{
|
||||
$where_clause[] = "i.updated BETWEEN {$this->search_begin_timestamp} AND {$this->search_end_timestamp}";
|
||||
}
|
||||
else
|
||||
{
|
||||
if( $this->search_begin_timestamp )
|
||||
{
|
||||
$where_clause[] = "i.updated > {$this->search_begin_timestamp}";
|
||||
}
|
||||
|
||||
if( $this->search_end_timestamp )
|
||||
{
|
||||
$where_clause[] = "i.updated < {$this->search_end_timestamp}";
|
||||
}
|
||||
}
|
||||
|
||||
/* Add in AND where conditions */
|
||||
if( isset( $this->whereConditions['AND'] ) && count( $this->whereConditions['AND'] ) )
|
||||
{
|
||||
$where_clause = array_merge( $where_clause, $this->whereConditions['AND'] );
|
||||
}
|
||||
|
||||
/* ADD in OR where conditions */
|
||||
if( isset( $this->whereConditions['OR'] ) && count( $this->whereConditions['OR'] ) )
|
||||
{
|
||||
$where_clause[] = '( ' . implode( ' OR ', $this->whereConditions['OR'] ) . ' )';
|
||||
}
|
||||
|
||||
/* Permissions */
|
||||
$where_clause[] = $this->DB->buildRegexp( "p.perm_view", $this->member->perm_id_array );
|
||||
|
||||
/* Build and return the string */
|
||||
return implode( " AND ", $where_clause );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user