Version 4.7.23
This commit is contained in:
1 parent
7124a02564
commit
25ddeb65d6
1791 files changed
+76990
-44452
No files matched your search
@@ -73,6 +73,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$existingIndexId = NULL;
|
||||
$resetLastComment = FALSE;
|
||||
$newIndexId = NULL;
|
||||
$firstCommentId = $this->getFirstCommentId( $object );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -91,7 +92,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
unset( $indexData['index_prefix'] );
|
||||
}
|
||||
|
||||
if ( $object instanceof \IPS\Content\Comment and $existingIndexId and $existingData['index_is_last_comment'] and $indexData['index_is_last_comment'] and $indexData['index_item_id'] and $indexData['index_hidden'] !== 0 )
|
||||
if ( $object instanceof \IPS\Content\Comment and $existingIndexId and $existingData['index_is_last_comment'] and $indexData['index_item_id'] and $indexData['index_hidden'] !== 0 )
|
||||
{
|
||||
/* We do not allow hidden or needing approval comments to become flagged as the last comment as this means users without hidden view permission never see the item in an item only stream */
|
||||
$indexData['index_is_last_comment'] = 0;
|
||||
@@ -129,6 +130,8 @@ class _Index extends \IPS\Content\Search\Index
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_is_last_comment' => 0 ), array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? AND index_is_last_comment=1', $indexData['index_item_id'] ) );
|
||||
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_date_updated' => $indexData['index_date_updated'], 'index_date_commented' => $indexData['index_date_commented'] ), array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? and index_object_id=?', $indexData['index_item_id'], ( $firstCommentId ?? $indexData['index_item_id'] ) ) );
|
||||
}
|
||||
|
||||
if ( $existingData !== NULL and ( $indexData['index_class'] == $existingData['index_class'] and $indexData['index_object_id'] == $existingData['index_object_id'] ) )
|
||||
@@ -214,7 +217,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
if ( $resetLastComment )
|
||||
{
|
||||
$this->resetLastComment( array( $indexData['index_class'] ), $indexData['index_item_id'] );
|
||||
$this->resetLastComment( array( $indexData['index_class'] ), $indexData['index_item_id'], null, $firstCommentId );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,9 +227,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* Retrieve the search ID for an item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $object Item to add
|
||||
* @return void
|
||||
* @return string
|
||||
*/
|
||||
public function getIndexId( \IPS\Content\Searchable $object )
|
||||
public function getIndexId( \IPS\Content\Searchable $object ): string
|
||||
{
|
||||
$databaseColumnId = $object::$databaseColumnId;
|
||||
return \IPS\Db::i()->select( 'index_id', 'core_search_index', array( 'index_class=? AND index_object_id=?', \get_class( $object ),$object->$databaseColumnId ) )->first();
|
||||
@@ -266,7 +269,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
try
|
||||
{
|
||||
$this->resetLastComment( $classes, $object->mapped('item'), $object->$idColumn );
|
||||
$this->resetLastComment( $classes, $object->mapped('item'), $object->$idColumn, $this->getFirstCommentId( $object ) );
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
|
||||
@@ -583,14 +586,15 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param array $classes The classes (when first post is required, this is typically just \IPS\forums\Topic\Post but for others, it will be both item and comment classes)
|
||||
* @param int|NULL $indexItemId The index item ID
|
||||
* @param int|NULL $ignoreId ID to ignore because it is being removed
|
||||
* @param int|null $firstCommentId The first comment in this item, used only if $firstCommentRequired
|
||||
* @return void
|
||||
*/
|
||||
public function resetLastComment( $classes, $indexItemId, $ignoreId = NULL )
|
||||
public function resetLastComment( $classes, $indexItemId, $ignoreId = NULL, $firstCommentId = NULL )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_is_last_comment' => 0 ), array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? AND index_is_last_comment=1', $indexItemId ) );
|
||||
try
|
||||
{
|
||||
$latest = \IPS\Db::i()->select( 'index_object_id, index_date_updated, index_class', 'core_search_index', array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? and index_hidden=0', $indexItemId ), 'index_date_created DESC', array( 0, 1 ) )->first();
|
||||
$latest = \IPS\Db::i()->select( 'index_object_id, index_date_updated, index_class, index_date_commented', 'core_search_index', array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? and index_hidden=0', $indexItemId ), 'index_date_created DESC', array( 0, 1 ) )->first();
|
||||
}
|
||||
catch( \Exception )
|
||||
{
|
||||
@@ -619,7 +623,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_is_last_comment' => 1 ), array( 'index_class=? AND index_object_id=?', $latest['index_class'], $latest['index_object_id'] ) );
|
||||
|
||||
/* Now reset the item index with the latest comment time */
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_date_updated' => $latest['index_date_updated'], 'index_date_commented' => $latest['index_date_commented'] ), array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? AND index_object_id=?', $indexItemId, $indexItemId ) );
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_date_updated' => $latest['index_date_updated'], 'index_date_commented' => $latest['index_date_commented'] ), array( \IPS\Db::i()->in( 'index_class', $classes ) . ' AND index_item_id=? AND index_object_id=?', $indexItemId, ( $firstCommentId ?? $indexItemId ) ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -172,19 +172,19 @@ class _Query extends \IPS\Content\Search\Query
|
||||
|
||||
$this->joins[] = array( 'from' => $class::$databaseTable, 'where' => $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId . '=main.index_item_id' );
|
||||
|
||||
if ( $filter->minimumComments )
|
||||
if ( $filter->minimumComments AND isset( $class::$databaseColumnMap['num_comments'] ) )
|
||||
{
|
||||
$this->select[ $class::$databaseTable . '_comments' ] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['num_comments'];
|
||||
$clause[] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['num_comments'] . '>=' . \intval( $filter->minimumComments );
|
||||
}
|
||||
|
||||
if ( $filter->minimumReviews )
|
||||
if ( $filter->minimumReviews AND isset( $class::$databaseColumnMap['num_reviews'] ) )
|
||||
{
|
||||
$this->select[ $class::$databaseTable . '_reviews' ] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['num_reviews'];
|
||||
$clause[] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['num_reviews'] . '>=' . \intval( $filter->minimumReviews );
|
||||
}
|
||||
|
||||
if ( $filter->minimumViews )
|
||||
if ( $filter->minimumViews AND isset( $class::$databaseColumnMap['views'] ) )
|
||||
{
|
||||
$this->select[ $class::$databaseTable . '_views' ] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['views'];
|
||||
$clause[] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['views'] . '>=' . \intval( $filter->minimumViews );
|
||||
@@ -503,21 +503,24 @@ class _Query extends \IPS\Content\Search\Query
|
||||
else if ( \count( $followed ) )
|
||||
{
|
||||
/* IN is not a SIN. It's been a long day */
|
||||
$where[] = \IPS\Db::i()->in( 'index_author', $followed );
|
||||
$where[] = \IPS\Db::i()->in( 'index_author', $followed );
|
||||
}
|
||||
else
|
||||
else if ( ! $includeItems and ! $includeContainers )
|
||||
{
|
||||
/* There are no results */
|
||||
/* There are no results, and we only wanted members they followed */
|
||||
$this->where[] = "1=2 /*Filter by followed returned nothing*/";
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $ex )
|
||||
{
|
||||
/* There are no results */
|
||||
$this->where[] = "1=2 /*Filter by followed returned nothing*/";
|
||||
if ( ! $includeItems and ! $includeContainers )
|
||||
{
|
||||
/* There are no results and we only wanted members they followed */
|
||||
$this->where[] = "1=2 /*Filter by followed returned nothing*/";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Put it all together */
|
||||
if ( \count( $where ) )
|
||||
{
|
||||
@@ -905,7 +908,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
$termWhere = NULL;
|
||||
|
||||
/* Do we have tags? */
|
||||
if ( $tags !== NULL )
|
||||
if ( \IPS\Settings::i()->tags_enabled AND $tags !== NULL )
|
||||
{
|
||||
$itemsOnlyTagSearch = '';
|
||||
|
||||
@@ -1001,15 +1004,39 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
}
|
||||
|
||||
$results = iterator_to_array( \IPS\Db::i()->select( 'index_item_id, index_class', array( 'core_search_index_item_map', 'sub' ), array( array( 'index_author_id=' . \intval( $this->member->member_id ) . ' AND ' . \IPS\Db::i()->in( 'index_class', $classes ) ) ), 'index_item_id desc', array( 0, 501 ) ) );
|
||||
|
||||
if ( \count( $results ) )
|
||||
$results = iterator_to_array( \IPS\Db::i()->select( 'index_item_id, index_class', array( 'core_search_index_item_map', 'sub' ), array( array( 'index_author_id=' . \intval( $this->member->member_id ) . ' AND ' . \IPS\Db::i()->in( 'index_class', $classes ) ) ), 'index_item_id desc', array( 0, 801 ) ) );
|
||||
|
||||
if ( \count( $results ) == 801 )
|
||||
{
|
||||
/* Assume we have loads of matches, so do a full query */
|
||||
$subClause = array( array( 'sub.index_item_id=main.index_item_id AND index_author_id=' . \intval( $this->member->member_id ) . ' AND ' . $this->makeEmbeddedIfClauseForSearchMapTable('sub.index_class') ) );
|
||||
$query = \IPS\Db::i()->select( 'index_item_id', array( 'core_search_index_item_map', 'sub' ), $subClause );
|
||||
$where[] = array( 'EXISTS(?)', $query );
|
||||
}
|
||||
else if ( \count( $results ) )
|
||||
{
|
||||
$classIds = array();
|
||||
foreach( $results as $result )
|
||||
{
|
||||
$classIds[ $result['index_class'] ][] = $result['index_item_id'];
|
||||
}
|
||||
|
||||
$subWhere = array();
|
||||
foreach( $classIds as $class => $ids )
|
||||
{
|
||||
$stack = array( $class );
|
||||
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
$stack[] = $class::$commentClass;
|
||||
}
|
||||
|
||||
$subWhere[] = '(' . \IPS\Db::i()->in( 'index_class', $stack ) . ' and ' . \IPS\Db::i()->in( 'index_item_id', $ids ) . ')';
|
||||
}
|
||||
|
||||
/* IN is not a SIN. It's been a long day */
|
||||
$where[] = '(' . implode( ' OR ', $subWhere ) . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are no results */
|
||||
@@ -1264,7 +1291,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
|
||||
/* Set order clause */
|
||||
$order = $this->order;
|
||||
|
||||
|
||||
/* This forces MySQL to strongly hint a better index to the optimiser for MySQL 5.7+, even though sorting will not be affected */
|
||||
if ( !\IPS\CIC )
|
||||
{
|
||||
@@ -1276,7 +1303,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
|
||||
/* If we're filtering by unread, and not using MariaDB, then force an index because MySQL tends to use the incorrect one in this scenario. */
|
||||
if ( !mb_stristr( \IPS\Db::i()->server_info, '-MariaDB' ) and $this->filterByUnread === TRUE )
|
||||
if ( !mb_stristr( \IPS\Db::i()->server_info, '-MariaDB' ) and $this->filterByUnread === TRUE and \IPS\Db::i()->server_version < 80000 )
|
||||
{
|
||||
$this->forceIndex = 'index_date_updated';
|
||||
}
|
||||
@@ -1288,7 +1315,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
if ( mb_substr( $this->order, 0, 9 ) === 'calcscore' )
|
||||
{
|
||||
/* But we can only do that if there's a term (rather than tag-only) */
|
||||
if ( $term !== NULL )
|
||||
if ( static::canUseRelevancy() and $term !== NULL )
|
||||
{
|
||||
if ( \IPS\Settings::i()->search_title_boost )
|
||||
{
|
||||
@@ -1311,7 +1338,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
. ',1.5)' // To the power of 1.5
|
||||
. ' AS calcscore';
|
||||
}
|
||||
/* So if we don't have a term, fallback to last updated */
|
||||
/* So if we don't have a term ot can't use relevancy, fallback to last updated */
|
||||
else
|
||||
{
|
||||
$order = 'index_date_updated DESC';
|
||||
@@ -1369,7 +1396,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
*/
|
||||
public function getDefaultDateCutOff()
|
||||
{
|
||||
if ( \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD and static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
if ( \IPS\USE_MYSQL_SEARCH_OPTIMIZED_MODE )
|
||||
{
|
||||
return 'year';
|
||||
}
|
||||
@@ -1384,13 +1411,23 @@ class _Query extends \IPS\Content\Search\Query
|
||||
*/
|
||||
public function getDefaultSortMethod()
|
||||
{
|
||||
if ( \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD and static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
if ( \IPS\USE_MYSQL_SEARCH_OPTIMIZED_MODE )
|
||||
{
|
||||
return 'newest';
|
||||
}
|
||||
|
||||
return parent::getDefaultSortMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can use relevancy?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function canUseRelevancy(): bool
|
||||
{
|
||||
return ! \IPS\USE_MYSQL_SEARCH_OPTIMIZED_MODE;
|
||||
}
|
||||
|
||||
protected static $tableCount = NULL;
|
||||
|
||||
@@ -1403,9 +1440,27 @@ class _Query extends \IPS\Content\Search\Query
|
||||
{
|
||||
if ( static::$tableCount === NULL )
|
||||
{
|
||||
/* Try and be more efficient */
|
||||
try
|
||||
{
|
||||
if( $result = \IPS\Db::i()->query( "SELECT TABLE_ROWS as _size FROM `information_schema`.`TABLES` WHERE TABLE_SCHEMA = '" . \IPS\Settings::i()->sql_database . "' AND TABLE_NAME='" . \IPS\Db::i()->prefix . "core_search_index'" ) )
|
||||
{
|
||||
if( $resultSet = $result->fetch_assoc() )
|
||||
{
|
||||
static::$tableCount = (int) $resultSet['_size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
}
|
||||
|
||||
/* Did that fail? */
|
||||
if ( static::$tableCount === NULL )
|
||||
{
|
||||
/* Do it the old-fashioned way */
|
||||
static::$tableCount = \IPS\Db::i()->select( 'COUNT(*)', 'core_search_index' )->first();
|
||||
}
|
||||
|
||||
|
||||
return static::$tableCount;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user