Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,16 +11,49 @@
|
||||
namespace IPS\Content\Search\Elastic;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Content\Comment;
|
||||
use IPS\Content\Item;
|
||||
use IPS\Content\Search\Index as SearchIndex;
|
||||
use IPS\Content\Search\Elastic\Exception as ElasticException;
|
||||
use IPS\Content;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Request\Exception as RequestException;
|
||||
use IPS\Http\Request\Curl;
|
||||
use IPS\Http\Response;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use OutOfRangeException;
|
||||
use RuntimeException;
|
||||
use StdClass;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
use function is_null;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
use const IPS\ELASTICSEARCH_PASSWORD;
|
||||
use const IPS\ELASTICSEARCH_USER;
|
||||
use const IPS\LONG_REQUEST_TIMEOUT;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elasticsearch Search Index
|
||||
*/
|
||||
class _Index extends \IPS\Content\Search\Index
|
||||
class Index extends SearchIndex
|
||||
{
|
||||
/**
|
||||
* @brief Elasticsearch version requirements
|
||||
@@ -31,15 +64,15 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* @brief The server URL
|
||||
*/
|
||||
protected $url;
|
||||
protected Url $url;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url $url The server URL
|
||||
* @param Url $url The server URL
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Http\Url $url )
|
||||
public function __construct( Url $url )
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
@@ -49,21 +82,21 @@ class _Index extends \IPS\Content\Search\Index
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
public function init(): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$analyzer = \IPS\Settings::i()->search_elastic_analyzer;
|
||||
$analyzer = Settings::i()->search_elastic_analyzer;
|
||||
$settings = array(
|
||||
'max_result_window' => \IPS\Settings::i()->search_index_maxresults
|
||||
'max_result_window' => Settings::i()->search_index_maxresults
|
||||
);
|
||||
if ( $analyzer === 'custom' )
|
||||
{
|
||||
$settings['analysis'] = json_decode( '{' . \IPS\Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
|
||||
$settings['analysis'] = json_decode( '{' . Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
|
||||
$analyzer = key( $settings['analysis']['analyzer'] );
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url )->delete();
|
||||
Index::request( $this->url )->delete();
|
||||
|
||||
$definition = array(
|
||||
'settings' => $settings,
|
||||
@@ -117,38 +150,38 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
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 ) );
|
||||
$response = 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;
|
||||
throw new RuntimeException;
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
$response = \IPS\Content\Search\Elastic\Index::request( $this->url )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
|
||||
$response = Index::request( $this->url )->setHeaders( array( 'Content-Type' => 'application/json' ) )->put( json_encode( $definition ) );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get index data
|
||||
*
|
||||
* @param \IPS\Content\Searchable $object Item to add
|
||||
* @param Content $object Item to add
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function indexData( \IPS\Content\Searchable $object )
|
||||
public function indexData( Content $object ): array|NULL
|
||||
{
|
||||
if ( $indexData = parent::indexData( $object ) )
|
||||
{
|
||||
$indexData['index_permissions'] = explode( ',', $indexData['index_permissions'] );
|
||||
$indexData['index_is_last_comment'] = (bool) $indexData['index_is_last_comment'];
|
||||
|
||||
if ( $object instanceof \IPS\Content\Item )
|
||||
if ( $object instanceof Item )
|
||||
{
|
||||
$indexData = array_merge( $indexData, $this->metaData( $object ) );
|
||||
}
|
||||
@@ -166,10 +199,10 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* Index an item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $object Item to add
|
||||
* @param Content $object Item to add
|
||||
* @return void
|
||||
*/
|
||||
public function index( \IPS\Content\Searchable $object )
|
||||
public function index( Content $object ): void
|
||||
{
|
||||
if ( $indexData = $this->indexData( $object ) )
|
||||
{
|
||||
@@ -190,16 +223,16 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
try
|
||||
{
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $object ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get()->decodeJson();
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $object ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get()->decodeJson();
|
||||
if ( $r['found'] )
|
||||
{
|
||||
$existingData = $r['_source'];
|
||||
$existingIndexId = $r['_id'];
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
catch( Exception ) { }
|
||||
|
||||
if ( $object instanceof \IPS\Content\Comment and $existingIndexId and $existingData['index_is_last_comment'] and $indexData['index_item_id'] and $indexData['index_hidden'] !== 0 )
|
||||
if ( $object instanceof 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 )
|
||||
{
|
||||
/* 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'] = false;
|
||||
@@ -213,7 +246,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
}
|
||||
|
||||
/* Insert into index */
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $object ) ), \IPS\LONG_REQUEST_TIMEOUT )
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $object ) ), LONG_REQUEST_TIMEOUT )
|
||||
->setHeaders( array( 'Content-Type' => 'application/json' ) )
|
||||
->put( json_encode( $indexData ) );
|
||||
|
||||
@@ -228,24 +261,24 @@ class _Index extends \IPS\Content\Search\Index
|
||||
}
|
||||
|
||||
/* Views / Comments / Reviews */
|
||||
if ( $object instanceof \IPS\Content\Item )
|
||||
if ( $object instanceof Item )
|
||||
{
|
||||
$item = $object;
|
||||
}
|
||||
elseif ( $object instanceof \IPS\Content\Comment )
|
||||
elseif ( $object instanceof Comment )
|
||||
{
|
||||
$item = $object->item();
|
||||
}
|
||||
|
||||
$this->rebuildMetaData( $item );
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
catch ( \IPS\Content\Search\Elastic\Exception $e )
|
||||
catch ( ElasticException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch_response_error' );
|
||||
Log::log( $e, 'elasticsearch_response_error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,16 +289,16 @@ class _Index extends \IPS\Content\Search\Index
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearTasks()
|
||||
public function clearTasks(): void
|
||||
{
|
||||
try
|
||||
{
|
||||
/* This request *intentionally* goes to _tasks and not (ourpath)/_tasks */
|
||||
$response = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( '/_tasks' ), \IPS\LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get();
|
||||
$response = Index::request( $this->url->setPath( '/_tasks' ), LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get();
|
||||
|
||||
if( $error = $this->getResponseError( $response ) )
|
||||
{
|
||||
throw new \IPS\Content\Search\Elastic\Exception( $error['type'] . ' ' . $error['type'] );
|
||||
throw new ElasticException( $error['type'] . ' ' . $error['type'] );
|
||||
}
|
||||
|
||||
$response = $response->decodeJson();
|
||||
@@ -286,45 +319,53 @@ class _Index extends \IPS\Content\Search\Index
|
||||
continue;
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( '/.tasks/task' . $taskId ), \IPS\LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->delete();
|
||||
Index::request( $this->url->setPath( '/.tasks/task' . $taskId ), LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Content\Search\Elastic\Exception $e )
|
||||
catch ( ElasticException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch_response_error' );
|
||||
Log::log( $e, 'elasticsearch_response_error' );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment / review counts for an item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $item The content item
|
||||
* @return void
|
||||
* @param Item $item The content item
|
||||
* @return array|null
|
||||
*/
|
||||
protected function metaData( $item )
|
||||
protected function metaData( Item $item ): ?array
|
||||
{
|
||||
$databaseColumnId = $item::$databaseColumnId;
|
||||
if( !Content\Search\SearchContent::isSearchable( $item ) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$databaseColumnId = $item::$databaseColumnId;
|
||||
|
||||
/* @var array $databaseColumnMap */
|
||||
$participants = array( $item->mapped('author') );
|
||||
if ( isset( $item::$commentClass ) )
|
||||
{
|
||||
/* @var Comment $commentClass */
|
||||
$commentClass = $item::$commentClass;
|
||||
$participants += iterator_to_array( \IPS\Db::i()->select( 'DISTINCT ' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'], $commentClass::$databaseTable, array( $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=?', $item->$databaseColumnId ) ) );
|
||||
$participants += iterator_to_array( Db::i()->select( 'DISTINCT ' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'], $commentClass::$databaseTable, array( $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=?', $item->$databaseColumnId ) ) );
|
||||
}
|
||||
if ( isset( $item::$reviewClass ) )
|
||||
{
|
||||
/* @var Content\Review $reviewClass */
|
||||
$reviewClass = $item::$reviewClass;
|
||||
$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 += iterator_to_array( 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() )
|
||||
if ( IPS::classUsesTrait( $item, 'IPS\Content\Solvable' ) and $item->isSolved() )
|
||||
{
|
||||
$isSolved = 1;
|
||||
}
|
||||
@@ -342,13 +383,13 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* Rebuild the comment / review counts for an item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $item The content item
|
||||
* @param Item $item The content item
|
||||
* @return void
|
||||
*/
|
||||
protected function rebuildMetaData( $item )
|
||||
protected function rebuildMetaData( Item $item ): void
|
||||
{
|
||||
$databaseColumnId = $item::$databaseColumnId;
|
||||
$class = \get_class( $item );
|
||||
$class = get_class( $item );
|
||||
$classes = array( $class );
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
@@ -365,24 +406,22 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$params = array();
|
||||
foreach ( $this->metaData( $item ) as $k => $v )
|
||||
{
|
||||
if ( \is_array( $v ) )
|
||||
$updates[] = "ctx._source.{$k} = params.param_{$k};";
|
||||
if ( is_array( $v ) )
|
||||
{
|
||||
$updates[] = "ctx._source.{$k} = params.param_{$k};";
|
||||
$params[ 'param_' . $k ] = ( $k !== 'index_tags' ? array_map( 'intval', $v ) : $v );
|
||||
}
|
||||
elseif ( \is_null( $v ) )
|
||||
elseif ( is_null( $v ) )
|
||||
{
|
||||
$updates[] = "ctx._source.{$k} = params.param_{$k};";
|
||||
$params['param_' . $k ] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$updates[] = "ctx._source.{$k} = params.param_{$k};";
|
||||
$params['param_' . $k ] = \intval( $v );
|
||||
$params['param_' . $k ] = intval( $v );
|
||||
}
|
||||
}
|
||||
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => \IPS\Settings::i()->search_index_maxresults ) ), \IPS\LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => Settings::i()->search_index_maxresults ) ), LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => implode( ' ', $updates ),
|
||||
'lang' => 'painless',
|
||||
@@ -406,44 +445,45 @@ class _Index extends \IPS\Content\Search\Index
|
||||
)
|
||||
) ) );
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the search ID for an item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $object Item to add
|
||||
* @return string
|
||||
* @param Content $object Item to add
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIndexId( \IPS\Content\Searchable $object ): string
|
||||
public function getIndexId( Content $object ): mixed
|
||||
{
|
||||
$databaseColumnId = $object::$databaseColumnId;
|
||||
return \strtolower( str_replace( '\\', '_', \substr( \get_class( $object ), 4 ) ) ) . '-' . $object->$databaseColumnId;
|
||||
return strtolower( str_replace( '\\', '_', substr( get_class( $object ), 4 ) ) ) . '-' . $object->$databaseColumnId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove item
|
||||
*
|
||||
* @param \IPS\Content\Searchable $object Item to remove
|
||||
* @return void
|
||||
* @param Content $object Item to remove
|
||||
* @return string
|
||||
*/
|
||||
public function removeFromSearchIndex( \IPS\Content\Searchable $object )
|
||||
public function removeFromSearchIndex( Content $object ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$class = \get_class( $object );
|
||||
$class = get_class( $object );
|
||||
$idColumn = $class::$databaseColumnId;
|
||||
|
||||
$this->directIndexRemoval( $class, $object->$idColumn );
|
||||
|
||||
if ( !( $object instanceof \IPS\Content\Item ) )
|
||||
if ( !( $object instanceof Item ) )
|
||||
{
|
||||
$this->rebuildMetaData( $object->item() );
|
||||
|
||||
$itemClass = \get_class( $object->item() );
|
||||
/* @var Item $itemClass */
|
||||
$itemClass = get_class( $object->item() );
|
||||
$itemIdColumn = $itemClass::$databaseColumnId;
|
||||
|
||||
$classes = array( $itemClass );
|
||||
@@ -456,12 +496,12 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$classes[] = $itemClass::$reviewClass;
|
||||
}
|
||||
|
||||
$this->resetLastComment( $classes, $object->item()->$itemIdColumn, $object->$idColumn, $this->getFirstCommentId( $object ) );
|
||||
$this->resetLastComment( $classes, $object->item()->$itemIdColumn, $object->$idColumn, null, $this->getFirstCommentId( $object ) );
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,19 +512,19 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param int $id ID
|
||||
* @return void
|
||||
*/
|
||||
public function directIndexRemoval( $class, $id )
|
||||
public function directIndexRemoval( string $class, int $id ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$indexId = \strtolower( str_replace( '\\', '_', \substr( $class, 4 ) ) ) . '-' . $id;
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/' . $indexId ) )->delete();
|
||||
$indexId = strtolower( str_replace( '\\', '_', substr( $class, 4 ) ) ) . '-' . $id;
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/' . $indexId ) )->delete();
|
||||
|
||||
if ( is_subclass_of( $class, 'IPS\Content\Item' ) )
|
||||
{
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
$commentClass = $class::$commentClass;
|
||||
$response = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
$response = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'query' => array(
|
||||
'bool' => array(
|
||||
'must' => array(
|
||||
@@ -507,7 +547,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
{
|
||||
$reviewClass = $class::$reviewClass;
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'query' => array(
|
||||
'bool' => array(
|
||||
'must' => array(
|
||||
@@ -529,9 +569,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,7 +583,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param int|NULL $authorId The author ID to delete, or NULL
|
||||
* @return void
|
||||
*/
|
||||
public function removeClassFromSearchIndex( $class, $containerId=NULL, $authorId=NULL )
|
||||
public function removeClassFromSearchIndex( string $class, int|null $containerId=null, int|null $authorId=null ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -579,13 +619,13 @@ class _Index extends \IPS\Content\Search\Index
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'query' => $query
|
||||
) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'query' => array(
|
||||
'term' => array(
|
||||
'index_class' => $class
|
||||
@@ -594,9 +634,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
) ) );
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +655,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param bool $addAuthorToPermissions If true, the index_author_id will be added to $newPermissions - used when changing the permissions for a node which allows access only to author's items
|
||||
* @return void
|
||||
*/
|
||||
public function massUpdate( $class, $containerId = NULL, $itemId = NULL, $newPermissions = NULL, $newHiddenStatus = NULL, $newContainer = NULL, $authorId = NULL, $newItemId = NULL, $newItemAuthorId = NULL, $addAuthorToPermissions = FALSE )
|
||||
public function massUpdate( string $class, int|null $containerId = null, int|null $itemId = null, string|null $newPermissions = null, int|null $newHiddenStatus = null, int|null $newContainer = null, int|null $authorId = null, int|null $newItemId = null, int|null $newItemAuthorId = null, bool $addAuthorToPermissions = FALSE ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -660,16 +700,17 @@ class _Index extends \IPS\Content\Search\Index
|
||||
if ( $newContainer )
|
||||
{
|
||||
$updates[] = "ctx._source.index_container_id = params.params_indexcontainer;";
|
||||
$params['params_indexcontainer'] = \intval( $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() )
|
||||
$params['params_indexcontainer'] = $newContainer;
|
||||
|
||||
/* @var Item $itemClass */
|
||||
if ( $itemClass = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) ? $class : $class::$itemClass ) and $containerClass = $itemClass::$containerNodeClass and IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) and $clubIdColumn = $containerClass::clubIdColumn() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$updates[] = "ctx._source.index_club_id = params.params_indexclub;";
|
||||
$params['params_indexclub'] = \intval( $containerClass::load( $newContainer )->$clubIdColumn );
|
||||
$params['params_indexclub'] = intval( $containerClass::load( $newContainer )->$clubIdColumn );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$updates[] = "ctx._source.index_club_id = params.params_indexclub;";
|
||||
$params['params_indexclub'] = null;
|
||||
@@ -679,17 +720,17 @@ class _Index extends \IPS\Content\Search\Index
|
||||
if ( $newItemId )
|
||||
{
|
||||
$updates[] = "ctx._source.index_item_id = params.params_indexitem;";
|
||||
$params['params_indexitem'] = \intval( $newItemId );
|
||||
$params['params_indexitem'] = $newItemId;
|
||||
}
|
||||
if ( $newItemAuthorId )
|
||||
{
|
||||
$updates[] = "ctx._source.index_item_author = params.params_indexauthor;";
|
||||
$params['params_indexauthor'] = \intval( $newItemAuthorId );
|
||||
$params['params_indexauthor'] = $newItemAuthorId;
|
||||
}
|
||||
|
||||
if ( \count( $updates ) )
|
||||
if ( count( $updates ) )
|
||||
{
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => \IPS\Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => implode( ' ', $updates ),
|
||||
'lang' => 'painless',
|
||||
@@ -710,7 +751,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
)
|
||||
);
|
||||
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => \IPS\Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => "ctx._source.index_permissions.add( 'm' + ctx._source.index_author );",
|
||||
'lang' => 'painless'
|
||||
@@ -740,11 +781,11 @@ class _Index extends \IPS\Content\Search\Index
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => \IPS\Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false', 'scroll_size' => Settings::i()->search_index_maxresults ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => "ctx._source.index_hidden = params.newHiddenStatus;",
|
||||
'lang' => 'painless',
|
||||
'params' => array( 'newHiddenStatus' => \intval( $newHiddenStatus ) )
|
||||
'params' => array( 'newHiddenStatus' => $newHiddenStatus )
|
||||
),
|
||||
'query' => array(
|
||||
'bool' => $conditions
|
||||
@@ -752,9 +793,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
) ) );
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,15 +805,15 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param array $conditions Conditions
|
||||
* @return array
|
||||
*/
|
||||
public static function convertConditionsToQuery( $conditions )
|
||||
public static function convertConditionsToQuery( array $conditions ): array
|
||||
{
|
||||
if ( \count( $conditions ) == 1 )
|
||||
if ( count( $conditions ) == 1 )
|
||||
{
|
||||
return $conditions[0];
|
||||
}
|
||||
elseif ( \count( $conditions ) == 0 )
|
||||
elseif ( count( $conditions ) == 0 )
|
||||
{
|
||||
return array( 'match_all' => new \StdClass );
|
||||
return array( 'match_all' => new StdClass );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -788,17 +829,16 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* Update data for the first and last comment after a merge
|
||||
* Sets index_is_last_comment on the last comment, and, if this is an item where the first comment is indexed rather than the item, sets index_title and index_tags on the first comment
|
||||
*
|
||||
* @param \IPS\Content\Item $item The item
|
||||
* @param Item $item The item
|
||||
* @return void
|
||||
*/
|
||||
public function rebuildAfterMerge( \IPS\Content\Item $item )
|
||||
public function rebuildAfterMerge( Item $item ): void
|
||||
{
|
||||
if ( $item::$commentClass )
|
||||
{
|
||||
$firstComment = $item->comments( 1, 0, 'date', 'asc', NULL, FALSE, NULL, NULL, TRUE, FALSE, FALSE );
|
||||
$lastComment = $item->comments( 1, 0, 'date', 'desc', NULL, FALSE, NULL, NULL, TRUE, FALSE, FALSE );
|
||||
|
||||
$idColumn = $item::$databaseColumnId;
|
||||
$update = array( 'index_is_last_comment' => false );
|
||||
if ( $item::$firstCommentRequired )
|
||||
{
|
||||
@@ -807,7 +847,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $item ) . '/_update' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/' . $this->getIndexId( $item ) . '/_update' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'doc' => $update
|
||||
) ) );
|
||||
|
||||
@@ -820,9 +860,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$this->index( $lastComment );
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -830,16 +870,16 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* Prune search index
|
||||
*
|
||||
* @param \IPS\DateTime|NULL $cutoff The date to delete index records from, or NULL to delete all
|
||||
* @param DateTime|NULL $cutoff The date to delete index records from, or NULL to delete all
|
||||
* @return void
|
||||
*/
|
||||
public function prune( \IPS\DateTime $cutoff = NULL )
|
||||
public function prune( DateTime|null $cutoff = NULL ): void
|
||||
{
|
||||
if ( $cutoff )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_delete_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'query' => array(
|
||||
'range' => array(
|
||||
'index_date_updated' => array(
|
||||
@@ -849,9 +889,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
)
|
||||
) ) );
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( RequestException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -859,22 +899,22 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$this->init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the last comment flag in any given class/index_item_id
|
||||
*
|
||||
* @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
|
||||
* @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, $firstCommentId = NULL )
|
||||
public function resetLastComment( array $classes, int|null $indexItemId, int|null $ignoreId = null, int|null $firstCommentId = null ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Remove the flag */
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => "ctx._source.index_is_last_comment = false;",
|
||||
'lang' => 'painless'
|
||||
@@ -906,7 +946,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$itemClass = NULL;
|
||||
foreach ( $classes as $class )
|
||||
{
|
||||
if ( \in_array( 'IPS\Content\Item', class_parents( $class ) ) )
|
||||
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
|
||||
{
|
||||
$itemClass = $class;
|
||||
break;
|
||||
@@ -931,10 +971,10 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$where = array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentIdColumn . '<>?', $ignoreId );
|
||||
}
|
||||
|
||||
if ( $lastComment = $item->comments( 1, 0, 'date', 'desc', NULL, FALSE, NULL, $where ) AND $lastComment instanceof \IPS\Content\Searchable )
|
||||
if ( $lastComment = $item->comments( 1, 0, 'date', 'desc', NULL, FALSE, NULL, $where ) AND Content\Search\SearchContent::isSearchable( $lastComment ) )
|
||||
{
|
||||
/* Set that it is the latest comment */
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_update/' . $this->getIndexId( $lastComment ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_update/' . $this->getIndexId( $lastComment ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'doc' => array(
|
||||
'index_is_last_comment' => true
|
||||
)
|
||||
@@ -942,13 +982,13 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
/* And set the updated time on the main item (done as _update_by_query because it might not exist if the first comment is required) */
|
||||
$indexDataForLastComment = $this->indexData( $lastComment );
|
||||
$r = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
$r = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_update_by_query' )->setQueryString( array( 'conflicts' => 'proceed', 'wait_for_completion' => 'false' ) ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->post( json_encode( array(
|
||||
'script' => array(
|
||||
'source' => "ctx._source.index_date_updated = params.dateUpdated; ctx._source.index_date_commented = params.dateCommented;",
|
||||
'lang' => 'painless',
|
||||
'params' => array(
|
||||
'dateUpdated' => \intval( $indexDataForLastComment['index_date_updated'] ),
|
||||
'dateCommented' => \intval( $indexDataForLastComment['index_date_commented'] )
|
||||
'dateUpdated' => intval( $indexDataForLastComment['index_date_updated'] ),
|
||||
'dateCommented' => intval( $indexDataForLastComment['index_date_commented'] )
|
||||
)
|
||||
),
|
||||
'query' => array(
|
||||
@@ -975,12 +1015,12 @@ class _Index extends \IPS\Content\Search\Index
|
||||
) ) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException ) {}
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,10 +1028,10 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* Given a list of item index IDs, return the ones that a given member has participated in
|
||||
*
|
||||
* @param array $itemIndexIds Item index IDs
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return array
|
||||
*/
|
||||
public function iPostedIn( array $itemIndexIds, \IPS\Member $member )
|
||||
public function iPostedIn( array $itemIndexIds, Member $member ): array
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1014,7 +1054,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
);
|
||||
|
||||
/* Get the count */
|
||||
$count = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
$count = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
'size' => 0,
|
||||
'query' => $query
|
||||
) ) )->decodeJson();
|
||||
@@ -1025,7 +1065,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
}
|
||||
|
||||
/* Now get the unique item ids */
|
||||
$results = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
$results = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
'aggs' => array(
|
||||
'itemIds' => array(
|
||||
'terms' => array(
|
||||
@@ -1037,9 +1077,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
'query' => $query
|
||||
) ) )->decodeJson();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -1059,15 +1099,15 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* Given a list of "index_class_type_id_hash"s, return the ones that a given member has permission to view
|
||||
*
|
||||
* @param array $hashes Item index hashes
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @param int|NULL $limit Number of results to return
|
||||
* @return array
|
||||
*/
|
||||
public function hashesWithPermission( array $hashes, \IPS\Member $member, $limit = NULL )
|
||||
public function hashesWithPermission( array $hashes, Member $member, int|null $limit = null ): array
|
||||
{
|
||||
try
|
||||
{
|
||||
$results = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
$results = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
'query' => array(
|
||||
'bool' => array(
|
||||
'filter' => array(
|
||||
@@ -1092,9 +1132,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
'size' => $limit ?: 10 // If we define a limit, use that, otherwise default to 10 which is ElasticSearch's default
|
||||
) ) )->decodeJson();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -1112,11 +1152,11 @@ class _Index extends \IPS\Content\Search\Index
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function firstIndexDate()
|
||||
public function firstIndexDate(): int|NULL
|
||||
{
|
||||
try
|
||||
{
|
||||
$results = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
$results = Index::request( $this->url->setPath( $this->url->data[ Url::COMPONENT_PATH ] . '/_doc/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
'size' => 1,
|
||||
'sort' => array( array( 'index_date_updated' => 'asc' ) )
|
||||
) ) )->decodeJson();
|
||||
@@ -1128,9 +1168,9 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
return NULL;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'elasticsearch' );
|
||||
Log::log( $e, 'elasticsearch' );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1141,18 +1181,18 @@ class _Index extends \IPS\Content\Search\Index
|
||||
* @param array $terms Terms
|
||||
* @return array
|
||||
*/
|
||||
public function stemmedTerms( $terms )
|
||||
public function stemmedTerms( array $terms ): array
|
||||
{
|
||||
$analyzer = \IPS\Settings::i()->search_elastic_analyzer;
|
||||
$analyzer = Settings::i()->search_elastic_analyzer;
|
||||
if ( $analyzer === 'custom' )
|
||||
{
|
||||
$analysisSettings = json_decode( '{' . \IPS\Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
|
||||
$analysisSettings = json_decode( '{' . Settings::i()->search_elastic_custom_analyzer . '}', TRUE );
|
||||
$analyzer = key( $analysisSettings['analyzer'] );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$results = \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( '/_analyze' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
$results = Index::request( $this->url->setPath( '/_analyze' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( json_encode( array(
|
||||
'analyzer' => $analyzer,
|
||||
'text' => implode( ' ', $terms )
|
||||
) ) )->decodeJson();
|
||||
@@ -1169,7 +1209,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
|
||||
return $terms;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception )
|
||||
{
|
||||
return $terms;
|
||||
}
|
||||
@@ -1180,7 +1220,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportViewFiltering()
|
||||
public function supportViewFiltering(): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1188,15 +1228,15 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* Wrapper to account for log in where needed
|
||||
*
|
||||
* @param $url
|
||||
* @param null $timeout
|
||||
* @return \IPS\Http\Request\Curl|Socket
|
||||
* @param Url $url
|
||||
* @param int|null $timeout
|
||||
* @return Curl
|
||||
*/
|
||||
public static function request( $url, $timeout=NULL )
|
||||
public static function request( Url $url, int|null $timeout=NULL ) : Curl
|
||||
{
|
||||
if ( \IPS\ELASTICSEARCH_USER or \IPS\ELASTICSEARCH_PASSWORD )
|
||||
if ( ELASTICSEARCH_USER or ELASTICSEARCH_PASSWORD )
|
||||
{
|
||||
return $url->request( $timeout )->login( \IPS\ELASTICSEARCH_USER, \IPS\ELASTICSEARCH_PASSWORD );
|
||||
return $url->request( $timeout )->login( ELASTICSEARCH_USER, ELASTICSEARCH_PASSWORD );
|
||||
}
|
||||
|
||||
return $url->request( $timeout );
|
||||
@@ -1205,10 +1245,10 @@ class _Index extends \IPS\Content\Search\Index
|
||||
/**
|
||||
* Check response to see if an error was produced
|
||||
*
|
||||
* @param \IPS\Http\Response $response Response object
|
||||
* @return string|null
|
||||
* @param Response $response Response object
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getResponseError( \IPS\Http\Response $response )
|
||||
protected function getResponseError( Response $response ): array|NULL
|
||||
{
|
||||
/* Log any errors */
|
||||
if( $response->httpResponseCode != 200 AND $content = $response->decodeJson() AND isset( $content['error'] ) )
|
||||
|
||||
Reference in new issue
Block a user