monthNameRu2En(). * Invision Power Services * IP.Board v3.2.3 * Global Search * Last Updated: $Date: 2011-09-21 16:54:20 -0400 (Wed, 21 Sep 2011) $ * * * @author $Author: bfarber $ * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://link.hatynka.in/FEH7 * @package IP.Board * @subpackage Core * @link http://hatynka.in * @version $Rev: 9532 $ */ if ( ! defined( 'IN_IPB' ) ) { print "

Incorrect access

You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files."; exit(); } class public_core_search_search extends ipsCommand { /** * Generated output * * @var string */ protected $output = ''; /** * Page Title * * @var string */ protected $title = ''; /** * Object to handle searches * * @var string */ protected $search_plugin = ''; /** * Topics array * * @var array */ protected $_topicArray = array(); protected $_removedTerms = array(); /** * Search controller * * @var obj */ protected $searchController; protected $_session; /** * Class entry point * * @param object Registry reference * @return @e void [Outputs to screen/redirects] */ public function doExecute( ipsRegistry $registry ) { /* Load language */ $this->registry->class_localization->loadLanguageFile( array( 'public_search' ), 'core' ); $this->registry->class_localization->loadLanguageFile( array( 'public_forums', 'public_topic' ), 'forums' ); /* Reset engine type */ $this->settings['search_method'] = ( $this->settings['search_method'] == 'traditional' ) ? 'sql' : $this->settings['search_method']; /* Force SQL for view new content? */ if ( ! empty( $this->settings['force_sql_vnc'] ) && $this->request['do'] == 'viewNewContent' ) { $this->settings['search_method'] = 'sql'; } /* Special consideration for contextual search */ if ( isset( $this->request['search_app'] ) AND strstr( $this->request['search_app'], ':' ) ) { list( $app, $type, $id ) = explode( ':', $this->request['search_app'] ); $this->request['search_app'] = $app; $this->request['cType'] = $type; $this->request['cId'] = $id; } else { /* Force forums as default search */ $this->request['search_in'] = ( $this->request['search_in'] AND IPSLib::appIsSearchable( $this->request['search_in'], 'search' ) ) ? $this->request['search_in'] : 'forums'; $this->request['search_app'] = $this->request['search_app'] ? $this->request['search_app'] : $this->request['search_in']; } /* Check Access */ $this->_canSearch(); /* Start session - needs to be called before the controller is initiated */ $this->_startSession(); /* Load the controller */ $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH. 'sources/classes/search/controller.php', 'IPSSearch' ); /* Sanitzie */ if ( ! is_string( $this->request['search_app'] ) ) { $this->request['search_app'] = 'forums'; } try { $this->searchController = new $classToLoad( $registry, $this->settings['search_method'], $this->request['search_app'] ); } catch( Exception $error ) { $msg = $error->getMessage(); /* Start session */ $this->_endSession(); switch( $msg ) { case 'NO_SUCH_ENGINE': case 'NO_SUCH_APP': case 'NO_SUCH_APP_ENGINE': $this->registry->output->showError( sprintf( $this->lang->words['no_search_app'], ipsRegistry::$applications[ $this->request['search_app'] ]['app_title'] ), 10145.1 ); break; } } /* Log type */ IPSDebug::addMessage( "Search type: " . $this->settings['search_method'] ); /* Set up some defaults */ IPSSearchRegistry::set('opt.noPostPreview', false ); IPSSearchRegistry::set('in.start', intval( $this->request['st'] ) ); IPSSearchRegistry::set('opt.search_per_page', intval( $this->settings['search_per_page'] ) ? intval( $this->settings['search_per_page'] ) : 25 ); $this->settings['search_ucontent_days'] = ( $this->settings['search_ucontent_days'] ) ? $this->settings['search_ucontent_days'] : 365; /* Contextuals */ if ( isset( $this->request['cType'] ) ) { IPSSearchRegistry::set('contextual.type', $this->request['cType'] ); IPSSearchRegistry::set('contextual.id' , $this->request['cId'] ); } /* What to do */ switch( $this->request['do'] ) { case 'user_activity': $this->viewUserContent(); break; case 'new_posts': case 'viewNewContent': case 'active': $this->viewNewContent(); break; case 'search': case 'quick_search': $this->searchResults(); break; case 'followed': $this->viewFollowedContent(); break; case 'manageFollowed': $this->updateFollowedContent(); break; default: case 'search_form': $this->searchAdvancedForm(); break; } /* Start session */ $this->_endSession(); /* If we have any HTML to print, do so... */ $this->registry->output->setTitle( $this->title . ' - ' . ipsRegistry::$settings['board_name'] ); $this->registry->output->addContent( $this->output ); $this->registry->output->sendOutput(); } /** * Moderate your list of liked content * * @author bfarber * @return string HTML to display */ public function updateFollowedContent() { IPSSearchRegistry::set( 'in.search_app', $this->request['search_app'] ); //----------------------------------------- // Get the likes we selected //----------------------------------------- $_likes = array(); if( is_array($this->request['likes']) AND count($this->request['likes']) ) { foreach( $this->request['likes'] as $_like ) { $_thisLike = explode( '-', $_like ); $_likes[] = array( 'app' => $_thisLike[0], 'area' => $_thisLike[1], 'id' => $_thisLike[2], ); } } //----------------------------------------- // Got any? //----------------------------------------- if( !count($_likes) OR !is_array($_likes) ) { return $this->viewFollowedContent( $this->lang->words['no_likes_for_del'] ); } //----------------------------------------- // Get like helper class //----------------------------------------- $bootstraps = array(); require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/ //----------------------------------------- // Loop over and moderate //----------------------------------------- foreach( $_likes as $_like ) { $_bootstrap = classes_like::bootstrap( $_like['app'], $_like['area'] ); $_likeKey = classes_like_registry::getKey( $_like['id'], $this->memberData['member_id'] ); $_frequencies = $_bootstrap->allowedFrequencies(); //----------------------------------------- // What action to take? //----------------------------------------- switch( $this->request['modaction'] ) { case 'delete': $_bootstrap->remove( $_like['id'], $this->memberData['member_id'] ); break; case 'change-donotify': $this->DB->update( 'core_like', array( 'like_notify_do' => 1, 'like_notify_freq' => 'immediate' ), "like_id='" . addslashes($_likeKey) . "'" ); break; case 'change-donotnotify': $this->DB->update( 'core_like', array( 'like_notify_do' => 0 ), "like_id='" . addslashes($_likeKey) . "'" ); break; case 'change-immediate': if( in_array( 'immediate', $_frequencies ) ) { $this->DB->update( 'core_like', array( 'like_notify_do' => 1, 'like_notify_freq' => 'immediate' ), "like_id='" . addslashes($_likeKey) . "'" ); } break; case 'change-offline': if( in_array( 'offline', $_frequencies ) ) { $this->DB->update( 'core_like', array( 'like_notify_do' => 1, 'like_notify_freq' => 'offline' ), "like_id='" . addslashes($_likeKey) . "'" ); } break; case 'change-daily': if( in_array( 'daily', $_frequencies ) ) { $this->DB->update( 'core_like', array( 'like_notify_do' => 1, 'like_notify_freq' => 'daily' ), "like_id='" . addslashes($_likeKey) . "'" ); } break; case 'change-weekly': if( in_array( 'weekly', $_frequencies ) ) { $this->DB->update( 'core_like', array( 'like_notify_do' => 1, 'like_notify_freq' => 'weekly' ), "like_id='" . addslashes($_likeKey) . "'" ); } break; case 'change-anon': $this->DB->update( 'core_like', array( 'like_is_anon' => 1 ), "like_id='" . addslashes($_likeKey) . "'" ); break; case 'change-noanon': $this->DB->update( 'core_like', array( 'like_is_anon' => 0 ), "like_id='" . addslashes($_likeKey) . "'" ); break; } } $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&module=search&do=followed&search_app={$this->request['search_app']}&contentType={$this->request['contentType']}&confirm=1" ); } /** * View content you are following * * @author Brandon Farber * @param string $error Error message * @return @e void */ public function viewFollowedContent( $error='' ) { IPSSearchRegistry::set( 'in.search_app', $this->request['search_app'] ); IPSSearchRegistry::set( 'opt.searchType', 'titles' ); IPSSearchRegistry::set( 'opt.noPostPreview', true ); $results = array(); $formatted = array(); $count = 0; //----------------------------------------- // Determine content type //----------------------------------------- $contentTypes = IPSSearchRegistry::get('config.followContentTypes'); //----------------------------------------- // Verify likes are available //----------------------------------------- if( count( IPSLib::getEnabledApplications('like') ) AND count( $contentTypes ) ) { //----------------------------------------- // What content type? //----------------------------------------- $_type = ''; if( $this->request['contentType'] AND in_array( $this->request['contentType'], $contentTypes ) ) { $_type = $this->request['contentType']; } else { $_type = $contentTypes[0]; } $this->request['contentType'] = $_type; IPSSearchRegistry::set( 'in.followContentType', $this->request['contentType'] ); /* Fetch like class */ try { require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/ $this->_like = classes_like::bootstrap( IPSSearchRegistry::get('in.search_app'), $_type ); } catch ( Exception $e) { /* Fail safe... */ $this->registry->output->addNavigation( $this->lang->words['followed_ct_title'], '' ); $this->title = $this->lang->words['followed_ct_title']; $this->output .= $this->registry->output->getTemplate( 'search' )->followedContentView( array(), '', 0, $error, $contentTypes ); } /* Get a count of likes */ $count = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as er', 'from' => 'core_like', 'where' => 'like_member_id=' . $this->memberData['member_id'] . " AND like_visible=1 AND like_app='" . IPSSearchRegistry::get('in.search_app') . "' AND like_area='" . $_type . "'" ) ); $count = $count['er']; /* Do we have some custom join and sort data? */ if ( method_exists( $this->_like, 'getSearchJoinAndSortBy' ) ) { $custom = $this->_like->getSearchJoinAndSortBy(); $this->DB->build( array( 'select' => 'l.*', 'from' => array('core_like' => 'l'), 'where' => 'l.like_member_id=' . $this->memberData['member_id'] . " AND l.like_visible=1 AND l.like_app='" . IPSSearchRegistry::get('in.search_app') . "' AND l.like_area='" . $_type . "'", 'add_join' => array( array( 'from' => $custom['from'], 'where' => $custom['where'] ) ), 'limit' => array( IPSSearchRegistry::get('in.start'), IPSSearchRegistry::get('opt.search_per_page') ), 'order' => $custom['order'] . ' DESC' ) ); } else { $this->DB->build( array( 'select' => '*', 'from' => 'core_like', 'where' => 'like_member_id=' . $this->memberData['member_id'] . " AND like_visible=1 AND like_app='" . IPSSearchRegistry::get('in.search_app') . "' AND like_area='" . $_type . "'", 'limit' => array( IPSSearchRegistry::get('in.start'), IPSSearchRegistry::get('opt.search_per_page') ), 'order' => 'like_added DESC' ) ); } $outer = $this->DB->execute(); while( $r = $this->DB->fetch($outer) ) { $results[] = $r['like_rel_id']; $formatted[ $r['like_id'] ] = $r; } /* Process */ $results = $this->searchController->fetchFollowedContentOutput( $results, $formatted ); $pages = $this->registry->getClass('output')->generatePagination( array( 'totalItems' => $count, 'itemsPerPage' => IPSSearchRegistry::get('opt.search_per_page'), 'currentStartValue' => IPSSearchRegistry::get('in.start'), 'baseUrl' => "app=core&module=search&do=followed&search_app=" . IPSSearchRegistry::get('in.search_app') . '&sid=' . $this->request['_sid'] ) ); } else { $count = 0; $results = array(); } /* Output */ $this->registry->output->addNavigation( $this->lang->words['followed_ct_title'], '' ); $this->title = $this->lang->words['followed_ct_title']; $this->output .= $this->registry->output->getTemplate( 'search' )->followedContentView( $results, $pages, $count, $error, $contentTypes ); } /** * Builds the advanced search form * * @param string Message * @return @e void */ public function searchAdvancedForm( $msg='', $removed_search_terms=array() ) { /* Set up data */ IPSSearchRegistry::set('view.search_form', true ); /* Get any application specific filters */ $appHtml = $this->searchController->getHtml(); $isBoolean = $this->searchController->isBoolean(); $canTag = ( $this->settings['tags_enabled'] && IPSSearchRegistry::get( 'config.can_searchTags' ) ) ? true : false; /* Output */ $this->title = $this->lang->words['search_form']; $this->registry->output->addNavigation( $this->lang->words['search_form'], '' ); $this->output .= $this->registry->output->getTemplate( 'search' )->searchAdvancedForm( $appHtml, $msg, $this->request['search_app'], $removed_search_terms, $isBoolean, $canTag ); } /** * Processes a search request * * @return @e void */ public function searchResults() { /* Search Term */ $_st = $this->searchController->formatSearchTerm( $this->request['search_term'] ); $search_term = $_st['search_term']; $removedTerms = $_st['removed']; /* Set up some defaults */ $this->settings['max_search_word'] = $this->settings['max_search_word'] ? $this->settings['max_search_word'] : 300; /* Did we come in off a post request? */ if ( $this->request['request_method'] == 'post' ) { /* Set a no-expires header */ $this->registry->getClass('output')->setCacheExpirationSeconds( 30 * 60 ); } /* App specific */ if ( isset( $this->request['search_sort_by_' . $this->request['search_app'] ] ) ) { $this->request['search_sort_by'] = ( $_POST[ 'search_sort_by_' . $this->request['search_app'] ] ) ? $_POST[ 'search_sort_by_' . $this->request['search_app'] ] : $this->request['search_sort_by_' . $this->request['search_app'] ]; $this->request['search_sort_order'] = ( $_POST[ 'search_sort_order_' . $this->request['search_app'] ] ) ? $_POST[ 'search_sort_order_' . $this->request['search_app'] ] : $this->request['search_sort_order_' . $this->request['search_app'] ]; } /* Populate the registry */ IPSSearchRegistry::set('in.search_app' , $this->request['search_app'] ); IPSSearchRegistry::set('in.raw_search_term' , trim( $this->request['search_term'] ) ); IPSSearchRegistry::set('in.clean_search_term', $search_term ); IPSSearchRegistry::set('in.raw_search_tags' , str_replace( '&', '&', trim( IPSText::parseCleanValue( urldecode( $_REQUEST['search_tags'] ) ) ) ) ); IPSSearchRegistry::set('in.search_higlight' , str_replace( '.', '', $this->request['search_term'] ) ); IPSSearchRegistry::set('in.search_date_end' , ( $this->request['search_date_start'] && $this->request['search_date_end'] ) ? $this->request['search_date_end'] : 'now' ); IPSSearchRegistry::set('in.search_date_start', ( $this->request['search_date_start'] ) ? $this->request['search_date_start'] : '' ); IPSSearchRegistry::set('in.search_author' , !empty( $this->request['search_author'] ) ? $this->request['search_author'] : '' ); /* Set sort filters */ $this->_setSortFilters(); /* These can be overridden in the actual engine scripts */ // IPSSearchRegistry::set('set.hardLimit' , 0 ); IPSSearchRegistry::set('set.resultsCutToLimit', false ); IPSSearchRegistry::set('set.resultsAsForum' , false ); /* Are we option to show titles only / search in titles only */ IPSSearchRegistry::set('opt.searchType', ( !empty( $this->request['search_content'] ) AND in_array( $this->request['search_content'], array( 'both', 'titles', 'content' ) ) ) ? $this->request['search_content'] : 'both' ); /* Do some date checking */ if( IPSSearchRegistry::get('in.search_date_end') AND IPSSearchRegistry::get('in.search_date_start') AND strtotime( IPSText::monthNameRu2En(IPSSearchRegistry::get('in.search_date_start')) ) > strtotime( IPSText::monthNameRu2En(IPSSearchRegistry::get('in.search_date_end')) ) ) { $this->searchAdvancedForm( $this->lang->words['search_invalid_date_range'] ); return; } /** * Lower limit */ if ( $this->settings['min_search_word'] && ! IPSSearchRegistry::get('in.search_author') && ! IPSSearchRegistry::get('in.raw_search_tags') ) { $_words = explode( ' ', preg_replace( "#\"(.*?)\"#", '', $search_term ) ); $_ok = $search_term ? true : false; foreach( $_words as $_word ) { $_word = preg_replace( '#^\+(.+?)$#', "\\1", $_word ); if( !$_word ) { continue; } if( strlen( $_word ) < $this->settings['min_search_word'] ) { $_ok = false; break; } } if( !$_ok ) { $this->searchAdvancedForm( sprintf( $this->lang->words['search_term_short'], $this->settings['min_search_word'] ), $removedTerms ); return; } } /** * Ok this is an upper limit. * If you needed to change this, you could do so via conf_global.php by adding: * $INFO['max_search_word'] = #####; */ if ( $this->settings['max_search_word'] && strlen( IPSSearchRegistry::get('in.raw_search_term') ) > $this->settings['max_search_word'] ) { $this->searchAdvancedForm( sprintf( $this->lang->words['search_term_long'], $this->settings['max_search_word'] ) ); return; } /* Search Flood Check */ if( $this->memberData['g_search_flood'] ) { /* Check for a cookie */ $last_search = IPSCookie::get( 'sfc' ); $last_term = str_replace( """, '"', IPSCookie::get( 'sfct' ) ); $last_term = str_replace( "&", '&', $last_term ); /* If we have a last search time, check it */ if( $last_search && $last_term ) { if( ( time() - $last_search ) <= $this->memberData['g_search_flood'] && $last_term != IPSSearchRegistry::get('in.raw_search_term') ) { $this->searchAdvancedForm( sprintf( $this->lang->words['xml_flood'], $this->memberData['g_search_flood'] ) ); return; } else { /* Reset the cookie */ IPSCookie::set( 'sfc', time() ); IPSCookie::set( 'sfct', urlencode( IPSSearchRegistry::get('in.raw_search_term') ) ); } } /* Set the cookie */ else { IPSCookie::set( 'sfc', time() ); IPSCookie::set( 'sfct', urlencode( IPSSearchRegistry::get('in.raw_search_term') ) ); } } /* Clean search term for results view */ $_search_term = trim( preg_replace( '#(^|\s)(\+|\-|\||\~)#', " ", $search_term ) ); /* Got tag search only but app doesn't support tags */ if ( IPSSearchRegistry::get('in.raw_search_tags') && ! IPSSearchRegistry::get( 'config.can_searchTags' ) && ! IPSSearchRegistry::get('in.raw_search_term') ) { $count = 0; $results = array(); } else if ( IPSLib::appIsSearchable( IPSSearchRegistry::get('in.search_app'), 'search' ) ) { /* Perform the search */ $this->searchController->search(); /* Get count */ $count = $this->searchController->getResultCount(); /* Get results which will be array of IDs */ $results = $this->searchController->getResultSet(); /* Get templates to use */ $template = $this->searchController->fetchTemplates(); /* Fetch sort details */ $sortDropDown = $this->searchController->fetchSortDropDown(); /* Set default sort option */ $_a = IPSSearchRegistry::get('in.search_app'); $_k = IPSSearchRegistry::get( $_a . '.searchInKey') ? IPSSearchRegistry::get( $_a . '.searchInKey') : ''; if( $_k AND !$this->request['search_app_filters'][ $_a ][ $_k ]['sortKey'] AND is_array($sortDropDown) AND count($sortDropDown) ) { $this->request['search_app_filters'][ $_a ][ $_k ]['sortKey'] = key( $sortDropDown ); } else if( !$_k AND !$this->request['search_app_filters'][ $_a ]['sortKey'] AND is_array($sortDropDown) AND count($sortDropDown) ) { $this->request['search_app_filters'][ $_a ]['sortKey'] = key( $sortDropDown ); } /* Fetch sort details */ $sortIn = $this->searchController->fetchSortIn(); /* Build pagination */ $links = $this->registry->output->generatePagination( array( 'totalItems' => $count, 'itemsPerPage' => IPSSearchRegistry::get('opt.search_per_page'), 'currentStartValue'=> IPSSearchRegistry::get('in.start'), 'baseUrl' => $this->_buildURLString() . '&search_app=' . IPSSearchRegistry::get('in.search_app') . '' ) ); /* Showing */ $showing = array( 'start' => IPSSearchRegistry::get('in.start') + 1, 'end' => ( IPSSearchRegistry::get('in.start') + IPSSearchRegistry::get('opt.search_per_page') ) > $count ? $count : IPSSearchRegistry::get('in.start') + IPSSearchRegistry::get('opt.search_per_page') ); /* Parse result set */ $results = $this->registry->output->getTemplate( $template['group'] )->$template['template']( $results, ( IPSSearchRegistry::get('opt.searchType') == 'titles' || IPSSearchRegistry::get('opt.noPostPreview') ) ? 1 : 0 ); /* Check for sortIn */ if( count( $sortIn ) && !$this->request['search_app_filters'][ $this->request['search_app'] ]['searchInKey'] ) { $this->request['search_app_filters'][ $this->request['search_app'] ]['searchInKey'] = $sortIn[0][0]; } } else { $count = 0; $results = array(); } /* Output */ $this->title = $this->lang->words['search_results']; $this->output .= $this->registry->output->getTemplate( 'search' )->searchResultsWrapper( $results, $sortDropDown, $sortIn, $links, $count, $showing, $_search_term, $this->_buildURLString(), $this->request['search_app'], $removedTerms, IPSSearchRegistry::get('set.hardLimit'), IPSSearchRegistry::get('set.resultsCutToLimit'), IPSSearchRegistry::get('in.raw_search_tags') ); } /** * Starts session * Loads / creates a session based on activity * * @return */ protected function _startSession() { $session_id = IPSText::md5Clean( $this->request['sid'] ); $requestType = ( $this->request['request_method'] == 'post' ) ? 'post' : 'get'; if ( $session_id ) { /* We check on member id 'cos we can. Obviously guests will have a member ID of zero, but meh */ $this->_session = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'search_sessions', 'where' => 'session_id=\'' . $session_id . '\' AND session_member_id=' . $this->memberData['member_id'] ) ); } /* Deflate */ if ( $this->_session['session_id'] ) { if ( $this->_session['session_data'] ) { $this->_session['_session_data'] = unserialize( $this->_session['session_data'] ); if ( isset( $this->_session['_session_data']['search_app_filters'] ) ) { $this->request['search_app_filters'] = is_array( $this->request['search_app_filters'] ) ? array_merge( $this->_session['_session_data']['search_app_filters'], $this->request['search_app_filters'] ) : $this->_session['_session_data']['search_app_filters']; } } IPSDebug::addMessage( "Loaded search session:
" . var_export( $this->_session['_session_data'], true ) . "
" ); } else { /* Create a session */ $this->_session = array( 'session_id' => md5( uniqid( microtime(), true ) ), 'session_created' => time(), 'session_updated' => time(), 'session_member_id' => $this->memberData['member_id'], 'session_data' => serialize( array( 'search_app_filters' => $this->request['search_app_filters'] ) ) ); $this->DB->insert( 'search_sessions', $this->_session ); $this->_session['_session_data']['search_app_filters'] = $this->request['search_app_filters']; IPSDebug::addMessage( "Created search session:
" . var_export( $this->_session['_session_data'], true ) . "
" ); } /* Do we have POST infos? */ if ( isset( $_POST['search_app_filters'] ) ) { $this->_session['_session_data']['search_app_filters'] = ( is_array( $this->_session['_session_data']['search_app_filters'] ) ) ? IPSLib::arrayMergeRecursive( $this->_session['_session_data']['search_app_filters'], $_POST['search_app_filters'] ) : $_POST['search_app_filters']; $this->request['search_app_filters'] = $this->_session['_session_data']['search_app_filters']; IPSDebug::addMessage( "Updated filters:
" . var_export( $_POST['search_app_filters'], true ) . "
" ); } /* Globalize the session ID */ $this->request['_sid'] = $this->_session['session_id']; } /** * End the session * */ protected function _endSession() { if ( $this->_session['session_id'] ) { $sd = array( 'session_updated' => time(), 'session_data' => serialize( $this->_session['_session_data'] ) ); $this->DB->update( 'search_sessions', $sd, 'session_id=\'' . $this->_session['session_id'] . '\'' ); } /* Delete old sessions */ $this->DB->delete( 'search_sessions', 'session_updated < ' . ( time() - 86400 ) ); } /** * Set the search order and key * * @return @e void */ protected function _setSortFilters() { $app = $this->request['search_app']; $key = 'date'; $dir = 'desc'; $dun = false; /* multi search in options? */ if ( isset( $this->request['search_app_filters'][ $app ]['searchInKey'] ) ) { $_k = $this->request['search_app_filters'][ $app ]['searchInKey']; if ( isset( $this->request['search_app_filters'][ $app ][ $_k ]['sortKey'] ) ) { $dun = true; $key = $this->request['search_app_filters'][ $app ][ $_k ]['sortKey']; $dir = $this->request['search_app_filters'][ $app ][ $_k ]['sortDir']; } } /* Normal options - although sometimes used even with multiple types */ if ( ! $dun AND isset( $this->request['search_app_filters'][$app]['sortKey'] ) ) { $key = $this->request['search_app_filters'][$app]['sortKey']; $dir = $this->request['search_app_filters'][$app]['sortDir']; } /* Global */ else { if ( isset( $this->request['search_sort_by'] ) ) { $key = $this->request['search_sort_by']; $dir = $this->request['search_sort_order']; } } /* Numeric? */ if ( is_numeric( $dir ) ) { $dir = ( $dir == 0 ) ? 'desc' : 'asc'; } else { $dir = 'desc'; } IPSSearchRegistry::set('in.search_sort_by' , trim( $key ) ); IPSSearchRegistry::set('in.search_sort_order', ( $dir != 'desc' ) ? 'asc' : 'desc' ); } /** * Displays latest user content * * @return @e void */ public function viewUserContent() { /* INIT */ $id = $this->request['mid'] ? intval( trim( $this->request['mid'] ) ) : $this->memberData['member_id']; /* Save query if we are viewing our own content */ if( $this->memberData['member_id'] AND $id == $this->memberData['member_id'] ) { $member = $this->memberData; } else { $member = IPSMember::load( $id, 'core' ); } $beginStamp = 0; if ( ! $member['member_id'] ) { $this->registry->output->showError( 'search_invalid_id', 10147, null, null, 403 ); } $this->request['userMode'] = !empty($this->request['userMode']) ? $this->request['userMode'] : 'all'; IPSSearchRegistry::set('in.search_app', $this->request['search_app'] ); IPSSearchRegistry::set('in.userMode' , $this->request['userMode'] ); /* Set sort filters */ $this->_setSortFilters(); /* Can we do this? */ if ( IPSLib::appIsSearchable( IPSSearchRegistry::get('in.search_app'), 'usercontent' ) ) { /* Perform the search */ $this->searchController->viewUserContent( $member ); /* Get count */ $count = $this->searchController->getResultCount(); /* Get results which will be array of IDs */ $results = $this->searchController->getResultSet(); /* Get templates to use */ $template = $this->searchController->fetchTemplates(); /* Fetch sort details */ $sortDropDown = $this->searchController->fetchSortDropDown(); /* Set default sort option */ $_a = IPSSearchRegistry::get('in.search_app'); $_k = IPSSearchRegistry::get( $_a . '.searchInKey') ? IPSSearchRegistry::get( $_a . '.searchInKey') : ''; if( $_k AND !$this->request['search_app_filters'][ $_a ][ $_k ]['sortKey'] AND is_array($sortDropDown) ) { $this->request['search_app_filters'][ $_a ][ $_k ]['sortKey'] = key( $sortDropDown ); } else if( !$_k AND !$this->request['search_app_filters'][ $_a ]['sortKey'] AND is_array($sortDropDown) ) { $this->request['search_app_filters'][ $_a ]['sortKey'] = key( $sortDropDown ); } /* Fetch sort details */ $sortIn = $this->searchController->fetchSortIn(); /* Reset for template */ $this->_resetRequestParameters(); /* Parse result set */ $results = $this->registry->output->getTemplate( $template['group'] )->$template['template']( $results, ( IPSSearchRegistry::get('opt.searchType') == 'titles' || IPSSearchRegistry::get('opt.noPostPreview') ) ? 1 : 0 ); /* Build pagination */ $links = $this->registry->output->generatePagination( array( 'totalItems' => $count, 'itemsPerPage' => IPSSearchRegistry::get('opt.search_per_page'), 'currentStartValue' => IPSSearchRegistry::get('in.start'), 'baseUrl' => 'app=core&module=search&do=user_activity&mid=' . $id . '&search_app=' . IPSSearchRegistry::get('in.search_app') . '&userMode=' . IPSSearchRegistry::get('in.userMode') . '&sid=' . $this->request['_sid'] . '&search_app_filters[' . IPSSearchRegistry::get('in.search_app') . '][searchInKey]=' . $this->request['search_app_filters'][ IPSSearchRegistry::get('in.search_app') ]['searchInKey'] . '&search_app_filters[' . IPSSearchRegistry::get('in.search_app') . '][sortKey]=' . $this->request['search_app_filters'][ IPSSearchRegistry::get('in.search_app') ]['sortKey'] . '&search_app_filters[' . IPSSearchRegistry::get('in.search_app') . '][sortDir]=' . $this->request['search_app_filters'][ IPSSearchRegistry::get('in.search_app') ]['sortDir'] ) ); } else { $count = 0; $results = array(); } $this->title = sprintf( $this->lang->words['s_participation_title'], $member['members_display_name'] ); $this->registry->output->addNavigation( $this->title, '' ); $this->output .= $this->registry->output->getTemplate( 'search' )->userPostsView( $results, $links, $count, $member, IPSSearchRegistry::get('set.hardLimit'), IPSSearchRegistry::get('set.resultsCutToLimit'), $beginStamp, $sortIn, $sortDropDown ); } /** * View new posts since your last visit * * @return @e void */ public function viewNewContent() { IPSSearchRegistry::set('in.search_app', $this->request['search_app'] ); /* Fetch member cache to see if we have a value set */ $vncPrefs = IPSMember::getFromMemberCache( $this->memberData, 'vncPrefs' ); /* Guests */ if ( ! $this->memberData['member_id'] AND ( !$this->request['period'] OR $this->request['period'] == 'unread' ) ) { $this->request['period'] = 'today'; } /* In period */ if ( $vncPrefs === null OR ! isset( $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['view'] ) OR isset( $this->request['period'] ) ) { $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['view'] = ( ! empty( $this->request['period'] ) ) ? $this->request['period'] : $this->settings['default_vnc_method']; } /* Follow filter enabled */ if ( $vncPrefs === null OR ! isset( $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['view'] ) OR isset( $this->request['followedItemsOnly'] ) ) { $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['vncFollowFilter'] = ( ! empty( $this->request['followedItemsOnly'] ) ) ? 1 : 0; } /* Filtering VNC by forum? */ IPSSearchRegistry::set('forums.vncForumFilters', $vncPrefs['forums']['vnc_forum_filter'] ); /* Set period up */ IPSSearchRegistry::set('in.period' , $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['view'] ); IPSSearchRegistry::set('in.vncFollowFilterOn', $vncPrefs[ IPSSearchRegistry::get('in.search_app') ]['vncFollowFilter'] ); $this->request['userMode'] = !empty($this->request['userMode']) ? $this->request['userMode'] : ''; IPSSearchRegistry::set('in.userMode' , $this->request['userMode'] ); /* Update member cache */ if ( isset( $this->request['period'] ) ) { IPSMember::setToMemberCache( $this->memberData, array( 'vncPrefs' => $vncPrefs ) ); } IPSDebug::addMessage( var_export( $vncPrefs, true ) ); IPSDebug::addMessage( 'Using: ' . IPSSearchRegistry::get('in.period') ); /* Can we do this? */ if ( IPSLib::appIsSearchable( IPSSearchRegistry::get('in.search_app'), 'vnc' ) || IPSLib::appIsSearchable( IPSSearchRegistry::get('in.search_app'), 'active' ) ) { /* Can't do a specific unread search, so */ if ( IPSSearchRegistry::get('in.period') == 'unread' && ! IPSLib::appIsSearchable( IPSSearchRegistry::get('in.search_app'), 'vncWithUnreadContent' ) ) { IPSSearchRegistry::set( 'in.period', 'lastvisit' ); } /* Perform the search */ $this->searchController->viewNewContent(); /* Get count */ $count = $this->searchController->getResultCount(); /* Get results which will be array of IDs */ $results = $this->searchController->getResultSet(); /* Get templates to use */ $template = $this->searchController->fetchTemplates(); /* Fetch sort details */ $sortDropDown = $this->searchController->fetchSortDropDown(); /* Fetch sort details */ $sortIn = $this->searchController->fetchSortIn(); /* Reset for template */ $this->_resetRequestParameters(); if( IPSSearchRegistry::get('in.start') > 0 AND !count($results) ) { $new_url = 'app=core&module=search&do=viewNewContent&period=' . IPSSearchRegistry::get('in.period') . '&userMode=' . IPSSearchRegistry::get('in.userMode') . '&search_app=' . IPSSearchRegistry::get('in.search_app') . '&sid=' . $this->request['_sid']; $new_url .= '&st=' . ( IPSSearchRegistry::get('in.start') - IPSSearchRegistry::get('opt.search_per_page') ) . '&search_app_filters[' . IPSSearchRegistry::get('in.search_app') . '][searchInKey]=' . $this->request['search_app_filters'][ IPSSearchRegistry::get('in.search_app') ]['searchInKey']; $this->registry->output->silentRedirect( $this->settings['base_url'] . $new_url ); } /* Parse result set */ $results = $this->registry->output->getTemplate( $template['group'] )->$template['template']( $results, ( IPSSearchRegistry::get('opt.searchType') == 'titles' || IPSSearchRegistry::get('opt.noPostPreview') ) ? 1 : 0 ); /* Build pagination */ $links = $this->registry->output->generatePagination( array( 'totalItems' => $count, 'itemsPerPage' => IPSSearchRegistry::get('opt.search_per_page'), 'currentStartValue' => IPSSearchRegistry::get('in.start'), //'method' => 'nextPrevious', 'baseUrl' => 'app=core&module=search&do=viewNewContent&period=' . IPSSearchRegistry::get('in.period') . '&userMode=' . IPSSearchRegistry::get('in.userMode') . '&search_app=' . IPSSearchRegistry::get('in.search_app') . '&sid=' . $this->request['_sid'] . '&search_app_filters[' . IPSSearchRegistry::get('in.search_app') . '][searchInKey]=' . $this->request['search_app_filters'][ IPSSearchRegistry::get('in.search_app') ]['searchInKey'] ) ); /* Showing */ $showing = array( 'start' => IPSSearchRegistry::get('in.start') + 1, 'end' => ( IPSSearchRegistry::get('in.start') + IPSSearchRegistry::get('opt.search_per_page') ) > $count ? $count : IPSSearchRegistry::get('in.start') + IPSSearchRegistry::get('opt.search_per_page') ); } else { $count = 0; $results = array(); } /* Add Debug message */ IPSDebug::addMessage( "View New Content Matches: " . $count ); /* Check for sortIn */ if( count( $sortIn ) && !$this->request['search_app_filters'][ $this->request['search_app'] ]['searchInKey'] ) { $this->request['search_app_filters'][ $this->request['search_app'] ]['searchInKey'] = $sortIn[0][0]; } /* Output */ $this->title = $this->lang->words['new_posts_title']; $this->registry->output->addNavigation( $this->lang->words['new_posts_title'], '' ); $this->output .= $this->registry->output->getTemplate( 'search' )->newContentView( $results, $links, $count, $sortDropDown, $sortIn, IPSSearchRegistry::get('set.resultCutToDate') ); } /** * Returns a url string that will maintain search results via links * * @return string */ protected function _buildURLString() { /* INI */ $url_string = 'app=core&module=search&do=search&andor_type=' . $this->request['andor_type']; $url_string .= '&sid=' . $this->request['_sid']; /* Add author name */ if( !empty( $this->request['search_author'] ) ) { $url_string .= "&search_author=" . urlencode($this->request['search_author']); } /* Search Range */ if( !empty( $this->request['search_date_start'] ) ) { $url_string .= "&search_date_start={$this->request['search_date_start']}"; } if( !empty( $this->request['search_date_end'] ) ) { $url_string .= "&search_date_end={$this->request['search_date_end']}"; } if( !empty( $this->request['search_app_filters'][ $this->request['search_app'] ]['sortKey'] ) ) { $url_string .= "&search_app_filters[{$this->request['search_app']}][sortKey]=" . $this->request['search_app_filters'][ $this->request['search_app'] ]['sortKey']; } if( !empty( $this->request['search_app_filters'][ $this->request['search_app'] ]['sortDir'] ) ) { $url_string .= "&search_app_filters[{$this->request['search_app']}][sortDir]=" . $this->request['search_app_filters'][ $this->request['search_app'] ]['sortDir']; } /* Contextual Type */ if ( IPSSearchRegistry::get('contextual.type') ) { $url_string .= "&cType=" . IPSSearchRegistry::get('contextual.type') . "&cId=" . IPSSearchRegistry::get('contextual.id'); } /* Content Only */ if( !empty( $this->request['search_content'] ) ) { $url_string .= "&search_content=" . $this->request['search_content']; } if ( IPSSearchRegistry::get('in.raw_search_tags') ) { $url_string .= "&search_tags=" . urlencode( IPSSearchRegistry::get('in.raw_search_tags') ); } /* Types */ if( isset( $this->request['type'] ) && isset( $this->request['type_id'] ) ) { $url_string .= "&type={$this->request['type']}&type_id={$this->request['type_id']}"; } if( isset( $this->request['type_2'] ) && isset( $this->request['type_id_2'] ) ) { $url_string .= "&type_2={$this->request['type_2']}&type_id_2={$this->request['type_id_2']}"; } if( isset($this->request['search_app_filters']) AND $this->request['search_app_filters'] ) { foreach( $this->request['search_app_filters'] as $app => $filters ) { if( $app == $this->request['search_app'] AND count($filters) ) { foreach( $filters as $_filterKey => $_filterValue ) { if( is_array($_filterValue) ) { foreach( $_filterValue as $_filterValueKey => $_filterValueValue ) { $url_string .= "&search_app_filters[{$app}][{$_filterKey}][{$_filterValueKey}]={$_filterValueValue}"; } } else { $url_string .= "&search_app_filters[{$app}][{$_filterKey}]={$_filterValue}"; } } } } } /* Fix up the search term a bit */ $_search_term = str_replace( '&', '&', $this->request['search_term'] ); $_search_term = str_replace( '"', '"', $_search_term ); $_search_term = str_replace( '>', '>', $_search_term ); $_search_term = str_replace( '<', '<', $_search_term ); $_search_term = str_replace( '$', '$', $_search_term ); $url_string .= '&search_term=' . urlencode( $_search_term ); return $url_string; } /** * Checks to see if the logged in user is allowed to use the search system * * @return @e void */ protected function _canSearch() { /* Check the search setting */ if( ! $this->settings['allow_search'] ) { if( $this->xml_out ) { @header( "Content-type: text/html;charset={$this->settings['gb_char_set']}" ); print $this->lang->words['search_off']; exit(); } else { $this->registry->output->showError( 'search_off', 10145 ); } } /* Check the member authorization */ if( ! isset( $this->memberData['g_use_search'] ) || ! $this->memberData['g_use_search'] ) { if( $this->xml_out ) { @header( "Content-type: text/html;charset={$this->settings['gb_char_set']}" ); print $this->lang->words['no_xml_permission']; exit(); } else { $this->registry->output->showError( 'no_permission_to_search', 10146, null, null, 403 ); } } } /** * Resets params for template */ protected function _resetRequestParameters() { $this->request['period'] = IPSSearchRegistry::get('in.period'); $this->request['search_app'] = IPSSearchRegistry::get('in.search_app'); $this->request['vncFollowFilterOn'] = IPSSearchRegistry::get('in.vncFollowFilterOn'); $this->request['followedItemsOnly'] = IPSSearchRegistry::get('in.vncFollowFilterOn'); } }