Passed
Push — master ( 41a727...ec7c33 )
by Sergey
02:52
created

Informer::getOptionName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 8
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
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\NotFoundException;
15
use LTDBeget\sphinx\informer\exceptions\UnknownValueException;
16
use LTDBeget\sphinx\informer\exceptions\YamlParseException;
17
use /** @noinspection PhpUndefinedClassInspection */
18
    Symfony\Component\Yaml\Parser;
19
20
/**
21
 * Class Informer
22
 * Class for manipulating with options info
23
 * @package LTDBeget\sphinx\informer
24
 */
25
final class Informer
26
{
27
    /**
28
     * Get informer for concrete version, and init if did not init yet
29
     * @param eVersion $version
30
     * @return Informer
31
     */
32 6
    public static function get(eVersion $version) : Informer
33
    {
34 6
        if (!array_key_exists("$version", self::$instances)) {
35 3
            self::$instances["$version"] = new self($version);
36
        }
37
38 6
        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 NotFoundException
47
     */
48 5
    public function getOptionInfo(eSection $section, eOption $optionName) : OptionInfo
49
    {
50 5
        if (!$this->isOptionInfoInit($section, $optionName)) {
51 3
            $this->makeOptionInfo($section, $optionName);
52
        }
53
54 5
        return $this->optionsInfo[(string) $section][(string) $optionName];
55
    }
56
57
    /**
58
     * check is known option for yaml documentation for concrete version
59
     * @param eSection $section
60
     * @param eOption $optionName
61
     * @return bool
62
     */
63 5
    public function isKnownOption(eSection $section, eOption $optionName)
64
    {
65 5
        return array_key_exists((string) $section, $this->documentation) &&
66 5
        array_key_exists((string) $optionName, $this->documentation[(string) $section]);
67
    }
68
69
    /**
70
     * Is this section exists in current sphinx version
71
     * @param eSection $section
72
     * @return bool
73
     */
74 6
    public function isSectionExist(eSection $section) : bool
75
    {
76 6
        if($section == eSection::COMMON && version_compare( (string) $this->version, eVersion::V_2_2_1, '<')) {
77 3
            return false;
78
        }
79
80 4
        return true;
81
    }
82
83
    /**
84
     * Iterate via all option in documentation via option section type
85
     * @param eSection $section
86
     * @return OptionInfo[]
87
     * @throws UnknownValueException
88
     */
89 2
    public function iterateOptionInfo(eSection $section)
90
    {
91 2
        if (! $this->isSectionExist($section)) {
92 1
            throw new \LogicException("Sphinx of version {$this->version} does't have section {$section}");
93
        }
94
95 1
        foreach ($this->documentation[(string) $section] as $optionName => $optionData) {
96 1
            yield $this->getOptionInfo($section, $this->getOptionName($section, $optionName));
97
        }
98 1
    }
99
100
    /**
101
     * Get enum for given section and string name
102
     * @internal
103
     * @param eSection $section
104
     * @param string $optionName
105
     * @return eOption
106
     */
107 1
    private function getOptionName(eSection $section, string $optionName) : eOption
108
    {
109 1
        $enumClassName = "LTDBeget\\sphinx\\enums\\options\\e".ucfirst( (string) $section)."Option";
110
        /**
111
         * @var eOption $enumClassName
112
         */
113 1
        return $enumClassName::get($optionName);
114
    }
115
116
    /**
117
     * Informer constructor.
118
     * Init informer for concrete sphinx version
119
     * @param eVersion $version
120
     * @throws NotFoundException
121
     */
122 3
    private function __construct(eVersion $version)
123
    {
124 3
        $this->version = $version;
125 3
        $this->loadDocumentation();
126 3
    }
127
128
    /**
129
     * check is option info object already init
130
     * @param eSection $section
131
     * @param eOption $optionName
132
     * @return bool
133
     */
134 5
    private function isOptionInfoInit(eSection $section, eOption $optionName) : bool
135
    {
136 5
        return array_key_exists((string) $section, $this->optionsInfo) &&
137 5
        array_key_exists((string) $optionName, $this->optionsInfo[(string) $section]);
138
    }
139
140
    /**
141
     * make option info object from plain data
142
     * @param eSection $section
143
     * @param eOption $optionName
144
     * @throws NotFoundException
145
     */
146 3
    private function makeOptionInfo(eSection $section, eOption $optionName)
147
    {
148 3
        if (!$this->isKnownOption($section, $optionName)) {
149
            throw new NotFoundException("For version {$this->version} {$optionName} is unknown option");
150
        }
151 3
        $info_data = $this->documentation[(string) $section][(string) $optionName];
152
153 3
        $optionInfo = new OptionInfo(
154
            $optionName,
155
            $section,
156 3
            $this->version,
157 3
            $info_data["description"],
158 3
            $info_data["multi_value"],
159 3
            $info_data["link"]
160
        );
161
162 3
        $this->optionsInfo[(string) $section][(string) $optionName] = $optionInfo;
163 3
    }
164
165
    /**
166
     * loads configuration from yaml files and save as array
167
     * @throws NotFoundException
168
     */
169 3
    private function loadDocumentation()
170
    {
171 3
        $path = $this->getDocumentationFilePath();
172
173 3
        if (!$this->isDocumentationExists()) {
174
            throw new NotFoundException("For version {$this->version} there are no file: {$path}");
175
        }
176
177
        /** @noinspection PhpUndefinedClassInspection */
178 3
        $documentation = (new Parser())->parse(file_get_contents($path));
179
180 3
        if (!is_array($documentation)) {
181
            throw new YamlParseException("Failed to parse yaml file {$path}");
182
        }
183
184 3
        $this->documentation = $documentation;
185 3
    }
186
187
    /**
188
     * check is documentation yaml file exists
189
     * @return bool
190
     */
191 3
    private function isDocumentationExists() : bool
192
    {
193 3
        return is_file($this->getDocumentationFilePath());
194
    }
195
196
    /**
197
     * path to yaml sphinx documentation
198
     * @return string
199
     */
200 3
    private function getDocumentationDirectoryPath() : string
201
    {
202 3
        return realpath(__DIR__ . "/../../../../sphinx/docs");
203
    }
204
205
    /**
206
     * path to yaml sphinx documentation file
207
     * @return string
208
     */
209 3
    private function getDocumentationFilePath() : string
210
    {
211 3
        return $this->getDocumentationDirectoryPath() . "/documentation_{$this->version}.yaml";
212
    }
213
214
    /**
215
     * @var Informer[]
216
     */
217
    private static $instances = [];
218
219
    /**
220
     * @var eVersion
221
     */
222
    private $version;
223
224
    /**
225
     * @var array
226
     */
227
    private $documentation;
228
229
    /**
230
     * @var array
231
     */
232
    private $optionsInfo = [];
233
}