GeneratePackageCommand::getGenerator()   A
last analyzed

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\Command;
6
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Output\OutputInterface;
10
use WsdlToPhp\PackageBase\AbstractSoapClientBase;
11
use WsdlToPhp\PackageBase\AbstractStructArrayBase;
12
use WsdlToPhp\PackageBase\AbstractStructBase;
13
use WsdlToPhp\PackageBase\AbstractStructEnumBase;
14
use WsdlToPhp\PackageGenerator\ConfigurationReader\GeneratorOptions;
15
use WsdlToPhp\PackageGenerator\Generator\Generator;
16
17
final class GeneratePackageCommand extends AbstractCommand
18
{
19
    public const GENERATOR_OPTIONS_CONFIG_OPTION = 'config';
20
    public const PROPER_USER_CONFIGURATION = 'wsdltophp.yml';
21
    public const DEFAULT_CONFIGURATION_FILE = 'wsdltophp.yml.dist';
22
23
    protected Generator $generator;
24
25
    protected GeneratorOptions $generatorOptions;
26
27 6
    public function getGenerator(): Generator
28
    {
29 6
        return $this->generator;
30
    }
31
32 20
    public function getGeneratorOptionsConfigOption()
33
    {
34 20
        return $this->getOptionValue(self::GENERATOR_OPTIONS_CONFIG_OPTION);
35
    }
36
37 20
    public function resolveGeneratorOptionsConfigPath(): ?string
38
    {
39 20
        $path = null;
40 20
        $possibilities = $this->getGeneratorOptionsPossibilities();
41 20
        foreach ($possibilities as $possibility) {
42 20
            if (!empty($possibility) && is_file($possibility)) {
43 20
                $path = $possibility;
44
45 20
                break;
46
            }
47
        }
48
49 20
        return $path;
50
    }
51
52 20
    public function getGeneratorOptionsPossibilities(): array
53
    {
54 20
        return [
55 20
            $this->getGeneratorOptionsConfigOption(),
56 20
            sprintf('%s/%s', getcwd(), self::PROPER_USER_CONFIGURATION),
57 20
            sprintf('%s/%s', getcwd(), self::DEFAULT_CONFIGURATION_FILE),
58 20
            GeneratorOptions::getDefaultConfigurationPath(),
59 20
        ];
60
    }
61
62 6
    protected function setGenerator(Generator $generator): self
63
    {
64 6
        $this->generator = $generator;
65
66 6
        return $this;
67
    }
68
69 8
    protected function initGenerator(): self
70
    {
71 8
        return $this->setGenerator(new Generator($this->generatorOptions));
72
    }
73
74 20
    protected function configure(): void
75
    {
76 20
        parent::configure();
77 20
        $this
78 20
            ->setName('generate:package')
79 20
            ->setDescription('Generate package based on options')
80 20
            ->addOption(
81 20
                'urlorpath',
82 20
                null,
83 20
                InputOption::VALUE_REQUIRED,
84 20
                'Url or path to WSDL'
85 20
            )
86 20
            ->addOption(
87 20
                'destination',
88 20
                null,
89 20
                InputOption::VALUE_REQUIRED,
90 20
                'Path to destination directory, where the package will be generated'
91 20
            )
92 20
            ->addOption(
93 20
                'login',
94 20
                null,
95 20
                InputOption::VALUE_OPTIONAL,
96 20
                'Basic authentication login required to access the WSDL url, can be avoided mot of the time'
97 20
            )
98 20
            ->addOption(
99 20
                'password',
100 20
                null,
101 20
                InputOption::VALUE_OPTIONAL,
102 20
                'Basic authentication password required to access the WSDL url, can be avoided mot of the time'
103 20
            )
104 20
            ->addOption(
105 20
                'proxy-host',
106 20
                null,
107 20
                InputOption::VALUE_OPTIONAL,
108 20
                'Use proxy url'
109 20
            )
110 20
            ->addOption(
111 20
                'proxy-port',
112 20
                null,
113 20
                InputOption::VALUE_OPTIONAL,
114 20
                'Use proxy port'
115 20
            )
116 20
            ->addOption(
117 20
                'proxy-login',
118 20
                null,
119 20
                InputOption::VALUE_OPTIONAL,
120 20
                'Use proxy login'
121 20
            )
122 20
            ->addOption(
123 20
                'proxy-password',
124 20
                null,
125 20
                InputOption::VALUE_OPTIONAL,
126 20
                'Use proxy password'
127 20
            )
128 20
            ->addOption(
129 20
                'prefix',
130 20
                null,
131 20
                InputOption::VALUE_REQUIRED,
132 20
                'Prepend generated classes'
133 20
            )
134 20
            ->addOption(
135 20
                'suffix',
136 20
                null,
137 20
                InputOption::VALUE_REQUIRED,
138 20
                'Append generated classes'
139 20
            )
140 20
            ->addOption(
141 20
                'namespace',
142 20
                null,
143 20
                InputOption::VALUE_OPTIONAL,
144 20
                'Package classes\' namespace'
145 20
            )
146 20
            ->addOption(
147 20
                'namespace-directories',
148 20
                null,
149 20
                InputOption::VALUE_OPTIONAL,
150 20
                'Should the directories match the namespace path or not? True by default'
151 20
            )
152 20
            ->addOption(
153 20
                'category',
154 20
                null,
155 20
                InputOption::VALUE_OPTIONAL,
156 20
                'First level directory name generation mode (start, end, cat, none)'
157 20
            )
158 20
            ->addOption(
159 20
                'gathermethods',
160 20
                null,
161 20
                InputOption::VALUE_OPTIONAL,
162 20
                'Gather methods based on operation name mode (start, end)'
163 20
            )
164 20
            ->addOption(
165 20
                'gentutorial',
166 20
                null,
167 20
                InputOption::VALUE_OPTIONAL,
168 20
                'Enable/Disable tutorial file, you should enable this option only on dev'
169 20
            )
170 20
            ->addOption(
171 20
                'genericconstants',
172 20
                null,
173 20
                InputOption::VALUE_OPTIONAL,
174 20
                'Enable/Disable usage of generic constants name (ex : ENUM_VALUE_0, ENUM_VALUE_1, etc) or contextual values (ex : VALUE_STRING, VALUE_YES, VALUES_NO, etc)'
175 20
            )
176 20
            ->addOption(
177 20
                'addcomments',
178 20
                null,
179 20
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
180 20
                'Set comments to be used within each generated file'
181 20
            )
182 20
            ->addOption(
183 20
                'standalone',
184 20
                null,
185 20
                InputOption::VALUE_OPTIONAL,
186 20
                'By default, the generated package can be used as a standalone. Otherwise, you must add wsdltophp/packagebase:dev-master to your main composer.json.'
187 20
            )
188 20
            ->addOption(
189 20
                'validation',
190 20
                null,
191 20
                InputOption::VALUE_OPTIONAL,
192 20
                'Enable/Disable the generation of validation rules in every generated setter.'
193 20
            )
194 20
            ->addOption(
195 20
                'struct',
196 20
                null,
197 20
                InputOption::VALUE_OPTIONAL,
198 20
                sprintf('Use this class as parent class for any StructType class. Default class is %s from wsdltophp/packagebase package', AbstractStructBase::class)
199 20
            )
200 20
            ->addOption(
201 20
                'structarray',
202 20
                null,
203 20
                InputOption::VALUE_OPTIONAL,
204 20
                sprintf('Use this class as parent class for any StructArrayType class. Default class is %s from wsdltophp/packagebase package', AbstractStructArrayBase::class)
205 20
            )
206 20
            ->addOption(
207 20
                'structenum',
208 20
                null,
209 20
                InputOption::VALUE_OPTIONAL,
210 20
                sprintf('Use this class as parent class for any StructEnumType class. Default class is %s from wsdltophp/packagebase package', AbstractStructEnumBase::class)
211 20
            )
212 20
            ->addOption(
213 20
                'soapclient',
214 20
                null,
215 20
                InputOption::VALUE_OPTIONAL,
216 20
                sprintf('Use this class as parent class for any ServiceType class. Default class is %s from wsdltophp/packagebase package', AbstractSoapClientBase::class)
217 20
            )
218 20
            ->addOption(
219 20
                'composer-name',
220 20
                null,
221 20
                InputOption::VALUE_REQUIRED,
222 20
                'Composer name of the generated package'
223 20
            )
224 20
            ->addOption(
225 20
                'composer-settings',
226 20
                null,
227 20
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
228 20
                'Composer settings of the generated package'
229 20
            )
230 20
            ->addOption(
231 20
                'structs-folder',
232 20
                null,
233 20
                InputOption::VALUE_OPTIONAL,
234 20
                'Structs folder name (default: SructType)'
235 20
            )
236 20
            ->addOption(
237 20
                'arrays-folder',
238 20
                null,
239 20
                InputOption::VALUE_OPTIONAL,
240 20
                'Arrays folder name (default: ArrayType)'
241 20
            )
242 20
            ->addOption(
243 20
                'enums-folder',
244 20
                null,
245 20
                InputOption::VALUE_OPTIONAL,
246 20
                'Enumerations folder name (default: EnumType)'
247 20
            )
248 20
            ->addOption(
249 20
                'services-folder',
250 20
                null,
251 20
                InputOption::VALUE_OPTIONAL,
252 20
                'Services class folder name (default: ServiceType)'
253 20
            )
254 20
            ->addOption(
255 20
                'src-dirname',
256 20
                null,
257 20
                InputOption::VALUE_OPTIONAL,
258 20
                'Source directory subfolder oof destination directory (default: src)'
259 20
            )
260 20
            ->addOption(
261 20
                'xsd-types-path',
262 20
                null,
263 20
                InputOption::VALUE_OPTIONAL,
264 20
                'Path to the xsd types configuration file to load'
265 20
            )
266 20
            ->addOption(
267 20
                self::GENERATOR_OPTIONS_CONFIG_OPTION,
268 20
                null,
269 20
                InputOption::VALUE_OPTIONAL,
270 20
                'Path to the generator\'s configuration file to load'
271 20
            )
272 20
        ;
273
    }
274
275 20
    protected function execute(InputInterface $input, OutputInterface $output): int
276
    {
277 20
        parent::execute($input, $output);
278 20
        $start = new \DateTime();
279 20
        $this->writeLn(sprintf(' Start at %s', $start->format('Y-m-d H:i:s')));
280 20
        $this->initGeneratorOptions();
281 20
        if ($this->canExecute()) {
282 8
            $this->initGenerator()->getGenerator()->generatePackage();
283
        } else {
284 12
            $this->writeLn('  Generation not launched, use "--force" option to force generation');
285 12
            $this->writeLn(sprintf("  Generator's option file used: %s", $this->resolveGeneratorOptionsConfigPath()));
286 12
            $this->writeLn("  Used generator's options:");
287 12
            $this->writeLn('    '.implode(PHP_EOL.'    ', $this->formatArrayForConsole($this->generatorOptions->toArray())));
288
        }
289 14
        $end = new \DateTime();
290 14
        $this->writeLn(sprintf(' End at %s, duration: %s', $end->format('Y-m-d H:i:s'), $start->diff($end)->format('%H:%I:%S')));
291
292 14
        return self::EXIT_OK;
293
    }
294
295 20
    protected function getPackageGenerationCommandLineOptions(): array
296
    {
297 20
        return [
298 20
            'addcomments' => GeneratorOptions::ADD_COMMENTS,
299 20
            'arrays-folder' => GeneratorOptions::ARRAYS_FOLDER,
300 20
            'composer-name' => GeneratorOptions::COMPOSER_NAME,
301 20
            'composer-settings' => GeneratorOptions::COMPOSER_SETTINGS,
302 20
            'category' => GeneratorOptions::CATEGORY,
303 20
            'destination' => GeneratorOptions::DESTINATION,
304 20
            'enums-folder' => GeneratorOptions::ENUMS_FOLDER,
305 20
            'gathermethods' => GeneratorOptions::GATHER_METHODS,
306 20
            'genericconstants' => GeneratorOptions::GENERIC_CONSTANTS_NAME,
307 20
            'gentutorial' => GeneratorOptions::GENERATE_TUTORIAL_FILE,
308 20
            'login' => GeneratorOptions::BASIC_LOGIN,
309 20
            'namespace' => GeneratorOptions::NAMESPACE_PREFIX,
310 20
            'namespace-directories' => GeneratorOptions::NAMESPACE_DICTATES_DIRECTORIES,
311 20
            'password' => GeneratorOptions::BASIC_PASSWORD,
312 20
            'prefix' => GeneratorOptions::PREFIX,
313 20
            'proxy-host' => GeneratorOptions::PROXY_HOST,
314 20
            'proxy-login' => GeneratorOptions::PROXY_LOGIN,
315 20
            'proxy-password' => GeneratorOptions::PROXY_PASSWORD,
316 20
            'proxy-port' => GeneratorOptions::PROXY_PORT,
317 20
            'services-folder' => GeneratorOptions::SERVICES_FOLDER,
318 20
            'src-dirname' => GeneratorOptions::SRC_DIRNAME,
319 20
            'structarray' => GeneratorOptions::STRUCT_ARRAY_CLASS,
320 20
            'structenum' => GeneratorOptions::STRUCT_ENUM_CLASS,
321 20
            'structs-folder' => GeneratorOptions::STRUCTS_FOLDER,
322 20
            'soapclient' => GeneratorOptions::SOAP_CLIENT_CLASS,
323 20
            'struct' => GeneratorOptions::STRUCT_CLASS,
324 20
            'standalone' => GeneratorOptions::STANDALONE,
325 20
            'suffix' => GeneratorOptions::SUFFIX,
326 20
            'urlorpath' => GeneratorOptions::ORIGIN,
327 20
            'validation' => GeneratorOptions::VALIDATION,
328 20
            'xsd-types-path' => GeneratorOptions::XSD_TYPES_PATH,
329 20
        ];
330
    }
331
332 20
    protected function initGeneratorOptions(): self
333
    {
334
        /** @var GeneratorOptions $generatorOptions */
335 20
        $generatorOptions = GeneratorOptions::instance($this->resolveGeneratorOptionsConfigPath());
336
337 20
        foreach ($this->getPackageGenerationCommandLineOptions() as $optionName => $generatorOptionName) {
338 20
            if (is_null($optionValue = $this->formatOptionValue($this->input->getOption($optionName)))) {
339 20
                continue;
340
            }
341 20
            $generatorOptions->setOptionValue($generatorOptionName, $optionValue);
342
        }
343 20
        $this->generatorOptions = $generatorOptions;
344
345 20
        return $this;
346
    }
347
348 20
    protected function formatOptionValue($optionValue)
349
    {
350 20
        if ('true' === $optionValue || (is_numeric($optionValue) && 1 === (int) $optionValue)) {
351
            return true;
352
        }
353 20
        if ('false' === $optionValue || (is_numeric($optionValue) && 0 === (int) $optionValue)) {
354
            return false;
355
        }
356
357 20
        return $optionValue;
358
    }
359
360
    /**
361
     * Utility method to return readable array based on "key: value".
362
     */
363 12
    protected function formatArrayForConsole(array $array): array
364
    {
365 12
        array_walk($array, function (&$value, $index) {
366 12
            $value = sprintf('%s: %s', $index, json_encode($value, JSON_THROW_ON_ERROR));
367 12
        });
368
369 12
        return $array;
370
    }
371
}
372