Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
AlternativeIndices
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
5 / 5
14
100.00% covered (success)
100.00%
1 / 1
 build
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAlternativeIndices
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
7
 getAlternativeIndexById
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isValidAltIndexId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace CirrusSearch;
4
5use CirrusSearch\Search\AlternativeIndex;
6use MediaWiki\Config\ConfigException;
7use Wikimedia\Assert\Assert;
8
9class AlternativeIndices {
10    public const COMPLETION = "completion";
11    public const ALLOWED_TYPES = [ self::COMPLETION ];
12    private SearchConfig $config;
13
14    public static function build( SearchConfig $config ): AlternativeIndices {
15        return new AlternativeIndices( $config );
16    }
17
18    private function __construct( SearchConfig $config ) {
19        $this->config = $config;
20    }
21
22    /**
23     * @param string $type
24     * @return AlternativeIndex[]
25     */
26    public function getAlternativeIndices( string $type ): array {
27        Assert::parameter( in_array( $type, self::ALLOWED_TYPES, true ), '$type', "$type is not allowed" );
28        $indices = $this->config->get( CirrusConfigNames::AlternativeIndices )[$type] ?? [];
29        $altIndices = [];
30        foreach ( $indices as $index ) {
31            $id = $index["index_id"] ?? null;
32            $use = $index["use"] ?? false;
33            $overrides = $index["config_overrides"] ?? [];
34            if ( $id === null ) {
35                throw new ConfigException( "Missing [index_id] in CirrusSearchAlternativeIndices." );
36            }
37            if ( !self::isValidAltIndexId( $id ) ) {
38                throw new ConfigException( "Expected a positive integer for [index_id] but got [$id]." );
39            }
40            $id = (int)$id;
41            if ( array_key_exists( $id, $altIndices ) ) {
42                throw new ConfigException( "Duplicated alternative index [$id]." );
43            }
44            if ( !is_array( $overrides ) ) {
45                throw new ConfigException( "[config_overrides] for alternative index id [$id] must be an array." );
46            }
47            if ( !is_bool( $use ) ) {
48                throw new ConfigException( "[use] for alternative index id [$id] must be a boolean." );
49            }
50            $altIndices[$id] = new AlternativeIndex( $id, $type, $use, $this->config, $overrides );
51        }
52        return $altIndices;
53    }
54
55    public function getAlternativeIndexById( string $type, int $id ): ?AlternativeIndex {
56        return $this->getAlternativeIndices( $type )[$id] ?? null;
57    }
58
59    /**
60     * Check whether the provided $id is a valid alternative index id:
61     * - a positive integer represented as a string
62     * - a positive integer
63     * @param mixed $id
64     * @return bool true if $id is a valid alt index id and can safely be cast to int, false otherwise
65     */
66    public static function isValidAltIndexId( mixed $id ): bool {
67        if ( ( is_string( $id ) && ctype_digit( $id ) ) || is_int( $id ) ) {
68            return (int)$id >= 0;
69        }
70        return false;
71    }
72}