Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.94% covered (success)
93.94%
31 / 33
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
CompletionSearchProfileRepository
93.94% covered (success)
93.94%
31 / 33
87.50% covered (warning)
87.50%
7 / 8
15.05
0.00% covered (danger)
0.00%
0 / 1
 fromFile
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 fromConfig
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 __construct
90.48% covered (success)
90.48%
19 / 21
0.00% covered (danger)
0.00%
0 / 1
8.06
 repositoryType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 repositoryName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getProfile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasProfile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 listExposedProfiles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace CirrusSearch\Profile;
4
5use CirrusSearch\SearchConfig;
6
7/**
8 * Repository dedicated to completion queries
9 * This one cannot simply use existing implementation because
10 * we need to filter the profiles based on the availability of
11 * some fields in the index.
12 */
13class CompletionSearchProfileRepository implements SearchProfileRepository {
14
15    /**
16     * @var SearchProfileRepository
17     */
18    private $wrapped;
19
20    /**
21     * @param string $repoType
22     * @param string $repoName
23     * @param string $phpFile
24     * @param SearchConfig $config
25     * @return CompletionSearchProfileRepository
26     */
27    public static function fromFile( $repoType, $repoName, $phpFile, SearchConfig $config ) {
28        // TODO: find a construct that does not require duplicating ArrayProfileRepository::fromFile
29        return new self( $repoType, $repoName, $config, static function () use ( $phpFile ) {
30            return require $phpFile;
31        } );
32    }
33
34    /**
35     * @param string $repoType
36     * @param string $repoName
37     * @param string $configEntry
38     * @param SearchConfig $config
39     * @return CompletionSearchProfileRepository
40     */
41    public static function fromConfig( $repoType, $repoName, $configEntry, SearchConfig $config ) {
42        return new self( $repoType, $repoName, $config, static function () use ( $configEntry, $config ) {
43            return ConfigProfileRepository::extractConfig( $configEntry, $config )
44                + ConfigProfileRepository::extractAttribute( $configEntry );
45        } );
46    }
47
48    /**
49     * @param string $repoType
50     * @param string $repoName
51     * @param SearchConfig $config
52     * @param callable $arrayLoader callable that resolves to an array of original profiles
53     */
54    private function __construct( $repoType, $repoName, SearchConfig $config, callable $arrayLoader ) {
55        $this->wrapped = ArrayProfileRepository::lazyLoaded( $repoType, $repoName, static function () use ( $arrayLoader, $config ) {
56            $profiles = [];
57
58            $allowedFields = [ 'suggest' => true, 'suggest-stop' => true ];
59            // Check that we can use the subphrases FST
60            if ( $config->getElement( 'CirrusSearchCompletionSuggesterSubphrases', 'use' ) ) {
61                $allowedFields['suggest-subphrases'] = true;
62            }
63            $originalProfiles = call_user_func( $arrayLoader );
64            if ( !is_array( $originalProfiles ) ) {
65                throw new SearchProfileException( "Expected an array but got a " . gettype( $originalProfiles ) );
66            }
67            foreach ( $originalProfiles as $name => $settings ) {
68                $allowed = true;
69                if ( !isset( $settings['fst'] ) ) {
70                    throw new SearchProfileException( "Completion profile $name must have a fst key defined" );
71                }
72                foreach ( $settings['fst'] as $value ) {
73                    if ( empty( $allowedFields[$value['field']] ) ) {
74                        $allowed = false;
75                        break;
76                    }
77                }
78                if ( !$allowed ) {
79                    continue;
80                }
81                $profiles[$name] = $settings;
82            }
83            return $profiles;
84        } );
85    }
86
87    /**
88     * @return string
89     */
90    public function repositoryType() {
91        return $this->wrapped->repositoryType();
92    }
93
94    /**
95     * @return string
96     */
97    public function repositoryName() {
98        return $this->wrapped->repositoryName();
99    }
100
101    /**
102     * @param string $name
103     * @return array
104     */
105    public function getProfile( $name ) {
106        return $this->wrapped->getProfile( $name );
107    }
108
109    /**
110     * @param string $name
111     * @return bool
112     */
113    public function hasProfile( $name ) {
114        return $this->wrapped->hasProfile( $name );
115    }
116
117    /**
118     * @return array[]
119     */
120    public function listExposedProfiles() {
121        return $this->wrapped->listExposedProfiles();
122    }
123}