Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
DefaultSearchQueryDispatchService
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
8
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
 bestRoute
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2
3namespace CirrusSearch\Dispatch;
4
5use CirrusSearch\Profile\SearchProfileException;
6use CirrusSearch\Search\SearchQuery;
7use Wikimedia\Assert\Assert;
8
9class DefaultSearchQueryDispatchService implements SearchQueryDispatchService {
10    /**
11     * List of routes per search engine entry point
12     * @var SearchQueryRoute[][] indexed by search engine entry point
13     */
14    private $routes;
15
16    /**
17     * @param SearchQueryRoute[][] $routes
18     */
19    public function __construct( array $routes ) {
20        $this->routes = $routes;
21    }
22
23    public function bestRoute( SearchQuery $query ): SearchQueryRoute {
24        Assert::parameter( isset( $this->routes[$query->getSearchEngineEntryPoint()] ), 'query',
25            "Unsupported search engine entry point {$query->getSearchEngineEntryPoint()}" );
26
27        $routes = $this->routes[$query->getSearchEngineEntryPoint()];
28
29        $bestScore = 0.0;
30
31        /** @var SearchQueryRoute $best */
32        $best = null;
33        foreach ( $routes as $route ) {
34            $score = $route->score( $query );
35            Assert::postcondition( $score >= 0 && $score <= 1.0, "SearchQueryRoute scores must be between 0.0 and 1.0" );
36            if ( $score === 0.0 ) {
37                continue;
38            }
39            if ( $score === 1.0 ) {
40                if ( $bestScore === 1.0 ) {
41                    throw new SearchProfileException( "Two competing contexts " .
42                        // @phan-suppress-next-line PhanNonClassMethodCall $best always set when reaching this line
43                        "{$route->getProfileContext()} and {$best->getProfileContext()} " .
44                        " produced the max score" );
45                }
46                $bestScore = $score;
47                $best = $route;
48            } elseif ( $score > $bestScore ) {
49                $best = $route;
50                $bestScore = $score;
51            }
52        }
53        Assert::postcondition( $best !== null,
54            "No route to backend, make sure a default SearchQueryRoute is added for {$query->getSearchEngineEntryPoint()}" );
55        return $best;
56    }
57}