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