Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
CirrusNearCoordFilterFeature
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
6 / 6
7
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
 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%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 parseValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 doGetFilterquery
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getFilterQuery
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace GeoData\Search;
4
5use CirrusSearch\Parser\AST\KeywordFeatureNode;
6use CirrusSearch\Query\Builder\QueryBuildingContext;
7use CirrusSearch\Query\FilterQueryFeature;
8use CirrusSearch\Query\SimpleKeywordFeature;
9use CirrusSearch\Search\SearchContext;
10use CirrusSearch\WarningCollector;
11use Elastica\Query\AbstractQuery;
12use GeoData\Coord;
13use MediaWiki\Config\Config;
14
15/**
16 * Applies geo filtering to the query by providing coordinates.
17 *
18 * Limits search results to a geographic area within the geographic area. All values
19 * can be prefixed with a radius in m or km to apply. If not specified this defaults
20 * to 5km.
21 *
22 * Examples:
23 *  nearcoord:1.2345,-5.4321
24 *  nearcoord:17km,54.321,-12.345
25 */
26class CirrusNearCoordFilterFeature extends SimpleKeywordFeature implements FilterQueryFeature {
27    use CirrusGeoFeature;
28
29    /**
30     * @var Config
31     */
32    private $config;
33
34    /**
35     * @param Config $config
36     */
37    public function __construct( Config $config ) {
38        $this->config = $config;
39    }
40
41    /**
42     * @return string[]
43     */
44    protected function getKeywords() {
45        return [ 'nearcoord' ];
46    }
47
48    /**
49     * @param SearchContext $context
50     * @param string $key The keyword
51     * @param string $value The value attached to the keyword with quotes stripped
52     * @param string $quotedValue The original value in the search string, including quotes if used
53     * @param bool $negated Is the search negated? Not used to generate the returned AbstractQuery,
54     *  that will be negated as necessary. Used for any other building/context necessary.
55     * @return array Two element array, first an AbstractQuery or null to apply to the
56     *  query. Second a boolean indicating if the quotedValue should be kept in the search
57     *  string.
58     */
59    protected function doApply( SearchContext $context, $key, $value, $quotedValue, $negated ) {
60        [ $coord, $radius ] = $this->parseValue( $key, $value, $quotedValue,
61            '', '', $context );
62        return [ $this->doGetFilterquery( $coord, $radius ), false ];
63    }
64
65    /**
66     * @param string $key
67     * @param string $value
68     * @param string $quotedValue
69     * @param string $valueDelimiter
70     * @param string $suffix
71     * @param WarningCollector $warningCollector
72     * @return array
73     */
74    public function parseValue(
75        $key,
76        $value,
77        $quotedValue,
78        $valueDelimiter,
79        $suffix,
80        WarningCollector $warningCollector
81    ) {
82        return $this->parseGeoNearby( $warningCollector, $this->config, $key, $value );
83    }
84
85    /**
86     * @param array|null $coord
87     * @param int $radius
88     * @return \Elastica\Query\AbstractQuery|null
89     */
90    protected function doGetFilterquery( $coord, $radius ) {
91        $filter = null;
92        if ( $coord !== null ) {
93            $coordObject = new Coord( $coord['lat'], $coord['lon'], $coord['globe'] );
94            $filter = CirrusNearTitleFilterFeature::createQuery( $coordObject, $radius );
95        }
96
97        return $filter;
98    }
99
100    /**
101     * @param KeywordFeatureNode $node
102     * @param QueryBuildingContext $context
103     * @return AbstractQuery|null
104     */
105    public function getFilterQuery( KeywordFeatureNode $node, QueryBuildingContext $context ) {
106        [ $coord, $radius ] = $node->getParsedValue();
107        return $this->doGetFilterquery( $coord, $radius );
108    }
109}