1 | <?php |
||
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) { |
||
|
|||
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) { |
||
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) { |
||
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) { |
||
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 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
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:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.