Passed
Push — develop ( 7b8638...42fd7f )
by Susi
01:52
created

ConfigurationParser::addAnalyzerToConfig()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.2
c 0
b 0
f 0
cc 4
eloc 5
nc 4
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace T3G\Elasticorn\Utility;
5
6
use Psr\Log\LoggerInterface;
7
use Symfony\Component\Yaml\Yaml;
8
9
/**
10
 * Class ConfigurationParser
11
 *
12
 * @package T3G\Elasticorn
13
 */
14
class ConfigurationParser
15
{
16
    /**
17
     * Name of index configuration file
18
     */
19
    const INDEX_CONF_FILENAME = 'IndexConfiguration.yaml';
20
21
    /**
22
     * @var string
23
     */
24
    private $configFolder;
25
    /**
26
     * @var \Psr\Log\LoggerInterface
27
     */
28
    private $logger;
29
30
    /**
31
     * ConfigurationParser constructor.
32
     *
33
     * @param \Psr\Log\LoggerInterface $logger
34
     */
35
    public function __construct(LoggerInterface $logger)
36
    {
37
        $this->configFolder = &$_ENV['configurationPath'];
38
        $this->logger = $logger;
39
    }
40
41
    /**
42
     * Get configurations for all indices
43
     *
44
     * @return array
45
     */
46
    public function getIndexConfigurations(): array
47
    {
48
        $indices = [];
49
        $this->logger->info('Loading configuration from ' . $this->configFolder);
50
        $filesInFolder = $this->getFilesInFolder($this->configFolder);
51
        $this->logger->debug('Found: ' . var_export($filesInFolder, true));
52
        foreach ($filesInFolder as $indexName) {
53
            $subFolder = $this->configFolder . $indexName;
54
            if (is_dir($subFolder) === true && file_exists($subFolder . '/' . self::INDEX_CONF_FILENAME)) {
55
                $indices[strtolower($indexName)] = $this->getIndexConfiguration($indexName);
56
            }
57
        }
58
        return $indices;
59
    }
60
61
    /**
62
     * Get Configuration for specified index1
63
     *
64
     * @param string $indexName
65
     *
66
     * @return array
67
     */
68
    public function getIndexConfiguration(string $indexName): array
69
    {
70
        $filePath = $this->getIndexDirectory($indexName) . '/' . self::INDEX_CONF_FILENAME;
71
        return $this->getConfig($filePath);
72
    }
73
74
    /**
75
     * Get all document type configurations for index
76
     *
77
     * @param string $indexName
78
     * @param string $language
79
     *
80
     * @return array
81
     */
82
    public function getDocumentTypeConfigurations(string $indexName, string $language = ''): array
83
    {
84
        $configs = [];
85
        $directory = $this->getDocumentTypesDirectory($indexName);
86
        $configFiles = $this->getFilesInFolder($directory);
87
        foreach ($configFiles as $configFile) {
88
            $filePath = $directory . $configFile;
89
            $pathInfo = pathinfo($filePath);
90
            if ($pathInfo['extension'] === 'yaml') {
91
                $configs[$pathInfo['filename']] = $this->getConfig($filePath);
92
            }
93
        }
94
        if ($language !== '') {
95
            $configs = $this->addAnalyzerToConfig($language, $configs);
96
        }
97
        return $configs;
98
    }
99
100
    /**
101
     * Convert document type configuration to mapping as returned from elastica (for comparison for example)
102
     *
103
     * @param array $configurations
104
     *
105
     * @return array
106
     */
107
    public function convertDocumentTypeConfigurationToMappingFromElastica(array $configurations): array
108
    {
109
        $mappings = [];
110
        foreach ($configurations as $index => $configuration) {
111
            $mappings[$index]['properties'] = $configuration;
112
        }
113
        return $mappings;
114
    }
115
116
    /**
117
     * Get configuration for document type in index
118
     *
119
     * @param string $indexName
120
     * @param string $documentType
121
     *
122
     * @return array
123
     */
124
    public function getDocumentTypeConfiguration(string $indexName, string $documentType): array
125
    {
126
        $filePath = $this->getDocumentTypesDirectory($indexName) . strtolower($documentType) . '.yaml';
127
        return $this->getConfig($filePath);
128
    }
129
130
    /**
131
     * @param string $language
132
     * @param        $configs
133
     *
134
     * @return mixed
135
     */
136
    private function addAnalyzerToConfig(string $language, $configs)
137
    {
138
        foreach ($configs as $key => $field) {
139
            foreach ($field as $name => $config) {
140
                if (array_key_exists('analyzer', $config)) {
141
                    $configs[$key][$name]['analyzer'] = $language;
142
                }
143
            }
144
        }
145
        return $configs;
146
    }
147
148
    /**
149
     * @param string $indexName
150
     *
151
     * @return string
152
     */
153
    private function getDocumentTypesDirectory(string $indexName): string
154
    {
155
        return $this->getIndexDirectory($indexName) . '/DocumentTypes/';
156
    }
157
158
    /**
159
     * @param string $directory
160
     *
161
     * @return array
162
     */
163
    private function getFilesInFolder(string $directory): array
164
    {
165
        return array_diff(scandir($directory), ['..', '.']);
166
    }
167
168
    /**
169
     * @param string $indexName
170
     *
171
     * @return string
172
     */
173
    private function getIndexDirectory(string $indexName): string
174
    {
175
        $indexDir = $this->configFolder . $indexName;
176
        if (!file_exists($indexDir)) {
177
            throw new \InvalidArgumentException(
178
                'Configuration directory ' . $indexDir . ' for index ' . $indexName . ' does not exist.', 666
179
            );
180
        }
181
        return $indexDir;
182
    }
183
184
    /**
185
     * @param string $filePath
186
     *
187
     * @return array
188
     * @throws \InvalidArgumentException
189
     */
190
    private function getConfig(string $filePath): array
191
    {
192
        if (!file_exists($filePath)) {
193
            throw new \InvalidArgumentException('No configuration found at ' . $filePath, 666);
194
        }
195
        $configFileContent = file_get_contents($filePath);
196
        return Yaml::parse($configFileContent);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Symfony\Component...rse($configFileContent) could return the type stdClass|null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
197
    }
198
199
    public function createConfigurationForIndex(string $indexName, array $mapping, array $settings)
200
    {
201
        $this->createConfigurationDirectories($indexName);
202
        $indexDirectory = $this->getIndexDirectory($indexName);
203
        $documentTypesDirectory = $this->getDocumentTypesDirectory($indexName);
204
        file_put_contents($indexDirectory . '/IndexConfiguration.yaml', Yaml::dump($settings));
205
        foreach ($mapping as $documentType => $mappingConfig) {
206
            file_put_contents(
207
                $documentTypesDirectory . '/' . $documentType . '.yaml',
208
                Yaml::dump($mappingConfig['properties'])
209
            );
210
        }
211
    }
212
213
    private function createConfigurationDirectories(string $indexName)
214
    {
215
        mkdir($this->configFolder . $indexName);
216
        mkdir($this->configFolder . $indexName . '/DocumentTypes');
217
    }
218
}