Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -114,7 +114,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$baseUrl = $baseUrl->setQueryString( 'tags', \IPS\Request::i()->tags );
|
||||
}
|
||||
|
||||
$types = $this->_contentTypes();
|
||||
$types = static::contentTypes();
|
||||
|
||||
/* Flood control */
|
||||
\IPS\Request::floodCheck();
|
||||
@@ -199,8 +199,16 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
foreach( $groups as $_idx => $groupId )
|
||||
{
|
||||
if( \IPS\Member\Group::load( $groupId )->g_bitoptions['gbw_hide_group'] )
|
||||
try
|
||||
{
|
||||
if( \IPS\Member\Group::load( $groupId )->g_bitoptions['gbw_hide_group'] )
|
||||
{
|
||||
unset( $groups[ $_idx ] );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* Group didn't exist, so let's ignore it */
|
||||
unset( $groups[ $_idx ] );
|
||||
}
|
||||
}
|
||||
@@ -339,9 +347,10 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
/* Set content type */
|
||||
if ( isset( \IPS\Request::i()->type ) and array_key_exists( \IPS\Request::i()->type, $types ) )
|
||||
{
|
||||
$class = $types[ \IPS\Request::i()->type ];
|
||||
|
||||
if ( isset( \IPS\Request::i()->item ) )
|
||||
{
|
||||
$class = $types[ \IPS\Request::i()->type ];
|
||||
try
|
||||
{
|
||||
$item = $class::loadAndCheckPerms( \IPS\Request::i()->item );
|
||||
@@ -392,19 +401,19 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$baseUrl = $baseUrl->setQueryString( 'search_min_comments', \IPS\Request::i()->search_min_comments );
|
||||
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_comments', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_comments ) ) );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_replies ) )
|
||||
if ( isset( \IPS\Request::i()->search_min_replies ) AND isset( $class::$commentClass ) )
|
||||
{
|
||||
$filter->minimumComments( \IPS\Request::i()->search_min_replies + 1 );
|
||||
$baseUrl = $baseUrl->setQueryString( 'search_min_replies', \IPS\Request::i()->search_min_replies );
|
||||
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_replies', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_replies ) ) );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_reviews ) )
|
||||
if ( isset( \IPS\Request::i()->search_min_reviews ) AND isset( $class::$reviewClass ) )
|
||||
{
|
||||
$filter->minimumReviews( \IPS\Request::i()->search_min_reviews );
|
||||
$baseUrl = $baseUrl->setQueryString( 'search_min_reviews', \IPS\Request::i()->search_min_reviews );
|
||||
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_reviews', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_reviews ) ) );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_views ) )
|
||||
if ( isset( \IPS\Request::i()->search_min_views ) AND isset( $class::$databaseColumnMap['views'] ) )
|
||||
{
|
||||
$filter->minimumViews( \IPS\Request::i()->search_min_views );
|
||||
$baseUrl = $baseUrl->setQueryString( 'search_min_views', \IPS\Request::i()->search_min_views );
|
||||
@@ -429,7 +438,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Filter by club */
|
||||
if ( isset( \IPS\Request::i()->club ) )
|
||||
if ( isset( \IPS\Request::i()->club ) AND \IPS\Settings::i()->clubs )
|
||||
{
|
||||
$clubIds = array();
|
||||
$clubNames = array();
|
||||
@@ -521,12 +530,16 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
$tagList = array_map( function( $val )
|
||||
{
|
||||
return '\'' . htmlentities( $val, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ) . '\'';
|
||||
return '\'' . htmlentities( $val, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ) . '\'';
|
||||
}, explode( ',', \IPS\Request::i()->tags ) );
|
||||
}
|
||||
$title = '';
|
||||
if ( \IPS\Request::i()->q )
|
||||
{
|
||||
\IPS\core\Facebook\Pixel::i()->Search = array(
|
||||
'search_string' => \IPS\Request::i()->q
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->tags )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' )
|
||||
@@ -588,10 +601,11 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$baseUrl = $baseUrl->setQueryString( 'sortby', \IPS\Request::i()->sortby );
|
||||
|
||||
$flags = ( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' ) ? \IPS\Content\Search\Query::TERM_AND_TAGS : \IPS\Content\Search\Query::TERM_OR_TAGS;
|
||||
|
||||
if ( isset( \IPS\Request::i()->search_and_or ) and \IPS\Request::i()->search_and_or === 'or' )
|
||||
$operator = NULL;
|
||||
|
||||
if ( isset( \IPS\Request::i()->search_and_or ) and in_array( \IPS\Request::i()->search_and_or, array( \IPS\Content\Search\Query::OPERATOR_OR, \IPS\Content\Search\Query::OPERATOR_AND ) ) )
|
||||
{
|
||||
$flags = $flags | \IPS\Content\Search\Query::TERM_OR_MODE;
|
||||
$operator = \IPS\Request::i()->search_and_or;
|
||||
$baseUrl = $baseUrl->setQueryString( 'search_and_or', \IPS\Request::i()->search_and_or );
|
||||
}
|
||||
|
||||
@@ -605,7 +619,8 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$results = $query->search(
|
||||
isset( \IPS\Request::i()->q ) ? ( \IPS\Request::i()->q ) : NULL,
|
||||
isset( \IPS\Request::i()->tags ) ? explode( ',', \IPS\Request::i()->tags ) : NULL,
|
||||
$flags + \IPS\Content\Search\Query::TAGS_MATCH_ITEMS_ONLY
|
||||
$flags + \IPS\Content\Search\Query::TAGS_MATCH_ITEMS_ONLY,
|
||||
$operator
|
||||
);
|
||||
|
||||
/* Get pagination */
|
||||
@@ -622,7 +637,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/* There's no point resetting the page at this point as the search query has been run and no results have been found */
|
||||
$_SESSION['lastSearch'] = 0;
|
||||
\IPS\Output::i()->redirect( $baseUrl->setQueryString( 'page', 1 ) );
|
||||
\IPS\Output::i()->redirect( $baseUrl->setQueryString( 'page', 1 ), NULL, 303 );
|
||||
}
|
||||
|
||||
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl, $pages, $page, $query->resultsToGet ) );
|
||||
@@ -690,7 +705,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Types */
|
||||
$types = array( '' => 'search_everything' );
|
||||
$contentTypes = $this->_contentTypes();
|
||||
$contentTypes = static::contentTypes();
|
||||
$contentToggles = array();
|
||||
$typeFields = array();
|
||||
$typeFieldToggles = array('' => array( 'club' ) );
|
||||
@@ -742,7 +757,13 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$types[ $k ] = $k . '_pl';
|
||||
if ( $k !== 'core_members' )
|
||||
{
|
||||
$typeFieldToggles[ $k ] = array_merge( $contentToggles, array( $k . '_node', 'search_min_views' ) );
|
||||
$typeFieldToggles[ $k ][] = $k . '_node';
|
||||
|
||||
if( isset( $class::$databaseColumnMap['views'] ) )
|
||||
{
|
||||
$typeFieldToggles[ $k ][] = 'search_min_views';
|
||||
}
|
||||
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
if ( $class::$firstCommentRequired )
|
||||
@@ -768,23 +789,26 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
/* Term */
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'q' ), NULL, 'search_tab_all' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'tags', \IPS\Request::i()->tags, FALSE, array( 'autocomplete' => TRUE ), NULL, NULL, NULL, 'tags' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'tags', \IPS\Request::i()->tags, FALSE, array( 'autocomplete' => array( 'minimized' => FALSE ) ), NULL, NULL, NULL, 'tags' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'eitherTermsOrTags', \IPS\Request::i()->eitherTermsOrTags, FALSE, array( 'options' => array( 'or' => 'termsortags_or_desc', 'and' => 'termsortags_and_desc' ) ), NULL, NULL, NULL, 'eitherTermsOrTags' ), NULL, 'search_tab_content' );
|
||||
|
||||
/* Author */
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'author', NULL, FALSE, array(), NULL, NULL, NULL, 'author' ), NULL, 'search_tab_content' );
|
||||
|
||||
/* Club */
|
||||
$clubs = \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'name', TRUE );
|
||||
if ( count( $clubs ) )
|
||||
if( \IPS\Settings::i()->clubs )
|
||||
{
|
||||
$clubOptions = array();
|
||||
foreach ( $clubs as $club )
|
||||
$clubs = \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'name', TRUE );
|
||||
if ( is_object( $clubs ) AND $clubs->count( TRUE ) )
|
||||
{
|
||||
$clubOptions[ "c{$club->id}" ] = $club->name;
|
||||
$clubOptions = array();
|
||||
foreach ( $clubs as $club )
|
||||
{
|
||||
$clubOptions[ "c{$club->id}" ] = $club->name;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'club', NULL, FALSE, array( 'options' => $clubOptions, 'parse' => 'normal', 'multiple' => TRUE, 'noDefault' => TRUE, 'class' => 'ipsField_fullWidth' ), NULL, NULL, NULL, 'club' ), NULL, 'search_tab_content' );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'club', NULL, FALSE, array( 'options' => $clubOptions, 'parse' => 'normal', 'multiple' => TRUE, 'noDefault' => TRUE, 'class' => 'ipsContained' ), NULL, NULL, NULL, 'club' ), NULL, 'search_tab_content' );
|
||||
}
|
||||
|
||||
/* Dates */
|
||||
@@ -795,15 +819,29 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Other filters */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'search_in', \IPS\Request::i()->search_in, FALSE, array( 'options' => array( 'all' => 'titles_and_body', 'titles' => 'titles_only' ) ), NULL, NULL, NULL, 'searchIn' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'search_and_or', \IPS\Request::i()->search_and_or, FALSE, array( 'options' => array( 'and' => 'search_and', 'or' => 'search_or' ) ), NULL, NULL, NULL, 'andOr' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'search_and_or', isset( \IPS\Request::i()->search_and_or ) ? \IPS\Request::i()->search_and_or : \IPS\Settings::i()->search_default_operator, FALSE, array( 'options' => array( 'and' => 'search_and', 'or' => 'search_or' ) ), NULL, NULL, NULL, 'andOr' ), NULL, 'search_tab_content' );
|
||||
|
||||
/* Nodes */
|
||||
foreach ( $contentTypes as $k => $class )
|
||||
{
|
||||
if ( isset( $class::$containerNodeClass ) )
|
||||
{
|
||||
$nodes = NULL;
|
||||
|
||||
/* If we have a node type, we should only select nodes for that type */
|
||||
if( isset( \IPS\Request::i()->type ) AND !empty( \IPS\Request::i()->type ) )
|
||||
{
|
||||
$typeInfo = explode( '_', \IPS\Request::i()->type );
|
||||
$typeClass = 'IPS\\' . $typeInfo[0] . '\\' . mb_ucfirst( $typeInfo[1] );
|
||||
|
||||
if( $typeClass == $class )
|
||||
{
|
||||
$nodes = ( isset( \IPS\Request::i()->nodes ) ) ? \IPS\Request::i()->nodes : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
$nodeClass = $class::$containerNodeClass;
|
||||
$field = new \IPS\Helpers\Form\Node( $k . '_node', ( isset( \IPS\Request::i()->nodes ) ) ? \IPS\Request::i()->nodes : NULL, FALSE, array( 'class' => $nodeClass, 'multiple' => TRUE, 'permissionCheck' => $nodeClass::searchableNodesPermission(), 'forceOwner' => FALSE, 'clubs' => \IPS\IPS::classUsesTrait( $nodeClass, 'IPS\Content\ClubContainer' ) ), NULL, NULL, NULL, $k . '_node' );
|
||||
$field = new \IPS\Helpers\Form\Node( $k . '_node', $nodes, FALSE, array( 'class' => $nodeClass, 'subnodes' => FALSE, 'multiple' => TRUE, 'permissionCheck' => $nodeClass::searchableNodesPermission(), 'forceOwner' => FALSE, 'clubs' => ( \IPS\Settings::i()->clubs AND \IPS\IPS::classUsesTrait( $nodeClass, 'IPS\Content\ClubContainer' ) ) ), NULL, NULL, NULL, $k . '_node' );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle );
|
||||
$form->add( $field, NULL, 'search_tab_nodes' );
|
||||
}
|
||||
@@ -1018,12 +1056,57 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle quicksearch and redirect to correct results page
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function quicksearch()
|
||||
{
|
||||
$query = array();
|
||||
|
||||
if ( \IPS\Request::i()->q )
|
||||
{
|
||||
$query['q'] = \IPS\Request::i()->q;
|
||||
|
||||
if ( \IPS\Request::i()->type != 'all' )
|
||||
{
|
||||
if ( mb_substr( \IPS\Request::i()->type, 0, 11 ) === 'contextual_' )
|
||||
{
|
||||
if ( $json = json_decode( mb_substr( \IPS\Request::i()->type, 11 ), TRUE ) )
|
||||
{
|
||||
foreach ( $json as $k => $v )
|
||||
{
|
||||
$query[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query['type'] = \IPS\Request::i()->type;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->search_and_or != \IPS\Settings::i()->search_default_operator )
|
||||
{
|
||||
$query['search_and_or'] = \IPS\Request::i()->search_and_or;
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->search_in == 'titles' )
|
||||
{
|
||||
$query['search_in'] = 'titles';
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=search&controller=search', 'front', 'search' )->setQueryString( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the different content type extensions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _contentTypes()
|
||||
public static function contentTypes()
|
||||
{
|
||||
$types = array();
|
||||
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
|
||||
@@ -1039,7 +1122,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
/**
|
||||
* Splits the search term into distinct matches
|
||||
* e.g. one "two three" beccomes ['one', 'two three']
|
||||
* e.g. one "two three" becomes ['one', 'two three']
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1050,10 +1133,12 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$words = preg_split("/[\s]*\\\"([^\\\"]+)\\\"[\s]*|[\s]*'([^']+)'[\s]*|[\s]+/", \IPS\Request::i()->q, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
$words = \IPS\Content\Search\Index::i()->stemmedTerms( $words );
|
||||
|
||||
foreach( $words as $idx => $word )
|
||||
{
|
||||
$words[ $idx ] = htmlentities( $word, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ); // ENT_QUOTES is because this will go in a HTML attribute (data-term="$value") so if you include a single quote in your search query, it can break
|
||||
$words[ $idx ] = htmlentities( $word, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ); // ENT_QUOTES is because this will go in a HTML attribute (data-term="$value") so if you include a single quote in your search query, it can break
|
||||
}
|
||||
|
||||
return json_encode( $words );
|
||||
@@ -1066,6 +1151,6 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function globalFilterOptions()
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'search' )->globalSearchMenuOptions( \IPS\Request::i()->checked ) );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'search' )->globalSearchMenuOptions( explode( ',', \IPS\Request::i()->exclude ) ) );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user