Completed
Push — develop ( af8b85...9cf029 )
by Susi
11s
created

ConfigurationParser::cleanSettingsArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
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
     * @param string                   $configPath
35
     */
36
    public function __construct(LoggerInterface $logger)
37
    {
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
        $configPath = getenv('configurationPath');
50
        $this->logger->info('Loading configuration from ' . $configPath);
51
        $filesInFolder = $this->getFilesInFolder($configPath);
52
        $this->logger->debug('Found: ' . var_export($filesInFolder, true));
53
        foreach ($filesInFolder as $indexName) {
54
            $subFolder = $configPath . $indexName;
55
            if (is_dir($subFolder) === true && file_exists($subFolder . '/' . self::INDEX_CONF_FILENAME)) {
56
                $indices[strtolower($indexName)] = $this->getIndexConfiguration($indexName);
57
            }
58
        }
59
        return $indices;
60
    }
61
62
    /**
63
     * Get Configuration for specified index1
64
     *
65
     * @param string $indexName
66
     *
67
     * @return array
68
     */
69
    public function getIndexConfiguration(string $indexName): array
70
    {
71
        $filePath = $this->getIndexDirectory($indexName) . '/' . self::INDEX_CONF_FILENAME;
72
        return $this->getConfig($filePath);
73
    }
74
75
    /**
76
     * Get all document type configurations for index
77
     *
78
     * @param string $indexName
79
     * @param string $language
80
     *
81
     * @return array
82
     */
83
    public function getDocumentTypeConfigurations(string $indexName, string $language = ''): array
84
    {
85
        $configs = [];
86
        $directory = $this->getDocumentTypesDirectory($indexName);
87
        $configFiles = $this->getFilesInFolder($directory);
88
        foreach ($configFiles as $configFile) {
89
            $filePath = $directory . $configFile;
90
            $pathInfo = pathinfo($filePath);
91
            if ($pathInfo['extension'] === 'yaml') {
92
                $configs[$pathInfo['filename']] = $this->getConfig($filePath);
93
            }
94
        }
95
        if ($language !== '') {
96
            $configs = $this->addAnalyzerToConfig($language, $configs);
97
        }
98
        return $configs;
99
    }
100
101
    /**
102
     * Convert document type configuration to mapping as returned from elastica (for comparison for example)
103
     *
104
     * @param array $configurations
105
     *
106
     * @return array
107
     */
108
    public function convertDocumentTypeConfigurationToMappingFromElastica(array $configurations): array
109
    {
110
        $mappings = [];
111
        foreach ($configurations as $index => $configuration) {
112
            $mappings[$index]['properties'] = $configuration;
113
        }
114
        return $mappings;
115
    }
116
117
    /**
118
     * Get configuration for document type in index
119
     *
120
     * @param string $indexName
121
     * @param string $documentType
122
     *
123
     * @return array
124
     */
125
    public function getDocumentTypeConfiguration(string $indexName, string $documentType): array
126
    {
127
        $filePath = $this->getDocumentTypesDirectory($indexName) . strtolower($documentType) . '.yaml';
128
        return $this->getConfig($filePath);
129
    }
130
131
    /**
132
     * @param string $language
133
     * @param        $configs
134
     *
135
     * @return mixed
136
     */
137
    private function addAnalyzerToConfig(string $language, $configs)
138
    {
139
        foreach ($configs as $key => $field) {
140
            foreach ($field as $name => $config) {
141
                if (array_key_exists('analyzer', $config)) {
142
                    $configs[$key][$name]['analyzer'] = $language;
143
                }
144
            }
145
        }
146
        return $configs;
147
    }
148
149
    /**
150
     * @param string $indexName
151
     *
152
     * @return string
153
     */
154
    private function getDocumentTypesDirectory(string $indexName): string
155
    {
156
        return $this->getIndexDirectory($indexName) . '/DocumentTypes/';
157
    }
158
159
    /**
160
     * @param string $directory
161
     *
162
     * @return array
163
     */
164
    private function getFilesInFolder(string $directory): array
165
    {
166
        return array_diff(scandir($directory, 0), ['..', '.']);
167
    }
168
169
    /**
170
     * @param string $indexName
171
     *
172
     * @return string
173
     */
174
    private function getIndexDirectory(string $indexName): string
175
    {
176
        $indexDir = getenv('configurationPath') . $indexName;
177
        if (!file_exists($indexDir)) {
178
            throw new \InvalidArgumentException(
179
                'Configuration directory ' . $indexDir . ' for index ' . $indexName . ' does not exist.', 666
180
            );
181
        }
182
        return $indexDir;
183
    }
184
185
    /**
186
     * @param string $filePath
187
     *
188
     * @return array
189
     * @throws \InvalidArgumentException
190
     */
191
    private function getConfig(string $filePath): array
192
    {
193
        if (!file_exists($filePath)) {
194
            throw new \InvalidArgumentException('No configuration found at ' . $filePath, 666);
195
        }
196
        $configFileContent = file_get_contents($filePath);
197
        return Yaml::parse($configFileContent);
198
    }
199
200
    public function createConfigurationForIndex(string $indexName, array $mapping, array $settings)
201
    {
202
        $this->createConfigurationDirectories($indexName);
203
        $indexDirectory = $this->getIndexDirectory($indexName);
204
        $documentTypesDirectory = $this->getDocumentTypesDirectory($indexName);
205
        file_put_contents($indexDirectory . '/IndexConfiguration.yaml', Yaml::dump($settings));
206
        foreach ($mapping as $documentType => $mappingConfig) {
207
            file_put_contents(
208
                $documentTypesDirectory . '/' . $documentType . '.yaml',
209
                Yaml::dump($mappingConfig['properties'])
210
            );
211
        }
212
    }
213
214
    /**
215
     * Remove array keys from settings the remote server returns
216
     * but we don't want in the config file
217
     *
218
     * @param array $settings
219
     *
220
     * @return array
221
     */
222
    public function cleanSettingsArray(array $settings): array
223
    {
224
        $unwantedSettings = [
225
            'creation_date',
226
            'uuid',
227
            'version',
228
            'provided_name'
229
        ];
230
        return array_diff_key($settings, array_flip($unwantedSettings));
231
232
    }
233
234
    private function createConfigurationDirectories(string $indexName)
235
    {
236
        $configPath = getenv('configurationPath');
237
        mkdir($configPath . $indexName);
238
        mkdir($configPath . $indexName . '/DocumentTypes');
239
    }
240
}