Files
IPB/upload/admin/applications/members/extensions/search/engines/sql.php
T
2025-12-19 00:32:22 -08:00

428 lines
12 KiB
PHP

<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.1.4
* Basic Forum Search
* Last Updated: $Date: 2010-02-23 12:38:11 +0000 (Tue, 23 Feb 2010) $
* </pre>
*
* @author $Author: matt $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/community/board/license.html
* @package IP.Board
* @subpackage Forums
* @link http://www.invisionpower.com
* @version $Rev: 5861 $
*/
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_members extends search_engine
{
/**
* Constructor
*/
public function __construct( ipsRegistry $registry )
{
parent::__construct( $registry );
}
/**
* Decide what type of search we're using
*
* @access public
* @return array
*/
public function search()
{
/* Ok, now because the top bar search box defaults to members default search, which is profile comments, we need
to convince it to default to members if the user used the top search bar with members selected */
if ( $this->request['fromMainBar'] )
{
IPSSearchRegistry::set('members.searchInKey', 'members');
}
if ( IPSSearchRegistry::get('members.searchInKey') AND IPSSearchRegistry::get('members.searchInKey') != 'comments' )
{
return $this->_membersSearch();
}
else
{
return $this->_commentsSearch();
}
}
/**
* Perform a comment search.
* Returns an array of a total count (total number of matches)
* and an array of IDs ( 0 => 1203, 1 => 928, 2 => 2938 ).. 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 _commentsSearch()
{
/* INIT */
$count = 0;
$results = array();
$sort_by = IPSSearchRegistry::get('in.search_sort_by');
$sort_order = IPSSearchRegistry::get('in.search_sort_order');
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$content_title_only = IPSSearchRegistry::get('opt.searchTitleOnly');
$post_search_only = IPSSearchRegistry::get('opt.onlySearchPosts');
$order_dir = ( $sort_order == 'asc' ) ? 'asc' : 'desc';
$sortKey = '';
$sortType = '';
$rows = array();
$got = 0;
/* Sorting */
switch( $sort_by )
{
default:
case 'date':
$sortKey = 'comment_date';
$sortType = 'numerical';
break;
}
/* Not allowed to see profile information */
if ( ! $this->memberData['g_mem_info'] )
{
return array( 'count' => 0, 'resultSet' => array() );
}
/* Query the count */
$count = $this->DB->buildAndFetch( array('select' => 'COUNT(*) as total_results',
'from' => array( 'profile_comments' => 'c' ),
'where' => $this->_buildCommentsWhereStatement( $search_term, $content_title_only ),
'add_join' => array( array( 'from' => array( 'profile_portal' => 'p' ),
'where' => "p.pp_member_id=c.comment_by_member_id",
'type' => 'left' ) ) ) );
/* Fetch data */
$this->DB->build( array('select' => 'c.*',
'from' => array( 'profile_comments' => 'c' ),
'where' => $this->_buildCommentsWhereStatement( $search_term, $content_title_only ),
'order' => $sortKey . ' ' . $sort_order,
'limit' => array( IPSSearchRegistry::get('in.start'), IPSSearchRegistry::get('opt.search_per_page') ),
'add_join' => array( array( 'select' => 'x.members_display_name as members_display_name_from, x.members_seo_name as members_seo_name_from',
'from' => array( 'members' => 'x' ),
'where' => "x.member_id=c.comment_by_member_id",
'type' => 'left' ),
array( 'select' => 'm.*',
'from' => array( 'members' => 'm' ),
'where' => "m.member_id=c.comment_for_member_id",
'type' => 'left' ),
array( 'select' => 'p.*',
'from' => array( 'profile_portal' => 'p' ),
'where' => "p.pp_member_id=c.comment_for_member_id",
'type' => 'left' ) ) ) );
$this->DB->execute();
/* Sort */
while ( $_row = $this->DB->fetch() )
{
$rows[ $got ] = $_row;
$got++;
}
/* Return it */
return array( 'count' => $count['total_results'], 'resultSet' => $rows );
}
/**
* Perform a MEMBER search.
* Returns an array of a total count (total number of matches)
* and an array of IDs ( 0 => 1203, 1 => 928, 2 => 2938 ).. 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 _membersSearch()
{
/* INIT */
$count = 0;
$results = array();
$sort_by = IPSSearchRegistry::get('in.search_sort_by');
$sort_order = IPSSearchRegistry::get('in.search_sort_order');
$search_term = IPSSearchRegistry::get('in.clean_search_term');
$content_title_only = IPSSearchRegistry::get('opt.searchTitleOnly');
$post_search_only = IPSSearchRegistry::get('opt.onlySearchPosts');
$order_dir = ( $sort_order == 'asc' ) ? 'asc' : 'desc';
$sortKey = '';
$sortType = '';
$rows = array();
$got = 0;
if ( IPSSearchRegistry::get('opt.noPostPreview') OR IPSSearchRegistry::get('display.onlyTitles') )
{
$group_by = 'm.member_id';
}
/* Sorting */
switch( $sort_by )
{
default:
case 'date':
$sortKey = ( $content_title_only ) ? 'member_id' : 'member_id';
$sortType = 'numerical';
break;
case 'title':
$sortKey = 'members_l_display_name';
$sortType = 'string';
break;
}
/* Query the count */
$count = $this->DB->buildAndFetch( array('select' => 'COUNT(*) as total_results',
'from' => array( 'members' => 'm' ),
'where' => $this->_buildWhereStatement( $search_term, $content_title_only ),
'group' => $group_by,
'add_join' => array( array( 'from' => array( 'profile_portal' => 'p' ),
'where' => "p.pp_member_id=m.member_id",
'type' => 'left' ) ) ) );
/* Fetch data */
$this->DB->build( array('select' => 'm.*',
'from' => array( 'members' => 'm' ),
'where' => $this->_buildWhereStatement( $search_term, $content_title_only ),
'group' => $group_by,
'order' => $sortKey . ' ' . $sort_order,
'limit' => array( IPSSearchRegistry::get('in.start'), IPSSearchRegistry::get('opt.search_per_page') ),
'add_join' => array( array( 'select' => 'p.*',
'from' => array( 'profile_portal' => 'p' ),
'where' => "p.pp_member_id=m.member_id",
'type' => 'left' ) ) ) );
$this->DB->execute();
/* Sort */
while ( $_row = $this->DB->fetch() )
{
$rows[ $got ] = $_row;
$got++;
}
/* Return it */
return array( 'count' => $count['total_results'], 'resultSet' => $rows );
}
/**
* 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 _buildCommentsWhereStatement( $search_term, $content_title_only=false )
{
/* INI */
$where_clause = array();
if( $search_term )
{
$where_clause[] = "c.comment_content LIKE '%" . mb_strtolower( $search_term ) . "%'";
}
/* 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'] ) . ' )';
}
/* Date Restrict */
if( $this->search_begin_timestamp && $this->search_end_timestamp )
{
$where_clause[] = $this->DB->buildBetween( "c.comment_date", $this->search_begin_timestamp, $this->search_end_timestamp );
}
else
{
if( $this->search_begin_timestamp )
{
$where_clause[] = "c.comment_date > {$this->search_begin_timestamp}";
}
if( $this->search_end_timestamp )
{
$where_clause[] = "c.comment_date < {$this->search_end_timestamp}";
}
}
$where_clause[] = "c.comment_approved=1";
/* Build and return the string */
return implode( " AND ", $where_clause );
}
/**
* 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 )
{
if( $content_title_only )
{
$where_clause[] = "m.members_l_display_name LIKE '%" . mb_strtolower( $search_term ) . "%'";
}
else
{
$where_clause[] = "m.members_l_display_name LIKE '%" . mb_strtolower( $search_term ) . "%' OR p.signature LIKE '%{$search_term}%' OR p.pp_about_me LIKE '%{$search_term}%'";
}
}
/* 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'] ) . ' )';
}
/* Date Restrict */
if( $this->search_begin_timestamp && $this->search_end_timestamp )
{
$where_clause[] = $this->DB->buildBetween( "m.joined", $this->search_begin_timestamp, $this->search_end_timestamp );
}
else
{
if( $this->search_begin_timestamp )
{
$where_clause[] = "m.joined > {$this->search_begin_timestamp}";
}
if( $this->search_end_timestamp )
{
$where_clause[] = "m.joined < {$this->search_end_timestamp}";
}
}
/* Build and return the string */
return implode( " AND ", $where_clause );
}
/**
* Remap standard columns (Apps can override )
*
* @access public
* @param string $column sql table column for this condition
* @return string column
* @return void
*/
public function remapColumn( $column )
{
if ( IPSSearchRegistry::get( 'members.searchInKey') == 'comments' )
{
$column = ( $column == 'member_id' ) ? 'c.comment_by_member_id' : '';
}
return $column;
}
/**
* Returns an array used in the searchplugin's setCondition method
*
* @access public
* @param array $data Array of forums to view
* @return array Array with column, operator, and value keys, for use in the setCondition call
**/
public function buildFilterSQL( $data )
{
/* INIT */
$return = array();
/* Set up some defaults */
IPSSearchRegistry::set( 'opt.noPostPreview' , false );
IPSSearchRegistry::set( 'opt.onlySearchPosts', false );
//IPSSearchRegistry::set( 'members.searchInKey' , 'comments' );
/* member specific search */
/* Make default search type topics */
if( isset( $data ) && is_array( $data ) && count( $data ) )
{
foreach( $data as $field => $_data )
{
/* CONTENT ONLY */
if ( $field == 'searchInKey' AND $_data['searchInKey'] == 'members' )
{
//IPSSearchRegistry::set( 'member.searchType', 'members' );
}
}
}
return array();
}
/**
* Can handle boolean searching
*
* @access public
* @return boolean
*/
public function isBoolean()
{
return false;
}
/**
* Perform the viewNewContent search
* Forum Version
* Populates $this->_count and $this->_results
*
* @access public
* @return nothin'
*/
public function viewNewContent()
{
/* Set up some vars */
IPSSearchRegistry::set('set.resultCutToDate', intval( $this->memberData['last_visit'] ) );
return parent::viewNewContent();
}
}