Version 4.7.6

This commit is contained in:
Neo committed 2025-12-19 16:05:19 -08:00
1 parent 8ba7d43898
commit 7b7404e741
1085 files changed
+30590 -7837

No files matched your search

+83 -69
View File
@@ -51,80 +51,87 @@ class _Index extends \IPS\Content\Search\Index
*/
public function init()
{
$analyzer = \IPS\Settings::i()->search_elastic_analyzer;
$settings = array(
'max_result_window' => \IPS\Settings::i()->search_index_maxresults
);
if ( $analyzer === 'custom' )
{
$settings['analysis'] = json_decode( '{' . \IPS\Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
$analyzer = key( $settings['analysis']['analyzer'] );
}
\IPS\Content\Search\Elastic\Index::request( $this->url )->delete();
$definition = array(
'settings' => $settings,
'mappings' => array(
'_doc' => array(
'properties' => array(
'index_class' => array( 'type' => 'keyword' ),
'index_object_id' => array( 'type' => 'long' ),
'index_item_id' => array( 'type' => 'long' ),
'index_container_class' => array( 'type' => 'keyword' ),
'index_container_id' => array( 'type' => 'long' ),
'index_title' => array(
'type' => 'text',
'analyzer' => $analyzer,
),
'index_content' => array(
'type' => 'text',
'analyzer' => $analyzer,
),
'index_permissions' => array( 'type' => 'keyword' ),
'index_date_created' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_date_updated' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_date_commented' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_author' => array( 'type' => 'long' ),
'index_tags' => array( 'type' => 'keyword' ),
'index_prefix' => array( 'type' => 'keyword' ),
'index_hidden' => array( 'type' => 'byte' ),
'index_item_index_id' => array( 'type' => 'keyword' ),
'index_item_author' => array( 'type' => 'long' ),
'index_is_last_comment' => array( 'type' => 'boolean' ),
'index_club_id' => array( 'type' => 'long' ),
'index_class_type_id_hash' => array( 'type' => 'keyword' ),
'index_comments' => array( 'type' => 'long' ),
'index_reviews' => array( 'type' => 'long' ),
'index_participants' => array( 'type' => 'long' ),
'index_is_anon' => array( 'type' => 'byte' ),
'index_item_solved' => array( 'type' => 'byte' )
)
)
)
);
try
{
$response = \IPS\Content\Search\Elastic\Index::request( $this->url->setQueryString( 'include_type_name', 'true' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
if( $response->httpResponseCode != 200 )
$analyzer = \IPS\Settings::i()->search_elastic_analyzer;
$settings = array(
'max_result_window' => \IPS\Settings::i()->search_index_maxresults
);
if ( $analyzer === 'custom' )
{
throw new \RuntimeException;
$settings['analysis'] = json_decode( '{' . \IPS\Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
$analyzer = key( $settings['analysis']['analyzer'] );
}
\IPS\Content\Search\Elastic\Index::request( $this->url )->delete();
$definition = array(
'settings' => $settings,
'mappings' => array(
'_doc' => array(
'properties' => array(
'index_class' => array( 'type' => 'keyword' ),
'index_object_id' => array( 'type' => 'long' ),
'index_item_id' => array( 'type' => 'long' ),
'index_container_class' => array( 'type' => 'keyword' ),
'index_container_id' => array( 'type' => 'long' ),
'index_title' => array(
'type' => 'text',
'analyzer' => $analyzer,
),
'index_content' => array(
'type' => 'text',
'analyzer' => $analyzer,
),
'index_permissions' => array( 'type' => 'keyword' ),
'index_date_created' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_date_updated' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_date_commented' => array(
'type' => 'date',
'format' => 'epoch_second',
),
'index_author' => array( 'type' => 'long' ),
'index_tags' => array( 'type' => 'keyword' ),
'index_prefix' => array( 'type' => 'keyword' ),
'index_hidden' => array( 'type' => 'byte' ),
'index_item_index_id' => array( 'type' => 'keyword' ),
'index_item_author' => array( 'type' => 'long' ),
'index_is_last_comment' => array( 'type' => 'boolean' ),
'index_club_id' => array( 'type' => 'long' ),
'index_class_type_id_hash' => array( 'type' => 'keyword' ),
'index_comments' => array( 'type' => 'long' ),
'index_reviews' => array( 'type' => 'long' ),
'index_participants' => array( 'type' => 'long' ),
'index_is_anon' => array( 'type' => 'byte' ),
'index_item_solved' => array( 'type' => 'byte' )
)
)
)
);
try
{
$response = \IPS\Content\Search\Elastic\Index::request( $this->url->setQueryString( 'include_type_name', 'true' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
if( $response->httpResponseCode != 200 )
{
throw new \RuntimeException;
}
}
catch( \Exception $e )
{
$response = \IPS\Content\Search\Elastic\Index::request( $this->url )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
}
}
catch( \Exception $e )
catch ( \Exception $e )
{
$response = \IPS\Content\Search\Elastic\Index::request( $this->url )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
\IPS\Log::log( $e, 'elasticsearch' );
}
}
@@ -314,13 +321,20 @@ class _Index extends \IPS\Content\Search\Index
$participants += iterator_to_array( \IPS\Db::i()->select( 'DISTINCT ' . $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['author'], $reviewClass::$databaseTable, array( $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['item'] . '=?', $item->$databaseColumnId ) ) );
}
$participants = array_values( array_unique( $participants ) );
$isSolved = 0;
if ( \IPS\IPS::classUsesTrait( $item, 'IPS\Content\Solvable' ) and $item->isSolved() )
{
$isSolved = 1;
}
return array(
'index_comments' => $item->mapped('num_comments'),
'index_reviews' => $item->mapped('num_reviews'),
'index_participants' => $participants,
'index_tags' => $item->tags(),
'index_prefix' => $item->prefix(),
'index_item_solved' => $isSolved
);
}
+28
View File
@@ -390,10 +390,24 @@ class _Query extends \IPS\Content\Search\Query
/* Some container types cannot be cached */
$classes = [];
$conditions = [];
$noSimilarContentClasses = [];
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', FALSE ) as $object )
{
$classes = array_merge( $object->classes, $classes );
if ( ! $object->similarContent )
{
foreach( $object->classes as $class )
{
$noSimilarContentClasses[] = $class;
if ( is_subclass_of( $class, 'IPS\Content\Item' ) and isset( $class::$commentClass ) )
{
$noSimilarContentClasses[] = $class::$commentClass;
}
}
}
}
/* Some nodes have complex permissions, so avoid any permission issues by not selecting these */
@@ -440,6 +454,20 @@ class _Query extends \IPS\Content\Search\Query
}
}
/* Prevent some things from being in similar content widget */
if ( \count( $noSimilarContentClasses ) )
{
$this->mustNot[] = array(
'bool' => array(
'filter' => array(
array(
'terms' => array( 'index_class' => $noSimilarContentClasses )
)
)
)
);
}
/* Only show non-hidden and approved items */
$this->setHiddenFilter( static::HIDDEN_VISIBLE );
}
-2
View File
@@ -565,8 +565,6 @@ class _Index extends \IPS\Content\Search\Index
{
if ( $cutoff )
{
$prefix = \IPS\Db::i()->prefix;
\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() ) );
+11 -8
View File
@@ -1263,15 +1263,18 @@ class _Query extends \IPS\Content\Search\Query
$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 ( $this->filterByUnread !== FALSE and ( ! mb_stristr( \IPS\Db::i()->server_info, '-MariaDB' ) and \IPS\Db::i()->server_version >= 50700 ) )
if ( !\IPS\CIC )
{
$order .= ", index_date_updated";
}
/* 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';
if ( $this->filterByUnread !== FALSE and ( ! mb_stristr( \IPS\Db::i()->server_info, '-MariaDB' ) and \IPS\Db::i()->server_version >= 50700 ) )
{
$order .= ", index_date_updated";
}
/* 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';
}
}
/* But we're sorting by relevancy, we need to actually select that value with our fancy algorithm */