Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -69,7 +69,12 @@ class _Query extends \IPS\Content\Search\Query
|
||||
parent::__construct( $member );
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @var bool Stores whether or not any content type needs to be limited by the latest comment
|
||||
*/
|
||||
protected $lastCommentMustBeTrue = false;
|
||||
|
||||
/**
|
||||
* Filter by multiple content types
|
||||
*
|
||||
@@ -198,11 +203,14 @@ class _Query extends \IPS\Content\Search\Query
|
||||
/* Only last comment? */
|
||||
if ( $filter->onlyLastComment )
|
||||
{
|
||||
/* Set this for when the search JSON is built */
|
||||
$this->lastCommentMustBeTrue = true;
|
||||
|
||||
$conditions[] = array(
|
||||
'term' => array( 'index_is_last_comment' => true )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* Put it together */
|
||||
if( \count( $conditions ) )
|
||||
{
|
||||
@@ -215,7 +223,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
{
|
||||
$this->filters[] = array(
|
||||
'bool' => array(
|
||||
( $type ? 'should' : 'must_not' ) => array( $contentFilterConditions )
|
||||
( $type ? 'should' : 'must_not' ) => $contentFilterConditions
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -363,7 +371,79 @@ class _Query extends \IPS\Content\Search\Query
|
||||
/* Return for daisy chaining */
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stores the "more like this" Content object for search()
|
||||
* @param null
|
||||
*/
|
||||
protected $moreLikeThis = NULL;
|
||||
|
||||
/**
|
||||
* Filter by more like this
|
||||
* @param \IPS\Content\Searchable $object
|
||||
*/
|
||||
public function filterByMoreLikeThis( \IPS\Content\Searchable $object )
|
||||
{
|
||||
$index = new \IPS\Content\Search\Elastic\Index( $this->url );
|
||||
$this->moreLikeThis = $index->getIndexId( ( $object instanceof \IPS\Content\Item and $object::$firstCommentRequired ) ? $object->firstComment() : $object );
|
||||
|
||||
/* Some container types cannot be cached */
|
||||
$classes = [];
|
||||
$conditions = [];
|
||||
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', FALSE ) as $object )
|
||||
{
|
||||
$classes = array_merge( $object->classes, $classes );
|
||||
}
|
||||
|
||||
/* Some nodes have complex permissions, so avoid any permission issues by not selecting these */
|
||||
foreach( $classes as $itemClass )
|
||||
{
|
||||
if ( isset( $itemClass::$containerNodeClass ) )
|
||||
{
|
||||
$containerClass = $itemClass::$containerNodeClass;
|
||||
$blockIds = [];
|
||||
if ( $customNodes = $containerClass::customPermissionNodes() )
|
||||
{
|
||||
foreach ( $customNodes as $key => $ids )
|
||||
{
|
||||
if ( $key !== 'count' )
|
||||
{
|
||||
$blockIds = array_merge( $blockIds, $ids );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $blockIds ) )
|
||||
{
|
||||
$conditions[] = array(
|
||||
'bool' => array(
|
||||
'filter' => array(
|
||||
array(
|
||||
'terms' => array( 'index_container_class' => [ $containerClass ] )
|
||||
),
|
||||
array(
|
||||
'terms' => array( 'index_container_id' => $blockIds )
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( \count( $conditions ) )
|
||||
{
|
||||
foreach( $conditions as $condition )
|
||||
{
|
||||
$this->mustNot[] = $condition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only show non-hidden and approved items */
|
||||
$this->setHiddenFilter( static::HIDDEN_VISIBLE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by container class
|
||||
*
|
||||
@@ -558,9 +638,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
if ( $includeMembers and $followed = iterator_to_array( \IPS\Db::i()->select( 'follow_rel_id', 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_member_id=?', 'core', 'member', $this->member->member_id ), 'follow_rel_id asc' ) ) )
|
||||
{
|
||||
$conditions[] = array(
|
||||
array(
|
||||
'terms' => array( 'index_author' => $followed )
|
||||
)
|
||||
'terms' => array( 'index_author' => $followed )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -799,7 +877,35 @@ class _Query extends \IPS\Content\Search\Query
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter by solved
|
||||
*
|
||||
* @return \IPS\Content\Search\Query (for daisy chaining)
|
||||
*/
|
||||
public function filterBySolved()
|
||||
{
|
||||
$this->filters[] = array(
|
||||
'term' => array( 'index_item_solved' => 1 )
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by Unsolved
|
||||
*
|
||||
* @return \IPS\Content\Search\Query (for daisy chaining)
|
||||
*/
|
||||
public function filterByUnsolved()
|
||||
{
|
||||
$this->filters[] = array(
|
||||
'term' => array( 'index_item_solved' => 0 )
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by start date
|
||||
*
|
||||
@@ -922,7 +1028,35 @@ class _Query extends \IPS\Content\Search\Query
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Debug by itemId, used for debugging purposes only
|
||||
* @note No permission checks run, do not use in production
|
||||
* @param $itemId
|
||||
* @return void
|
||||
*/
|
||||
public function debugByItemId( $itemId )
|
||||
{
|
||||
$array = array(
|
||||
'query' => [
|
||||
'term' => [
|
||||
'index_item_id' => [
|
||||
'value' => \intval( $itemId )
|
||||
]
|
||||
]
|
||||
],
|
||||
'sort' => $this->sort ?: array(),
|
||||
'from' => 0,
|
||||
'size' => 50,
|
||||
);
|
||||
|
||||
$json = json_encode( $array, JSON_PARTIAL_OUTPUT_ON_ERROR );
|
||||
|
||||
return \IPS\Content\Search\Elastic\Index::request( $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_search' ) )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( $json )->decodeJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
@@ -1017,6 +1151,12 @@ class _Query extends \IPS\Content\Search\Query
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
/* If we're not searching with a term, then just show the title record, not comments */
|
||||
if ( $term === NULL and ! $this->lastCommentMustBeTrue )
|
||||
{
|
||||
$must[] = ['exists' => ['field' => 'index_title']];
|
||||
}
|
||||
}
|
||||
|
||||
/* Put that with the rest of the conditions */
|
||||
@@ -1050,7 +1190,25 @@ class _Query extends \IPS\Content\Search\Query
|
||||
$filters[] = array( 'term' => array( 'index_hidden' => $this->hiddenStatuses ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$searchUrl = $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_search' );
|
||||
|
||||
if ( $this->moreLikeThis )
|
||||
{
|
||||
$must[] = [
|
||||
'more_like_this' => [
|
||||
'fields' => [ 'index_title' ],
|
||||
'like' => [ '_index' => \IPS\Settings::i()->search_elastic_index, '_id' => $this->moreLikeThis ],
|
||||
'min_term_freq' => 1,
|
||||
'max_query_terms' => 12,
|
||||
'min_word_length' => 3,
|
||||
]
|
||||
];
|
||||
|
||||
/* Let's enforce a relatively short timeout to prevent slow ES server from dragging down topics */
|
||||
$searchUrl = $searchUrl->setQueryString( 'timeout', '3s' );
|
||||
}
|
||||
|
||||
/* Peform the search */
|
||||
try
|
||||
{
|
||||
@@ -1062,9 +1220,9 @@ class _Query extends \IPS\Content\Search\Query
|
||||
'filter' => $filters
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/* Add the time decay */
|
||||
if ( \IPS\Settings::i()->search_decay_factor and !$this->sort )
|
||||
if ( \IPS\Settings::i()->search_decay_factor and !$this->sort and ! $this->sort )
|
||||
{
|
||||
$query = array(
|
||||
'function_score' => array(
|
||||
@@ -1081,7 +1239,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
|
||||
/* Add the self boost */
|
||||
if ( \IPS\Settings::i()->search_elastic_self_boost and $this->member->member_id and !$this->sort )
|
||||
if ( \IPS\Settings::i()->search_elastic_self_boost and $this->member->member_id and !$this->sort and ! $this->moreLikeThis )
|
||||
{
|
||||
$query = array(
|
||||
'function_score' => array(
|
||||
@@ -1117,10 +1275,10 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
|
||||
/* Make the call! */
|
||||
$return = $this->url->setPath( $this->url->data[ \IPS\Http\Url::COMPONENT_PATH ] . '/_search' )->request()->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( $json )->decodeJson();
|
||||
$return = \IPS\Content\Search\Elastic\Index::request( $searchUrl )->setHeaders( array( 'Content-Type' => 'application/json' ) )->get( $json )->decodeJson();
|
||||
if ( isset( $return['error'] ) )
|
||||
{
|
||||
\IPS\Log::log( print_r( $return['error'], TRUE ), 'elasticsearch' );
|
||||
\IPS\Log::log( print_r( array_merge( $array, ['error' => $return['error'] ] ), TRUE ), 'elasticsearch' );
|
||||
return new \IPS\Content\Search\Results( array(), 0 );
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user