Passed
Push — master ( 870a57...334d92 )
by Mikaël
13:03 queued 09:40
created

GeneratorOptions::getSuffix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\ConfigurationReader;
6
7
use InvalidArgumentException;
8
use JsonSerializable;
9
use WsdlToPhp\PackageGenerator\Model\StructValue;
10
11
/**
12
 * @method string getCategory()
13
 * @method self   setCategory(string $category)
14
 * @method string getGatherMethods()
15
 * @method self   setGatherMethods(string $gatherMethods)
16
 * @method bool   getGenerateTutorialFile()
17
 * @method self   setGenerateTutorialFile(bool $generateTutorialFile)
18
 * @method bool   getGenericConstantsNames()
19
 * @method self   setGenericConstantsNames(bool $genericConstantsNames)
20
 * @method bool   getNamespaceDictatesDirectories()
21
 * @method self   setNamespaceDictatesDirectories(bool $namespaceDictatesDirectories)
22
 * @method bool   getStandalone()
23
 * @method self   setStandalone(bool $standalone)
24
 * @method bool   getValidation()
25
 * @method self   setValidation(bool $validation)
26
 * @method string getStructClass()
27
 * @method self   setStructClass(string $structClass)
28
 * @method string getStructArrayClass()
29
 * @method self   setStructArrayClass(string $structArrayClass)
30
 * @method string getStructEnumClass()
31
 * @method self   setStructEnumClass(string $structEnumClass)
32
 * @method string getSoapClientClass()
33
 * @method self   setSoapClientClass(string $soapClientClass)
34
 * @method string getOptionNamespace()
35
 * @method self   setOptionNamespace(string $namespace)
36
 * @method string getOrigin()
37
 * @method self   setOrigin(string $origin)
38
 * @method string getDestination()
39
 * @method self   setDestination(string $destination)
40
 * @method string getSrcDirname()
41
 * @method self   setSrcDirname(string $srcDirname)
42
 * @method string getPrefix()
43
 * @method self   setPrefix(string $prefix)
44
 * @method string getSuffix()
45
 * @method self   setSuffix(string $suffix)
46
 * @method string getBasicLogin()
47
 * @method self   setBasicLogin(string $basicLogin)
48
 * @method string getBasicPassword()
49
 * @method self   setBasicPassword(string $basicPassword)
50
 * @method string getProxyHost()
51
 * @method self   setProxyHost(string $proxyHost)
52
 * @method string getProxyPort()
53
 * @method self   setProxyPort(string $proxyPort)
54
 * @method string getProxyLogin()
55
 * @method self   setProxyLogin(string $proxyLogin)
56
 * @method string getProxyPassword()
57
 * @method self   setProxyPassword(string $proxyPassword)
58
 * @method string getSoapOptions()
59
 * @method self   setSoapOptions(array $soapOptions)
60
 * @method string getComposerName()
61 20
 * @method self   setComposerName(string $composerName)
62
 * @method array  getComposerSettings()
63 20
 * @method string getStructsFolder()
64 20
 * @method self   setStructsFolder(string $structsFolder)
65 18
 * @method string getArraysFolder()
66
 * @method self   setArraysFolder(string $arraysFolder)
67 714
 * @method string getEnumsFolder()
68
 * @method self   setEnumsFolder(string $enumsFolder)
69 714
 * @method string getServicesFolder()
70 2
 * @method self   setServicesFolder(string $servicesFolder)
71
 * @method bool   getSchemasSave()
72
 * @method self   setSchemasSave(bool $saveSchemas)
73 712
 * @method string getSchemasFolder()
74
 * @method self   setSchemasFolder(string $schemasFolder)
75
 * @method string getXsdTypesPath()
76 522
 * @method self   setXsdTypesPath(string $xsdTypesPath)
77
 */
78 522
final class GeneratorOptions extends AbstractYamlReader implements JsonSerializable
79 4
{
80 4
    /**
81 4
     * Common values used as option's value.
82
     */
83 520
    public const VALUE_CAT = 'cat';
84 4
    public const VALUE_END = 'end';
85
    public const VALUE_FALSE = false;
86 516
    public const VALUE_NONE = 'none';
87
    public const VALUE_START = 'start';
88
    public const VALUE_TRUE = true;
89 518
90
    /**
91
     * Possible option keys.
92 234
     */
93
    public const ADD_COMMENTS = 'add_comments';
94 234
    public const ARRAYS_FOLDER = 'arrays_folder';
95
    public const BASIC_LOGIN = 'basic_login';
96
    public const BASIC_PASSWORD = 'basic_password';
97 236
    public const CATEGORY = 'category';
98
    public const COMPOSER_NAME = 'composer_name';
99 236
    public const COMPOSER_SETTINGS = 'composer_settings';
100
    public const DESTINATION = 'destination';
101
    public const ENUMS_FOLDER = 'enums_folder';
102
    public const GATHER_METHODS = 'gather_methods';
103
    public const GENERATE_TUTORIAL_FILE = 'generate_tutorial_file';
104
    public const GENERIC_CONSTANTS_NAME = 'generic_constants_names';
105
    public const NAMESPACE_PREFIX = 'namespace_prefix';
106
    public const NAMESPACE_DICTATES_DIRECTORIES = 'namespace_dictates_directories';
107
    public const ORIGIN = 'origin';
108
    public const PREFIX = 'prefix';
109
    public const PROXY_HOST = 'proxy_host';
110
    public const PROXY_LOGIN = 'proxy_login';
111 18
    public const PROXY_PASSWORD = 'proxy_password';
112
    public const PROXY_PORT = 'proxy_port';
113 18
    public const SERVICES_FOLDER = 'services_folder';
114
    public const SOAP_CLIENT_CLASS = 'soap_client_class';
115
    public const SOAP_OPTIONS = 'soap_options';
116
    public const SRC_DIRNAME = 'src_dirname';
117
    public const STANDALONE = 'standalone';
118
    public const STRUCT_ARRAY_CLASS = 'struct_array_class';
119
    public const STRUCT_ENUM_CLASS = 'struct_enum_class';
120
    public const STRUCT_CLASS = 'struct_class';
121 166
    public const STRUCTS_FOLDER = 'structs_folder';
122
    public const SUFFIX = 'suffix';
123 166
    public const VALIDATION = 'validation';
124
    public const SCHEMAS_SAVE = 'schemas_save';
125
    public const SCHEMAS_FOLDER = 'schemas_folder';
126
    public const XSD_TYPES_PATH = 'xsd_types_path';
127
128
    protected array $options;
129
130
    protected function __construct(string $filename)
131
    {
132
        $this->options = [];
133 38
        $this->parseOptions($filename);
134
    }
135
136
    public function __call($name, $arguments)
137
    {
138 38
        if ('set' === substr($name, 0, 3) && 1 === count($arguments)) {
139 38
            return $this->setOptionValue(self::methodNameToOptionName($name), array_shift($arguments));
140 8
        }
141 2
        if ('get' === substr($name, 0, 3) && empty($arguments)) {
142 2
            return $this->getOptionValue(self::methodNameToOptionName($name));
143
        }
144 6
145
        throw new \BadMethodCallException(sprintf('Method %s undefined', $name));
146
    }
147
148 38
    public function getOptionValue(string $optionName)
149
    {
150
        if (!array_key_exists($optionName, $this->options)) {
151
            throw new InvalidArgumentException(sprintf('Invalid option name "%s", possible options: %s', $optionName, implode(', ', array_keys($this->options))), __LINE__);
152
        }
153
154
        return array_key_exists('value', $this->options[$optionName]) ? $this->options[$optionName]['value'] : $this->options[$optionName]['default'];
155
    }
156 184
157
    public function setOptionValue(string $optionName, $optionValue, array $values = []): self
158 184
    {
159
        if (!array_key_exists($optionName, $this->options)) {
160
            $this->options[$optionName] = [
161
                'value' => $optionValue,
162
                'values' => $values,
163
            ];
164
        } elseif (!empty($this->options[$optionName]['values']) && !in_array($optionValue, $this->options[$optionName]['values'], true)) {
165
            throw new InvalidArgumentException(sprintf('Invalid value "%s" for option "%s", possible values: %s', $optionValue, $optionName, implode(', ', $this->options[$optionName]['values'])), __LINE__);
166
        } else {
167
            $this->options[$optionName]['value'] = $optionValue;
168
        }
169
170 16
        return $this;
171
    }
172 16
173
    public static function getDefaultConfigurationPath(): string
174
    {
175
        return __DIR__.'/../resources/config/generator_options.yml';
176
    }
177
178
    public static function methodNameToOptionName(string $name): string
179
    {
180 20
        return trim(strtolower(preg_replace(StructValue::MATCH_PATTERN, StructValue::REPLACEMENT_PATTERN, substr($name, 3))), '_');
181
    }
182 20
183
    public function setAddComments(array $addComments = []): self
184
    {
185
        /**
186
         * If array is type array("author:john Doe","Release:1",).
187
         */
188
        $comments = [];
189
        foreach ($addComments as $index => $value) {
190
            if (is_numeric($index) && mb_strpos($value, ':') > 0) {
191
                [$tag, $val] = explode(':', $value);
192
                $comments[$tag] = $val;
193
            } else {
194 30
                $comments[$index] = $value;
195
            }
196 30
        }
197
198
        return $this->setOptionValue(self::ADD_COMMENTS, $comments);
199
    }
200
201
    public function getNamespace(): string
202
    {
203
        return $this->getOptionValue(self::NAMESPACE_PREFIX);
204 236
    }
205
206 236
    public function setNamespace(string $namespace): self
207
    {
208
        return $this->setOptionValue(self::NAMESPACE_PREFIX, $namespace);
209
    }
210
211
    public function setComposerSettings(array $composerSettings = []): self
212
    {
213
        /**
214
         * If array is type array("config.value:true","require:library/src",).
215
         */
216
        $settings = [];
217
        foreach ($composerSettings as $index => $value) {
218 24
            if (is_numeric($index) && mb_strpos($value, ':') > 0) {
219
                $path = implode('', array_slice(explode(':', $value), 0, 1));
220 24
                $val = implode(':', array_slice(explode(':', $value), 1));
221
                self::dotNotationToArray($path, $val, $settings);
222
            } else {
223
                $settings[$index] = $value;
224
            }
225
        }
226
227
        return $this->setOptionValue(self::COMPOSER_SETTINGS, $settings);
228 52
    }
229
230 52
    public function toArray(): array
231
    {
232
        $options = [];
233
        foreach (array_keys($this->options) as $name) {
234
            $options[$name] = $this->getOptionValue($name);
235
        }
236
237
        return $options;
238
    }
239
240
    public function jsonSerialize(): array
241
    {
242 30
        return $this->toArray();
243
    }
244 30
245
    protected function parseOptions(string $filename): self
246
    {
247
        $options = $this->loadYaml($filename);
248
        if (is_array($options)) {
249
            $this->options = $options;
250
        } else {
251
            throw new InvalidArgumentException(sprintf('Settings contained by "%s" are not valid as the settings are not contained by an array: "%s"', $filename, gettype($options)), __LINE__);
252 38
        }
253
254 38
        return $this;
255
    }
256
257
    /**
258
     * turns my.key.path to array('my' => array('key' => array('path' => $value))).
259
     *
260
     * @param mixed $value
261
     */
262
    protected static function dotNotationToArray(string $string, $value, array &$array)
263
    {
264
        $keys = explode('.', $string);
265
        foreach ($keys as $key) {
266 18
            $array = &$array[$key];
267
        }
268 18
        $array = ('true' === $value || 'false' === $value) ? 'true' === $value : $value;
269
    }
270
}
271