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