Version 4.7.0

This commit is contained in:
Neo committed 2025-12-19 16:00:35 -08:00
1 parent 517a5e1f70
commit 8ba7d43898
1933 files changed
+65613 -11332

No files matched your search

+73 -65
View File
@@ -609,7 +609,31 @@ class _Query extends \IPS\Content\Search\Query
$this->filterByUnread = TRUE;
}
/**
* Filter only solved content
*
* @return \IPS\Content\Search\Query (for daisy chaining)
*/
public function filterBySolved()
{
$this->where[] = array( 'index_item_solved=?', 1 );
return $this;
}
/**
* Filter only unsolved content
*
* @return \IPS\Content\Search\Query (for daisy chaining)
*/
public function filterByUnsolved()
{
$this->where[] = array( 'index_item_solved=?', 0 );
return $this;
}
/**
* Get the 'unread' where SQL
*
@@ -629,54 +653,61 @@ class _Query extends \IPS\Content\Search\Query
$unreadWheres = array();
$containerIds = array();
$containerClass = isset( $class::$containerNodeClass ) ? $class::$containerNodeClass : NULL;
foreach( $resetTimes as $containerId => $timestamp )
{
/* Pages has different classes per database, but recorded as 'cms' and the container ID in the marking tables */
if ( $containerClass and method_exists( $containerClass, 'isValidContainerId' ) )
{
if ( ! $containerClass::isValidContainerId( $containerId ) )
{
continue;
}
}
$timestamp = $timestamp ?: $this->member->marked_site_read;
$containerIds[] = $containerId;
$unreadWheres[] = '( index_container_id=' . $containerId . ' AND index_date_updated > ' . (int) $timestamp . ')';
$items = $this->member->markersItems( $application, \IPS\Content\Item::makeMarkerKey( $containerId ) );
if ( \count( $items ) )
if ( \is_array( $resetTimes ) )
{
foreach( $resetTimes as $containerId => $timestamp )
{
foreach( $items as $mid => $mtime )
/* Pages has different classes per database, but recorded as 'cms' and the container ID in the marking tables */
if ( $containerClass and method_exists( $containerClass, 'isValidContainerId' ) )
{
if ( $mtime > $timestamp )
if ( ! $containerClass::isValidContainerId( $containerId ) )
{
/* If an item has been moved from one container to another, the user may have a marker
in it's old location, with the previously 'read' time. In this circumstance, we need
to only use more recent read time, otherwise the topic may be incorrectly included
in the results */
if ( \in_array( $mid, $markers ) )
continue;
}
}
$timestamp = $timestamp ?: $this->member->marked_site_read;
$containerIds[] = $containerId;
$unreadWheres[] = '( index_container_id=' . $containerId . ' AND index_date_updated > ' . (int) $timestamp . ')';
$items = $this->member->markersItems( $application, \IPS\Content\Item::makeMarkerKey( $containerId ) );
if ( \count( $items ) )
{
foreach( $items as $mid => $mtime )
{
if ( $mtime > $timestamp )
{
$_key = array_search( $mid, $markers );
$_mtime = \intval( mb_substr( $_key, 0, mb_strpos( $_key, '.' ) ) );
if ( $_mtime < $mtime )
/* If an item has been moved from one container to another, the user may have a marker
in it's old location, with the previously 'read' time. In this circumstance, we need
to only use more recent read time, otherwise the topic may be incorrectly included
in the results */
if ( \in_array( $mid, $markers ) )
{
unset( $markers[ $_key ] );
}
/* If the existing timestamp is higher, retain that since we reset the $markers array below */
else
{
$mtime = $_mtime;
$_key = array_search( $mid, $markers );
$_mtime = \intval( mb_substr( $_key, 0, mb_strpos( $_key, '.' ) ) );
if ( $_mtime < $mtime )
{
unset( $markers[ $_key ] );
}
/* If the existing timestamp is higher, retain that since we reset the $markers array below */
else
{
$mtime = $_mtime;
}
}
$markers[ $mtime . '.' . $mid ] = $mid;
}
$markers[ $mtime . '.' . $mid ] = $mid;
}
}
}
}
else
{
$unreadWheres[] = "( index_date_updated > " . \intval( $resetTimes ) . ")";
}
if( \count( $containerIds ) )
@@ -972,37 +1003,13 @@ 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 ) == 501 )
if ( \count( $results ) )
{
/* 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 */
@@ -1260,8 +1267,9 @@ class _Query extends \IPS\Content\Search\Query
{
$order .= ", index_date_updated";
}
if( $this->filterByUnread === TRUE )
/* 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 )
{
$this->forceIndex = 'index_date_updated';
}