Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+98 -15
View File
@@ -11,7 +11,7 @@
namespace IPS\Content\Search\Mysql;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -56,7 +56,7 @@ class _Index extends \IPS\Content\Search\Index
{
/* Get the index data */
$indexData = $this->indexData( $object );
$class = get_class( $object );
$class = \get_class( $object );
/* If we got the data... */
if( $indexData )
@@ -167,7 +167,7 @@ class _Index extends \IPS\Content\Search\Index
}
/* Add add them back if we have any */
if ( count( $tags ) )
if ( \count( $tags ) )
{
foreach( $tags as $tag )
{
@@ -229,7 +229,7 @@ class _Index extends \IPS\Content\Search\Index
public function getIndexId( \IPS\Content\Searchable $object )
{
$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();
return \IPS\Db::i()->select( 'index_id', 'core_search_index', array( 'index_class=? AND index_object_id=?', \get_class( $object ),$object->$databaseColumnId ) )->first();
}
/**
@@ -240,7 +240,7 @@ class _Index extends \IPS\Content\Search\Index
*/
public function removeFromSearchIndex( \IPS\Content\Searchable $object )
{
$class = get_class( $object );
$class = \get_class( $object );
$idColumn = $class::$databaseColumnId;
/* Tags */
@@ -266,7 +266,7 @@ class _Index extends \IPS\Content\Search\Index
try
{
$this->resetLastComment( $classes, $object->mapped('item') );
$this->resetLastComment( $classes, $object->mapped('item'), $object->$idColumn );
}
catch( \Exception $ex ) { }
@@ -300,6 +300,41 @@ class _Index extends \IPS\Content\Search\Index
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=? AND index_item_id=?', $reviewClass, $object->$idColumn ) );
}
}
/**
* Direct removal from the search index - only used when we don't need to perform ancillary cleanup (i.e. orphaned data)
*
* @param string $class Class
* @param int $id ID
* @return void
*/
public function directIndexRemoval( $class, $id )
{
/* Tags */
$this->_deleteTagsFromIndex( $class, $id );
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=? AND index_object_id=?', $class, $id ) );
/* If this was a comment, we really need to reset the index_is_last_comment flag if it was set */
if ( is_subclass_of( $class, 'IPS\Content\Item' ) )
{
\IPS\Db::i()->delete( 'core_search_index_item_map', array( 'index_class=? AND index_item_id=?', $class, $id ) );
}
if ( isset( $class::$commentClass ) )
{
$commentClass = $class::$commentClass;
$this->_deleteTagsFromIndex( $commentClass, $id );
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=? AND index_item_id=?', $commentClass, $id ) );
}
if ( isset( $class::$reviewClass ) )
{
$reviewClass = $class::$reviewClass;
$this->_deleteTagsFromIndex( $reviewClass, $id );
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=? AND index_item_id=?', $reviewClass, $id ) );
}
}
/**
* Return the index IDs associated with this class and $id
@@ -319,7 +354,7 @@ class _Index extends \IPS\Content\Search\Index
$ids = FALSE;
}
if ( is_array( $ids ) and count( $ids ) < 1000 )
if ( \is_array( $ids ) and \count( $ids ) < 1000 )
{
\IPS\Db::i()->delete( 'core_search_index_tags', array( \IPS\Db::i()->in( 'index_id', $ids ) ) );
}
@@ -328,6 +363,52 @@ class _Index extends \IPS\Content\Search\Index
\IPS\Db::i()->delete( 'core_search_index_tags', array( 'index_id IN( ? )', \IPS\Db::i()->select( 'index_id', 'core_search_index', array( 'index_class=? AND index_item_id=?', $class, $id ) ) ) );
}
}
/**
* Removes all content for a specific application from the index (for example, when uninstalling).
*
* @param \IPS\Application $application The application
* @return void
*/
public function removeApplicationContent( \IPS\Application $application )
{
$classes = array();
foreach ( $application->extensions( 'core', 'ContentRouter' ) as $router )
{
foreach( $router->classes AS $class )
{
if ( is_subclass_of( $class, 'IPS\Content\Searchable' ) )
{
$classes[] = $class;
if ( isset( $class::$commentClass ) )
{
$commentClass = $class::$commentClass;
if ( is_subclass_of( $commentClass, 'IPS\Content\Searchable' ) )
{
$classes[] = $commentClass;
}
}
if ( isset( $class::$reviewClass ) )
{
$reviewClass = $class::$reviewClass;
if ( is_subclass_of( $reviewClass, 'IPS\Content\Searchable' ) )
{
$classes[] = $reviewClass;
}
}
}
}
}
$where = array( \IPS\Db::i()->in( 'index_class', $classes ) );
\IPS\Db::i()->delete( 'core_search_index_item_map', $where );
\IPS\Db::i()->delete( 'core_search_index_tags', array( 'index_id IN( ? )', \IPS\Db::i()->select( 'index_id', 'core_search_index', $where ) ) );
\IPS\Db::i()->delete( 'core_search_index', $where );
}
/**
* Removes all content for a classs
@@ -394,7 +475,7 @@ class _Index extends \IPS\Content\Search\Index
{
$update['index_container_id'] = $newContainer;
if ( $itemClass = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) ? $class : $class::$itemClass ) and $containerClass = $itemClass::$containerNodeClass and \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) and $clubIdColumn = $containerClass::clubIdColumn() )
if ( $itemClass = ( \in_array( 'IPS\Content\Item', class_parents( $class ) ) ? $class : $class::$itemClass ) and $containerClass = $itemClass::$containerNodeClass and \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) and $clubIdColumn = $containerClass::clubIdColumn() )
{
try
{
@@ -415,7 +496,7 @@ class _Index extends \IPS\Content\Search\Index
$update['index_item_author'] = $newItemAuthorId;
}
if ( count( $update ) )
if ( \count( $update ) )
{
\IPS\Db::i()->update( 'core_search_index', $update, $where );
}
@@ -423,7 +504,7 @@ class _Index extends \IPS\Content\Search\Index
{
$addAuthorToPermissionsWhere = $where;
$addAuthorToPermissionsWhere[] = array( 'index_author<>0' );
\IPS\Db::i()->update( 'core_search_index', "index_permissions = CONCAT( index_permissions, ',m.', index_author )", $addAuthorToPermissionsWhere );
\IPS\Db::i()->update( 'core_search_index', "index_permissions = CONCAT( index_permissions, ',m', index_author )", $addAuthorToPermissionsWhere );
}
if ( $newHiddenStatus !== NULL )
@@ -486,8 +567,8 @@ class _Index extends \IPS\Content\Search\Index
{
$prefix = \IPS\Db::i()->prefix;
\IPS\Db::i()->query( "DELETE {$prefix}core_search_index_item_map FROM {$prefix}core_search_index_item_map, {$prefix}core_search_index WHERE {$prefix}core_search_index_item_map.index_item_id={$prefix}core_search_index.index_item_id AND index_date_updated < " . $cutoff->getTimestamp() );
\IPS\Db::i()->query( "DELETE {$prefix}core_search_index_tags FROM {$prefix}core_search_index_tags, {$prefix}core_search_index WHERE {$prefix}core_search_index_tags.index_id={$prefix}core_search_index.index_id AND index_date_updated < " . $cutoff->getTimestamp() );
\IPS\Db::i()->delete( array( 'core_search_index_item_map', 'core_search_index' ), array( "core_search_index_item_map.index_item_id=core_search_index.index_item_id AND (core_search_index.index_id=core_search_index.index_item_index_id AND index_date_updated < ?)", $cutoff->getTimestamp() ), NULL, NULL, NULL, 'core_search_index_item_map' );
\IPS\Db::i()->delete( array( 'core_search_index_tags', 'core_search_index' ), array( "core_search_index_tags.index_id=core_search_index.index_id AND (core_search_index.index_id=core_search_index.index_item_index_id AND index_date_updated < ?)", $cutoff->getTimestamp() ), NULL, NULL, NULL, 'core_search_index_tags' );
\IPS\Db::i()->delete( 'core_search_index', array( 'index_date_updated < ?', $cutoff->getTimestamp() ) );
}
else
@@ -503,9 +584,10 @@ 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
* @return void
*/
public function resetLastComment( $classes, $indexItemId )
public function resetLastComment( $classes, $indexItemId, $ignoreId = 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=?', $indexItemId ) );
@@ -537,14 +619,15 @@ class _Index extends \IPS\Content\Search\Index
*
* @param array $itemIndexIds Item index IDs
* @param \IPS\Member $member The member
* @param int|NULL $limit Number of results to return
* @return array
*/
public function hashesWithPermission( array $hashes, \IPS\Member $member )
public function hashesWithPermission( array $hashes, \IPS\Member $member, $limit = NULL )
{
return iterator_to_array( \IPS\Db::i()->select( 'index_class_type_id_hash', array( 'core_search_index', 'si' ), array(
array( "( si.index_permissions = '*' OR " . \IPS\Db::i()->findInSet( 'si.index_permissions', \IPS\Member::loggedIn()->permissionArray() ) . ' AND si.index_hidden=0 )' ),
array( \IPS\Db::i()->in( 'si.index_class_type_id_hash', $hashes ) )
) )->setKeyField('index_class_type_id_hash') );
), NULL, $limit )->setKeyField('index_class_type_id_hash') );
}
/**