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