Passed
Push — master ( 6e9648...ae59e9 )
by Sergey
05:36 queued 02:45
created

Informer::isRemovedOption()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * @author: Viskov Sergey
4
 * @date: 3/17/16
5
 * @time: 1:22 PM
6
 */
7
8
namespace LTDBeget\sphinx\informer;
9
10
11
use LTDBeget\sphinx\enums\base\eOption;
12
use LTDBeget\sphinx\enums\eSection;
13
use LTDBeget\sphinx\enums\eVersion;
14
use LTDBeget\sphinx\informer\exceptions\DocumentationSourceException;
15
use LTDBeget\sphinx\informer\exceptions\InformerRuntimeException;
16
use Symfony\Component\Yaml\Parser;
17
18
/**
19
 * Class Informer
20
 * Class for manipulating with options info
21
 * @package LTDBeget\sphinx\informer
22
 */
23
final class Informer
24
{
25
    /**
26
     * Get informer for concrete version, and init if did not init yet
27
     * @param eVersion $version
28
     * @return Informer
29
     * @throws \Symfony\Component\Yaml\Exception\ParseException
30
     * @throws \LTDBeget\sphinx\informer\exceptions\DocumentationSourceException
31
     */
32 15
    public static function get(eVersion $version) : Informer
33
    {
34 15
        if (!array_key_exists("$version", self::$instances)) {
35 3
            self::$instances["$version"] = new self($version);
36
        }
37
38 15
        return self::$instances["$version"];
39
    }
40
41
    /**
42
     * return option info for concrete option of concrete section
43
     * @param eSection $section
44
     * @param eOption $optionName
45
     * @return OptionInfo
46
     * @throws \LTDBeget\sphinx\informer\exceptions\InformerRuntimeException
47
     */
48 9
    public function getOptionInfo(eSection $section, eOption $optionName) : OptionInfo
49
    {
50 9
        if (! $this->isSectionExist($section)) {
51 1
            throw new InformerRuntimeException("Sphinx of version {$this->version} does't have section {$section}");
52
        }
53
54 8
        if (! $this->isKnownOption($section, $optionName)) {
55 1
            throw new InformerRuntimeException("For sphinx v. {$this->version} option {$optionName} in {$section} isn't available");
56
        }
57
        
58 7
        if ($this->isRemovedOption($section, $optionName)) {
59
            throw new InformerRuntimeException("For sphinx v. {$this->version} option {$optionName} in {$section} is permanently removed");
60
        }
61
        
62 7
        if (!$this->isOptionInfoInit($section, $optionName)) {
63 3
            $this->makeOptionInfo($section, $optionName);
64
        }
65
66 7
        return $this->optionsInfo[(string) $section][(string) $optionName];
67
    }
68
69
    /**
70
     * check is known option for yaml documentation for concrete version
71
     * @param eSection $section
72
     * @param eOption $optionName
73
     * @return bool
74
     */
75 8
    public function isKnownOption(eSection $section, eOption $optionName)
76
    {
77 8
        return array_key_exists((string) $section, $this->documentation) &&
78 8
        array_key_exists((string) $optionName, $this->documentation[(string) $section]);
79
    }
80
81
    /**
82
     * checks is this option was permanently removed in newer sphinx version
83
     * @param eSection $section
84
     * @param eOption $optionName
85
     * @return bool
86
     */
87 7
    public function isRemovedOption(eSection $section, eOption $optionName)
88
    {
89 7
        return array_key_exists((string) $section, $this->removedOptions) && 
90 7
            array_key_exists((string) $optionName, $this->removedOptions[(string) $section]);
91
    }
92
93
    /**
94
     * Is this section exists in current sphinx version
95
     * @param eSection $section
96
     * @return bool
97
     */
98 9
    public function isSectionExist(eSection $section) : bool
99
    {
100 9
        return !$section->is(eSection::COMMON) || !version_compare((string) $this->version, eVersion::V_2_2_1, '<');
101
    }
102
103
    /**
104
     * Iterate via all option in documentation via option section type
105
     * @param eSection $section
106
     * @return OptionInfo[]
107
     * @throws \LogicException
108
     * @throws \InvalidArgumentException
109
     * @throws \LTDBeget\sphinx\informer\exceptions\InformerRuntimeException
110
     */
111 1
    public function iterateOptionInfo(eSection $section)
112
    {
113 1
        if (! $this->isSectionExist($section)) {
114
            throw new InformerRuntimeException("Sphinx of version {$this->version} does't have section {$section}");
115
        }
116
117 1
        foreach ($this->documentation[(string) $section] as $optionName => $optionData) {
118 1
            yield $this->getOptionInfo($section, $this->getOptionName($section, $optionName));
119
        }
120 1
    }
121
122
    /**
123
     * Get enum for given section and string name
124
     * @internal
125
     * @param eSection $section
126
     * @param string $optionName
127
     * @return eOption
128
     * @throws \LogicException
129
     * @throws \InvalidArgumentException
130
     */
131 1
    private function getOptionName(eSection $section, string $optionName) : eOption
132
    {
133 1
        $enumClassName = "LTDBeget\\sphinx\\enums\\options\\e".ucfirst( (string) $section). 'Option';
134
        /**
135
         * @var eOption $enumClassName
136
         */
137 1
        return $enumClassName::get($optionName);
138
    }
139
140
    /**
141
     * Informer constructor.
142
     * Init informer for concrete sphinx version
143
     * @param eVersion $version
144
     * @throws \LTDBeget\sphinx\informer\exceptions\DocumentationSourceException
145
     * @throws \Symfony\Component\Yaml\Exception\ParseException
146
     */
147 3
    private function __construct(eVersion $version)
148
    {
149 3
        $this->version = $version;
150 3
        $this->loadDocumentation();
151 3
        $this->loadRemovedList();
152 3
    }
153
154
    /**
155
     * check is option info object already init
156
     * @param eSection $section
157
     * @param eOption $optionName
158
     * @return bool
159
     */
160 7
    private function isOptionInfoInit(eSection $section, eOption $optionName) : bool
161
    {
162 7
        return array_key_exists((string) $section, $this->optionsInfo) &&
163 7
        array_key_exists((string) $optionName, $this->optionsInfo[(string) $section]);
164
    }
165
166
    /**
167
     * make option info object from plain data
168
     * @param eSection $section
169
     * @param eOption $optionName
170
     * @throws \LTDBeget\sphinx\informer\exceptions\InformerRuntimeException
171
     */
172 3
    private function makeOptionInfo(eSection $section, eOption $optionName)
173
    {
174 3
        if (!$this->isKnownOption($section, $optionName)) {
175
            throw new InformerRuntimeException("For version {$this->version} {$optionName} is unknown option");
176
        }
177 3
        $info_data = $this->documentation[(string) $section][(string) $optionName];
178
179 3
        $optionInfo = new OptionInfo(
180
            $optionName,
181
            $section,
182 3
            $this->version,
183 3
            $info_data['description'],
184 3
            $info_data['multi_value'],
185 3
            $info_data['link']
186
        );
187
188 3
        $this->optionsInfo[(string) $section][(string) $optionName] = $optionInfo;
189 3
    }
190
191
    /**
192
     * load to object info about permanently removed options
193
     * @throws \LTDBeget\sphinx\informer\exceptions\DocumentationSourceException
194
     * @throws \Symfony\Component\Yaml\Exception\ParseException
195
     */
196 3
    private function loadRemovedList()
197
    {
198 3
        $path = $this->getRemovedListFilePath();
199
200 3
        if ($this->isRemovedListFileExists()) {
201
            /** @noinspection PhpUndefinedClassInspection */
202 2
            $removed_list = (new Parser())->parse(file_get_contents($path));
203
204 2
            if (!is_array($removed_list)) {
205
                throw new DocumentationSourceException("Failed to parse yaml file {$path}");
206
            }
207
208 2
            $this->removedOptions = $removed_list;
209
        }
210 3
    }
211
212
    /**
213
     * loads configuration from yaml files and save as array
214
     * @throws \LTDBeget\sphinx\informer\exceptions\DocumentationSourceException
215
     * @throws \Symfony\Component\Yaml\Exception\ParseException
216
     */
217 3
    private function loadDocumentation()
218
    {
219 3
        $path = $this->getDocumentationFilePath();
220
221 3
        if (!$this->isDocumentationExists()) {
222
            throw new DocumentationSourceException("For version {$this->version} there are no file: {$path}");
223
        }
224
225
        /** @noinspection PhpUndefinedClassInspection */
226 3
        $documentation = (new Parser())->parse(file_get_contents($path));
227
228 3
        if (!is_array($documentation)) {
229
            throw new DocumentationSourceException("Failed to parse yaml file {$path}");
230
        }
231
232 3
        $this->documentation = $documentation;
233 3
    }
234
235
    /**
236
     * check is documentation yaml file exists
237
     * @return bool
238
     */
239 3
    private function isDocumentationExists() : bool
240
    {
241 3
        return is_file($this->getDocumentationFilePath());
242
    }
243
244
    /**
245
     * path to yaml sphinx documentation
246
     * @return string
247
     */
248 3
    private function getDocumentationDirectoryPath() : string
249
    {
250 3
        return __DIR__ . '/../../../../sphinx/docs';
251
    }
252
253
    /**
254
     * path to yaml sphinx documentation file
255
     * @return string
256
     */
257 3
    private function getDocumentationFilePath() : string
258
    {
259 3
        return $this->getDocumentationDirectoryPath() . "/documentation_{$this->version}.yaml";
260
    }
261
262
    /**
263
     * Return path to file with removed options list
264
     * @return string
265
     */
266 3
    private function getRemovedListFilePath() : string
267
    {
268 3
        return $this->getDocumentationDirectoryPath() . "/permanently_removed_options_{$this->version}.yaml";
269
    }
270
271
    /**
272
     * Is file with removed options list exists
273
     * @return bool
274
     */
275 3
    private function isRemovedListFileExists() : bool
276
    {
277 3
        return is_file($this->getRemovedListFilePath());
278
    }
279
280
    /**
281
     * @var Informer[]
282
     */
283
    private static $instances = [];
284
285
    /**
286
     * @var eVersion
287
     */
288
    private $version;
289
290
    /**
291
     * @var array
292
     */
293
    private $documentation;
294
295
    /**
296
     * @var array
297
     */
298
    private $removedOptions = [];
299
300
    /**
301
     * @var array
302
     */
303
    private $optionsInfo = [];
304
}