Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
PageIdFeature
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
5 / 5
9
100.00% covered (success)
100.00%
1 / 1
 getFilterQuery
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parseValue
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 doGetFilterQuery
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getKeywords
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 doApply
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace CirrusSearch\Query;
4
5use CirrusSearch\Parser\AST\KeywordFeatureNode;
6use CirrusSearch\Query\Builder\QueryBuildingContext;
7use CirrusSearch\Search\SearchContext;
8use CirrusSearch\SearchConfig;
9use CirrusSearch\WarningCollector;
10use Elastica\Query\AbstractQuery;
11use Elastica\Query\Ids;
12use MediaWiki\Message\Message;
13use Wikimedia\Message\ListType;
14
15/**
16 * Filter by a set of page IDs. This is useful for re-validating cached query results.
17 * Format: pageid:1|2|3
18 */
19class PageIdFeature extends SimpleKeywordFeature implements FilterQueryFeature {
20
21    /** Maximum number of IDs allowed. */
22    public const MAX_VALUES = 1000;
23
24    /** @inheritDoc */
25    public function getFilterQuery( KeywordFeatureNode $node, QueryBuildingContext $context ) {
26        return $this->doGetFilterQuery( $node->getParsedValue(), $context->getSearchConfig() );
27    }
28
29    /** @inheritDoc */
30    public function parseValue(
31        $key, $value, $quotedValue, $valueDelimiter, $suffix, WarningCollector $warningCollector
32    ) {
33        $values = explode( '|', $value );
34        $validValues = array_map( 'intval', array_values( array_filter( $values, 'ctype_digit' ) ) );
35        if ( count( $validValues ) < count( $values ) ) {
36            $invalidValues = array_values( array_diff( $values, $validValues ) );
37            $warningCollector->addWarning( 'cirrussearch-feature-pageid-invalid-id',
38                Message::listParam( $invalidValues, ListType::COMMA ), count( $invalidValues ) );
39        }
40
41        if ( count( $validValues ) > self::MAX_VALUES ) {
42            $warningCollector->addWarning(
43                'cirrussearch-feature-too-many-conditions',
44                $key,
45                self::MAX_VALUES
46            );
47            $validValues = array_slice( $validValues, 0, self::MAX_VALUES );
48        }
49
50        return [ 'pageids' => $validValues ];
51    }
52
53    /**
54     * @param array $parsedValue
55     * @param SearchConfig $searchConfig
56     * @return AbstractQuery|null
57     */
58    protected function doGetFilterQuery( array $parsedValue, SearchConfig $searchConfig ) {
59        if ( !$parsedValue['pageids'] ) {
60            return null;
61        }
62        $documentIds = array_map( [ $searchConfig, 'makeId' ], $parsedValue['pageids'] );
63        return new Ids( $documentIds );
64    }
65
66    /** @inheritDoc */
67    protected function getKeywords() {
68        return [ 'pageid' ];
69    }
70
71    /** @inheritDoc */
72    protected function doApply( SearchContext $context, $key, $value, $quotedValue, $negated ) {
73        $filter = $this->doGetFilterQuery(
74            $this->parseValue( $key, $value, $quotedValue, '', '', $context ),
75            $context->getConfig()
76        );
77        if ( !$filter ) {
78            $context->setResultsPossible( false );
79        }
80        return [ $filter, false ];
81    }
82
83}