Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
CirrusNearCoordBoostFeature
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
5 / 5
7
100.00% covered (success)
100.00%
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%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 parseValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBoostFunctionBuilder
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 buildBoostFunction
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace GeoData\Search;
4
5use CirrusSearch\Parser\AST\KeywordFeatureNode;
6use CirrusSearch\Query\BoostFunctionFeature;
7use CirrusSearch\Query\Builder\QueryBuildingContext;
8use CirrusSearch\Query\SimpleKeywordFeature;
9use CirrusSearch\Search\Rescore\BoostFunctionBuilder;
10use CirrusSearch\Search\SearchContext;
11use CirrusSearch\SearchConfig;
12use CirrusSearch\WarningCollector;
13use GeoData\Coord;
14
15/**
16 * Applies geo boosting to the query by providing coordinates.
17 *
18 * it increases the score of results within the geographic area. All values can be prefixed
19 * with a radius in m or km to apply. If not specified this defaults to 5km.
20 *
21 * Examples:
22 *  boost-nearcoord:-12.345,87.654
23 *  boost-nearcoord:77km,34.567,76.543
24 */
25class CirrusNearCoordBoostFeature extends SimpleKeywordFeature implements BoostFunctionFeature {
26    use CirrusGeoFeature;
27
28    /** @inheritDoc */
29    protected function getKeywords() {
30        return [ 'boost-nearcoord' ];
31    }
32
33    /** @inheritDoc */
34    protected function doApply( SearchContext $context, $key, $value, $quotedValue, $negated ) {
35        [ $coord, $radius ] = $this->parseValue( $key, $value, $quotedValue, '', '', $context );
36        if ( $coord !== null ) {
37            $context->addCustomRescoreComponent(
38                $this->buildBoostFunction( $context->getConfig(), $coord, $radius )
39            );
40        }
41
42        return [ null, false ];
43    }
44
45    /**
46     * @param string $key
47     * @param string $value
48     * @param string $quotedValue
49     * @param string $valueDelimiter
50     * @param string $suffix
51     * @param WarningCollector $warningCollector
52     * @return array{array{lat:float,lon:float,globe:string}|null,int}
53     */
54    public function parseValue(
55        $key,
56        $value,
57        $quotedValue,
58        $valueDelimiter,
59        $suffix,
60        WarningCollector $warningCollector
61    ) {
62        return $this->parseGeoNearby( $warningCollector, $key, $value );
63    }
64
65    /**
66     * @param KeywordFeatureNode $node
67     * @param QueryBuildingContext $context
68     * @return BoostFunctionBuilder|null
69     */
70    public function getBoostFunctionBuilder(
71        KeywordFeatureNode $node,
72        QueryBuildingContext $context
73    ) {
74        [ $coord, $radius ] = $node->getParsedValue();
75        if ( $coord !== null ) {
76            return $this->buildBoostFunction( $context->getSearchConfig(), $coord, $radius );
77        }
78        return null;
79    }
80
81    /**
82     * @param SearchConfig $config
83     * @param array{lat:float,lon:float,globe:string} $coord
84     * @param int $radius
85     * @return GeoRadiusFunctionScoreBuilder
86     */
87    private function buildBoostFunction( SearchConfig $config, array $coord, $radius ) {
88        $coordObject = new Coord( $coord['lat'], $coord['lon'], $coord['globe'] );
89        return new GeoRadiusFunctionScoreBuilder( $config,
90            1, $coordObject, $radius );
91    }
92}