Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
+155
-33
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Abstract Search Query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -27,6 +27,7 @@ abstract class _Query
|
||||
const TERM_AND_TAGS = 2;
|
||||
const TERM_OR_MODE = 4;
|
||||
const TERM_TITLES_ONLY = 8;
|
||||
const TAGS_MATCH_ITEMS_ONLY = 16;
|
||||
|
||||
const HIDDEN_VISIBLE = 0;
|
||||
const HIDDEN_UNAPPROVED = 1;
|
||||
@@ -80,22 +81,13 @@ abstract class _Query
|
||||
|
||||
/* Exclude disabled applications */
|
||||
$filters = array();
|
||||
foreach ( \IPS\Application::applications() as $application )
|
||||
foreach ( \IPS\Content::routedClasses( $member, FALSE, TRUE ) as $class )
|
||||
{
|
||||
if ( !$application->enabled )
|
||||
{
|
||||
foreach ( $application->extensions( 'core', 'ContentRouter' ) as $extension )
|
||||
{
|
||||
foreach ( $extension->classes as $class )
|
||||
{
|
||||
$filters[] = \IPS\Content\Search\ContentFilter::init( $class );
|
||||
}
|
||||
}
|
||||
}
|
||||
$filters[] = \IPS\Content\Search\ContentFilter::init( $class );
|
||||
}
|
||||
if ( !empty( $filters ) )
|
||||
{
|
||||
$this->filterByContent( $filters, FALSE );
|
||||
$this->filterByContent( $filters );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +223,26 @@ abstract class _Query
|
||||
*/
|
||||
abstract public function search( $term = NULL, $tags = NULL, $method = 1 );
|
||||
|
||||
/**
|
||||
* Get the default date cut off
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultDateCutOff()
|
||||
{
|
||||
return 'any';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default sort method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultSortMethod()
|
||||
{
|
||||
return 'relevancy';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
@@ -256,38 +268,148 @@ abstract class _Query
|
||||
}
|
||||
|
||||
/**
|
||||
* Term as words array
|
||||
* Returns an array of words. A word is considered as either an entire phrase (eg "sticks stones") when $ignorePhrase is FALSE, or a sequence of characters delimited by a space.
|
||||
* Words smaller than 2 characters are ignored.
|
||||
* Convert the term into an array of words
|
||||
*
|
||||
* @param string $term The term to search for
|
||||
* @param boolean $ignorePhrase When true, phrases are stripped of quotes and treated as normal words
|
||||
* @param int $minLength The minimum length a sequence of characters has to be before it is considered a word
|
||||
* @param string $term The term to search for
|
||||
* @param boolean $ignorePhrase When true, phrases are stripped of quotes and treated as normal words
|
||||
* @param int|NULL $minLength The minimum length a sequence of characters has to be before it is considered a word. If null, ft_min_word_len/innodb_ft_min_token_size is used.
|
||||
* @param int|NULL $maxLength The maximum length a sequence of characters can be for it to be considered a word. If null, ft_max_word_len/innodb_ft_max_token_size is used.
|
||||
* @return array
|
||||
*/
|
||||
public static function termAsWordsArray( $term, $ignorePhrase=FALSE, $minLength=3 )
|
||||
{
|
||||
if ( static::termIsPhrase( $term ) )
|
||||
public static function termAsWordsArray( $term, $ignorePhrase=FALSE, $minLength=NULL, $maxLength=NULL )
|
||||
{
|
||||
/* If we haven't set a preferred min/max length, use the MySQL configuration */
|
||||
if ( $minLength === NULL or $maxLength === NULL )
|
||||
{
|
||||
if ( ! $ignorePhrase )
|
||||
/* If we don't already know what they are, get the values from the MySQL configuration */
|
||||
if ( ( $minLength === NULL and !isset( \IPS\Data\Store::i()->mysqlMinWord ) ) or ( $maxLength === NULL and !isset( \IPS\Data\Store::i()->mysqlMaxWord ) ) )
|
||||
{
|
||||
return array( $term );
|
||||
/* The variable we need depends on whether the table is MyISAM or InnoDB */
|
||||
$tableDefinition = \IPS\Db::i()->getTableDefinition('core_search_index');
|
||||
if ( $tableDefinition['engine'] == 'InnoDB' )
|
||||
{
|
||||
$minVariable = 'innodb_ft_min_token_size';
|
||||
$maxVariable = 'innodb_ft_max_token_size';
|
||||
}
|
||||
else
|
||||
{
|
||||
$minVariable = 'ft_min_word_len';
|
||||
$maxVariable = 'ft_max_word_len';
|
||||
}
|
||||
|
||||
/* Now fetch those */
|
||||
try
|
||||
{
|
||||
foreach ( new \IPS\Db\Select( 'SHOW VARIABLES WHERE Variable_Name=? OR Variable_Name=?', array( $minVariable, $maxVariable ), \IPS\Db::i() ) as $row )
|
||||
{
|
||||
if ( $row['Variable_name'] === $minVariable )
|
||||
{
|
||||
\IPS\Data\Store::i()->mysqlMinWord = intval( $row['Value'] );
|
||||
}
|
||||
elseif ( $row['Variable_name'] === $maxVariable )
|
||||
{
|
||||
\IPS\Data\Store::i()->mysqlMaxWord = intval( $row['Value'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \IPS\Db\Exception $e ) { }
|
||||
|
||||
/* If we weren't able to get them, set sensible defaults */
|
||||
if ( !isset( \IPS\Data\Store::i()->mysqlMinWord ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->mysqlMinWord = 3;
|
||||
}
|
||||
if ( !isset( \IPS\Data\Store::i()->mysqlMaxWord ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->mysqlMaxWord = 84;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Set */
|
||||
if ( $minLength === NULL )
|
||||
{
|
||||
$term = str_replace( '"', '', $term );
|
||||
$minLength = \IPS\Data\Store::i()->mysqlMinWord;
|
||||
}
|
||||
if ( $maxLength === NULL )
|
||||
{
|
||||
$maxLength = \IPS\Data\Store::i()->mysqlMaxWord;
|
||||
}
|
||||
}
|
||||
|
||||
$theWords = array();
|
||||
foreach( explode( ' ', $term ) as $_term )
|
||||
/* Sub quotes with smaller than min word strings can cause issues for larger tables, so we convert the sub quote into normal words for a boolean search */
|
||||
if ( ! static::termIsPhrase( $term ) )
|
||||
{
|
||||
if ( mb_strlen( $_term ) > $minLength )
|
||||
preg_match_all( '#"([^"]+?)"#', $term, $matches, PREG_SET_ORDER );
|
||||
|
||||
foreach( $matches as $match )
|
||||
{
|
||||
$theWords[] = $_term;
|
||||
$allWordsInPhraseAreGood = true;
|
||||
$subWords = array();
|
||||
foreach( explode( ' ', $match[1] ) as $subWord )
|
||||
{
|
||||
if ( mb_strlen( $subWord ) <= $minLength or mb_strlen( $subWord ) >= $maxLength )
|
||||
{
|
||||
$allWordsInPhraseAreGood = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$subWords[] = $subWord;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $allWordsInPhraseAreGood )
|
||||
{
|
||||
$term = str_replace( $match[0], implode( ' ', $subWords ), $term );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $theWords;
|
||||
|
||||
/* Parse */
|
||||
$words = array();
|
||||
$currentWord = '';
|
||||
$inQuote = false;
|
||||
$termLength = mb_strlen( $term );
|
||||
for ( $i = 0; $i < $termLength; $i++ )
|
||||
{
|
||||
$c = mb_substr( $term, $i, 1 );
|
||||
if ( $c == '"' )
|
||||
{
|
||||
if ( $ignorePhrase )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$inQuote = !$inQuote;
|
||||
}
|
||||
elseif ( $c == ' ' and !$inQuote )
|
||||
{
|
||||
$words[] = trim( $currentWord );
|
||||
$currentWord = '';
|
||||
}
|
||||
$currentWord .= $c;
|
||||
}
|
||||
$words[] = trim( $currentWord );
|
||||
|
||||
/* Now check each of the words is acceptable */
|
||||
$finalWords = array();
|
||||
foreach( $words as $word )
|
||||
{
|
||||
if ( mb_strlen( $word ) >= $minLength and mb_strlen( $word ) <= $maxLength )
|
||||
{
|
||||
$finalWords[] = $word;
|
||||
}
|
||||
}
|
||||
|
||||
/* And return */
|
||||
return $finalWords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a rebuild task running?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isRebuildRunning()
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'core_queue', array( '`key`=?', 'RebuildSearchIndex' ) )->first() ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user