AbstractConvert::convert()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
1
<?php
2
namespace Goetas\Xsd\XsdToPhp\Command;
3
4
use Exception;
5
use Goetas\Xsd\XsdToPhp\AbstractConverter;
6
use Goetas\Xsd\XsdToPhp\Naming\LongNamingStrategy;
7
use Goetas\Xsd\XsdToPhp\Naming\NamingStrategy;
8
use Goetas\Xsd\XsdToPhp\Naming\ShortNamingStrategy;
9
use GoetasWebservices\XML\XSDReader\SchemaReader;
10
use Symfony\Component\Console;
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
abstract class AbstractConvert extends Console\Command\Command
16
{
17
18
    /**
19
     *
20
     * @see Console\Command\Command
21
     */
22
    protected function configure()
23
    {
24
        $this->setDefinition(array(
25
            new InputArgument('src', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Where is located your XSD definitions'),
26
            new InputOption('ns-map', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'How to map XML namespaces to PHP namespaces? Syntax: <info>XML-namespace;PHP-namespace</info>'),
27
            new InputOption('ns-dest', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Where place the generated files? Syntax: <info>PHP-namespace;destination-directory</info>'),
28
            new InputOption('alias-map', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'How to map XML namespaces into existing PHP classes? Syntax: <info>XML-namespace;XML-type;PHP-type</info>. '),
29
            new InputOption('naming-strategy', null, InputOption::VALUE_REQUIRED, 'The naming strategy for classes. short|long', 'short')
30
        ));
31
    }
32
33
    /**
34
     */
35
    protected abstract function getConverterter(NamingStrategy $naming);
36
37
    /**
38
     *
39
     * @see Console\Command\Command
40
     */
41
    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
42
    {
43
        $src = $input->getArgument('src');
44
45
        $nsMap = $input->getOption('ns-map');
46
        if (!$nsMap) {
47
            throw new \RuntimeException(__CLASS__ . " requires at least one ns-map.");
48
        }
49
50
        $nsTarget = $input->getOption('ns-dest');
51
        if (!$nsTarget) {
52
            throw new \RuntimeException(__CLASS__ . " requires at least one ns-target.");
53
        }
54
55
        if ($input->getOption('naming-strategy') == 'short') {
56
            $naming = new ShortNamingStrategy();
57
        } elseif ($input->getOption('naming-strategy') == 'long') {
58
            $naming = new LongNamingStrategy();
59
        } else {
60
            throw new \InvalidArgumentException("Unsupported naming strategy");
61
        }
62
63
        $converter = $this->getConverterter($naming);
64
65
        $nsMapKeyed = array();
66
        $output->writeln("Namespaces:");
67
        foreach ($nsMap as $val) {
0 ignored issues
show
Bug introduced by
The expression $nsMap of type string|array<integer,string>|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
68
            if (substr_count($val, ';') !== 1) {
69
                throw new Exception("Invalid syntax for --ns-map");
70
            }
71
            list ($xmlNs, $phpNs) = explode(";", $val, 2);
72
            $nsMapKeyed[$xmlNs] = $phpNs;
73
            $converter->addNamespace($xmlNs, trim(strtr($phpNs, "./", "\\\\"), "\\"));
74
            $output->writeln("\tXML namepsace: <comment>$xmlNs</comment> => PHP namepsace: <info>$phpNs</info>");
75
        }
76
        $targets = array();
77
        $output->writeln("Target directories:");
78
        foreach ($nsTarget as $val) {
0 ignored issues
show
Bug introduced by
The expression $nsTarget of type string|array<integer,string>|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
79
            if (substr_count($val, ';') !== 1) {
80
                throw new Exception("Invalid syntax for --ns-dest");
81
            }
82
            list ($phpNs, $dir) = explode(";", $val, 2);
83
            $phpNs = strtr($phpNs, "./", "\\\\");
84
85
            $targets[$phpNs] = $dir;
86
            $output->writeln("\tPHP namepsace: <comment>" . strtr($phpNs, "\\", "/") . "</comment> => Destination directory: <info>$dir</info>");
87
        }
88
        $arrayMap = $input->getOption('alias-map');
89
        if ($arrayMap) {
90
            $output->writeln("Aliases:");
91
            foreach ($arrayMap as $val) {
0 ignored issues
show
Bug introduced by
The expression $arrayMap of type string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
92
                if (substr_count($val, ';') !== 2) {
93
                    throw new Exception("Invalid syntax for --alias-map");
94
                }
95
                list ($xmlNs, $name, $type) = explode(";", $val, 3);
96
                $converter->addAliasMapType($xmlNs, $name, $type);
97
                $output->writeln("\tXML Type: <comment>$xmlNs</comment>#<comment>$name</comment>  => PHP Class: <info>$type</info> ");
98
            }
99
        }
100
        $reader = new SchemaReader();
101
        $schemas = array();
102
        foreach ($src as $file) {
0 ignored issues
show
Bug introduced by
The expression $src of type string|array<integer,string>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
103
            $output->writeln("Reading <comment>$file</comment>");
104
105
            $xml = new \DOMDocument('1.0', 'UTF-8');
106
            if (!$xml->load($file)) {
107
                throw new \Exception("Can't load the schema '{$file}'");
108
            }
109
110
            if (!isset($nsMapKeyed[$xml->documentElement->getAttribute("targetNamespace")])) {
111
                $output->writeln("\tSkipping <comment>" . $xml->documentElement->getAttribute("targetNamespace") . "</comment>, can't find a PHP-equivalent namespace. Use --ns-map option?");
112
                continue;
113
            }
114
115
            $schema = $reader->readFile($file);
116
117
            $schemas[spl_object_hash($schema)] = $schema;
118
        }
119
120
        $this->convert($converter, $schemas, $targets, $output);
121
122
        return 0;
123
    }
124
125
    protected abstract function convert(AbstractConverter $converter, array $schemas, array $targets, OutputInterface $output);
126
}
127