Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
MoreLikeFeature
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
9 / 9
10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 greedy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 queryHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getKeywords
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFeatureName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCrossSearchStrategy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 doApply
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 expand
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace CirrusSearch\Query;
4
5use CirrusSearch\CirrusConfigNames;
6use CirrusSearch\CrossSearchStrategy;
7use CirrusSearch\Parser\AST\KeywordFeatureNode;
8use CirrusSearch\Search\SearchContext;
9use CirrusSearch\SearchConfig;
10use CirrusSearch\WarningCollector;
11use MediaWiki\Title\Title;
12
13/**
14 * Finds pages similar to another one.
15 * Greedy keyword kept for BC purposes, MoreLikeThisFeature should be preferred.
16 */
17class MoreLikeFeature extends SimpleKeywordFeature implements LegacyKeywordFeature {
18    use MoreLikeTrait;
19
20    private const MORE_LIKE_THIS = 'morelike';
21
22    /**
23     * @var SearchConfig
24     */
25    private $config;
26
27    public function __construct( SearchConfig $config ) {
28        $this->config = $config;
29    }
30
31    /**
32     * @return bool
33     */
34    public function greedy() {
35        return true;
36    }
37
38    /**
39     * morelike is only allowed at the beginning of the query
40     * @return bool
41     */
42    public function queryHeader() {
43        return true;
44    }
45
46    /** @inheritDoc */
47    protected function getKeywords() {
48        return [ self::MORE_LIKE_THIS ];
49    }
50
51    /**
52     * @param string $key
53     * @param string $valueDelimiter
54     * @return string
55     */
56    public function getFeatureName( $key, $valueDelimiter ) {
57        return "more_like";
58    }
59
60    /**
61     * @param KeywordFeatureNode $node
62     * @return CrossSearchStrategy
63     */
64    public function getCrossSearchStrategy( KeywordFeatureNode $node ) {
65        // We depend on the db to fetch the title
66        return CrossSearchStrategy::hostWikiOnlyStrategy();
67    }
68
69    /**
70     * @param SearchContext $context
71     * @param string $key
72     * @param string $value
73     * @param string $quotedValue
74     * @param bool $negated
75     * @return array
76     */
77    protected function doApply( SearchContext $context, $key, $value, $quotedValue, $negated ) {
78        $context->setCacheTtl( $this->config->get( CirrusConfigNames::MoreLikeThisTTL ) );
79        $titles = $this->doExpand( $key, $value, $context );
80        if ( $titles === [] ) {
81            $context->setResultsPossible( false );
82            return [ null, false ];
83        }
84        $query = $this->buildMoreLikeQuery( $titles );
85
86        // this erases the main query making it impossible to combine with
87        // other keywords/search query. MoreLikeThisFeature addresses this problem.
88        $context->setMainQuery( $query );
89
90        // highlight snippets are not great so it's worth running a match all query
91        // to save cpu cycles
92        $context->setHighlightQuery( new \Elastica\Query\MatchAll() );
93
94        return [ null, false ];
95    }
96
97    /**
98     * @param KeywordFeatureNode $node
99     * @param SearchConfig $config
100     * @param WarningCollector $warningCollector
101     * @return array|Title[]
102     */
103    public function expand( KeywordFeatureNode $node, SearchConfig $config, WarningCollector $warningCollector ) {
104        return $this->doExpand( $node->getKey(), $node->getValue(), $warningCollector );
105    }
106
107    public function getConfig(): SearchConfig {
108        return $this->config;
109    }
110}