mirror of
https://github.com/silverstripe/silverstripe-fulltextsearch
synced 2024-10-22 14:05:29 +02:00
Merge pull request #202 from creative-commoners/pulls/3.0/irrelevant-variant-isolation
NEW Add SearchVariant::withCommon to run callbacks on relevant variants rather than all
This commit is contained in:
commit
48f3df725a
@ -2,11 +2,10 @@
|
||||
|
||||
namespace SilverStripe\FullTextSearch\Search\Variants;
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use ReflectionClass;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Config\Configurable;
|
||||
use SilverStripe\FullTextSearch\Utils\CombinationsArrayIterator;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* A Search Variant handles decorators and other situations where the items to reindex or search through are modified
|
||||
@ -93,6 +92,7 @@ abstract class SearchVariant
|
||||
public static function variants($class = null, $includeSubclasses = true)
|
||||
{
|
||||
if (!$class) {
|
||||
// Build up and cache a list of all search variants (subclasses of SearchVariant)
|
||||
if (self::$variants === null) {
|
||||
$classes = ClassInfo::subclassesFor(static::class);
|
||||
|
||||
@ -166,6 +166,42 @@ abstract class SearchVariant
|
||||
return self::$call_instances[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link SearchVariant::with}, except will only use variants that apply to at least one of the classes
|
||||
* in the input array, where {@link SearchVariant::with} will run the query on the specific class you give it.
|
||||
*
|
||||
* @param string[] $classes
|
||||
* @return SearchVariant_Caller
|
||||
*/
|
||||
public static function withCommon(array $classes = [])
|
||||
{
|
||||
// Allow caching
|
||||
$cacheKey = sha1(serialize($classes));
|
||||
if (isset(self::$call_instances[$cacheKey])) {
|
||||
return self::$call_instances[$cacheKey];
|
||||
}
|
||||
|
||||
// Construct new array of variants applicable to at least one class in the list
|
||||
$commonVariants = [];
|
||||
foreach ($classes as $class => $options) {
|
||||
// Extract relevant class options
|
||||
$includeSubclasses = isset($options['include_children']) ? $options['include_children'] : true;
|
||||
|
||||
// Get the variants for the current class
|
||||
$variantsForClass = self::variants($class, $includeSubclasses);
|
||||
|
||||
// Merge the variants applicable to the current class into the list of common variants, using
|
||||
// the variant instance to replace any previous versions for the same class name (should be singleton
|
||||
// anyway).
|
||||
$commonVariants = array_replace($commonVariants, $variantsForClass);
|
||||
}
|
||||
|
||||
// Cache for future calls
|
||||
self::$call_instances[$cacheKey] = new SearchVariant_Caller($commonVariants);
|
||||
|
||||
return self::$call_instances[$cacheKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut to with when calling without passing in a class,
|
||||
*
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\FullTextSearch\Solr;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Core\Environment;
|
||||
use SilverStripe\FulltextSearch\Search\Indexes\SearchIndex;
|
||||
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant_Caller;
|
||||
use SilverStripe\FullTextSearch\Solr\Services\SolrService;
|
||||
use SilverStripe\FulltextSearch\Search\Queries\SearchQuery;
|
||||
use SilverStripe\FullTextSearch\Search\Queries\SearchQuery_Range;
|
||||
@ -710,12 +711,7 @@ abstract class SolrIndex extends SearchIndex
|
||||
public function search(SearchQuery $query, $offset = -1, $limit = -1, $params = array())
|
||||
{
|
||||
$service = $this->getService();
|
||||
|
||||
$searchClass = count($query->classes) == 1
|
||||
? $query->classes[0]['class']
|
||||
: null;
|
||||
SearchVariant::with($searchClass)
|
||||
->call('alterQuery', $query, $this);
|
||||
$this->applySearchVariants($query);
|
||||
|
||||
$q = array(); // Query
|
||||
$fq = array(); // Filter query
|
||||
@ -870,6 +866,21 @@ abstract class SolrIndex extends SearchIndex
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* With a common set of variants that are relevant to at least one class in the list (from either the query or
|
||||
* the current index), allow them to alter the query to add their variant column conditions.
|
||||
*
|
||||
* @param SearchQuery $query
|
||||
*/
|
||||
protected function applySearchVariants(SearchQuery $query)
|
||||
{
|
||||
$classes = count($query->classes) ? $query->classes : $this->getClasses();
|
||||
|
||||
/** @var SearchVariant_Caller $variantCaller */
|
||||
$variantCaller = SearchVariant::withCommon($classes);
|
||||
$variantCaller->call('alterQuery', $query, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solr requires namespaced classes to have double escaped backslashes
|
||||
*
|
||||
|
@ -172,7 +172,7 @@ class SolrIndexTest extends SapphireTest
|
||||
$this->equalTo([
|
||||
'qf' => SearchUpdaterTest_Container::class . '_Field1^1.5 '
|
||||
. SearchUpdaterTest_Container::class . '_Field2^2.1 _text',
|
||||
'fq' => '+(_versionedstage:"" (*:* -_versionedstage:[* TO *]))',
|
||||
'fq' => '',
|
||||
]),
|
||||
$this->anything()
|
||||
)->willReturn($this->getFakeRawSolrResponse());
|
||||
|
Loading…
Reference in New Issue
Block a user