Mercurial > hg > rc1
comparison vendor/pear/console_commandline/Console/CommandLine/XmlParser.php @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e000243b222 |
---|---|
1 <?php | |
2 | |
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ | |
4 | |
5 /** | |
6 * This file is part of the PEAR Console_CommandLine package. | |
7 * | |
8 * PHP version 5 | |
9 * | |
10 * LICENSE: This source file is subject to the MIT license that is available | |
11 * through the world-wide-web at the following URI: | |
12 * http://opensource.org/licenses/mit-license.php | |
13 * | |
14 * @category Console | |
15 * @package Console_CommandLine | |
16 * @author David JEAN LOUIS <izimobil@gmail.com> | |
17 * @copyright 2007 David JEAN LOUIS | |
18 * @license http://opensource.org/licenses/mit-license.php MIT License | |
19 * @version CVS: $Id$ | |
20 * @link http://pear.php.net/package/Console_CommandLine | |
21 * @since File available since release 0.1.0 | |
22 * @filesource | |
23 */ | |
24 | |
25 /** | |
26 * Required file | |
27 */ | |
28 require_once 'Console/CommandLine.php'; | |
29 | |
30 /** | |
31 * Parser for command line xml definitions. | |
32 * | |
33 * @category Console | |
34 * @package Console_CommandLine | |
35 * @author David JEAN LOUIS <izimobil@gmail.com> | |
36 * @copyright 2007 David JEAN LOUIS | |
37 * @license http://opensource.org/licenses/mit-license.php MIT License | |
38 * @version Release: @package_version@ | |
39 * @link http://pear.php.net/package/Console_CommandLine | |
40 * @since Class available since release 0.1.0 | |
41 */ | |
42 class Console_CommandLine_XmlParser | |
43 { | |
44 // parse() {{{ | |
45 | |
46 /** | |
47 * Parses the given xml definition file and returns a | |
48 * Console_CommandLine instance constructed with the xml data. | |
49 * | |
50 * @param string $xmlfile The xml file to parse | |
51 * | |
52 * @return Console_CommandLine A parser instance | |
53 */ | |
54 public static function parse($xmlfile) | |
55 { | |
56 if (!is_readable($xmlfile)) { | |
57 Console_CommandLine::triggerError('invalid_xml_file', | |
58 E_USER_ERROR, array('{$file}' => $xmlfile)); | |
59 } | |
60 $doc = new DomDocument(); | |
61 $doc->load($xmlfile); | |
62 self::validate($doc); | |
63 $nodes = $doc->getElementsByTagName('command'); | |
64 $root = $nodes->item(0); | |
65 return self::_parseCommandNode($root, true); | |
66 } | |
67 | |
68 // }}} | |
69 // parseString() {{{ | |
70 | |
71 /** | |
72 * Parses the given xml definition string and returns a | |
73 * Console_CommandLine instance constructed with the xml data. | |
74 * | |
75 * @param string $xmlstr The xml string to parse | |
76 * | |
77 * @return Console_CommandLine A parser instance | |
78 */ | |
79 public static function parseString($xmlstr) | |
80 { | |
81 $doc = new DomDocument(); | |
82 $doc->loadXml($xmlstr); | |
83 self::validate($doc); | |
84 $nodes = $doc->getElementsByTagName('command'); | |
85 $root = $nodes->item(0); | |
86 return self::_parseCommandNode($root, true); | |
87 } | |
88 | |
89 // }}} | |
90 // validate() {{{ | |
91 | |
92 /** | |
93 * Validates the xml definition using Relax NG. | |
94 * | |
95 * @param DomDocument $doc The document to validate | |
96 * | |
97 * @return boolean Whether the xml data is valid or not. | |
98 * @throws Console_CommandLine_Exception | |
99 * @todo use exceptions | |
100 */ | |
101 public static function validate($doc) | |
102 { | |
103 $pkgRoot = __DIR__ . '/../../'; | |
104 $paths = array( | |
105 // PEAR/Composer | |
106 '@data_dir@/Console_CommandLine/data/xmlschema.rng', | |
107 // Composer | |
108 $pkgRoot . 'data/Console_CommandLine/data/xmlschema.rng', | |
109 $pkgRoot . 'data/console_commandline/data/xmlschema.rng', | |
110 // Git | |
111 $pkgRoot . 'data/xmlschema.rng', | |
112 'xmlschema.rng', | |
113 ); | |
114 | |
115 foreach ($paths as $path) { | |
116 if (is_readable($path)) { | |
117 return $doc->relaxNGValidate($path); | |
118 } | |
119 } | |
120 Console_CommandLine::triggerError( | |
121 'invalid_xml_file', | |
122 E_USER_ERROR, array('{$file}' => $rngfile)); | |
123 } | |
124 | |
125 // }}} | |
126 // _parseCommandNode() {{{ | |
127 | |
128 /** | |
129 * Parses the root command node or a command node and returns the | |
130 * constructed Console_CommandLine or Console_CommandLine_Command instance. | |
131 * | |
132 * @param DomDocumentNode $node The node to parse | |
133 * @param bool $isRootNode Whether it is a root node or not | |
134 * | |
135 * @return mixed Console_CommandLine or Console_CommandLine_Command | |
136 */ | |
137 private static function _parseCommandNode($node, $isRootNode = false) | |
138 { | |
139 if ($isRootNode) { | |
140 $obj = new Console_CommandLine(); | |
141 } else { | |
142 include_once 'Console/CommandLine/Command.php'; | |
143 $obj = new Console_CommandLine_Command(); | |
144 } | |
145 foreach ($node->childNodes as $cNode) { | |
146 $cNodeName = $cNode->nodeName; | |
147 switch ($cNodeName) { | |
148 case 'name': | |
149 case 'description': | |
150 case 'version': | |
151 $obj->$cNodeName = trim($cNode->nodeValue); | |
152 break; | |
153 case 'add_help_option': | |
154 case 'add_version_option': | |
155 case 'force_posix': | |
156 $obj->$cNodeName = self::_bool(trim($cNode->nodeValue)); | |
157 break; | |
158 case 'option': | |
159 $obj->addOption(self::_parseOptionNode($cNode)); | |
160 break; | |
161 case 'argument': | |
162 $obj->addArgument(self::_parseArgumentNode($cNode)); | |
163 break; | |
164 case 'command': | |
165 $obj->addCommand(self::_parseCommandNode($cNode)); | |
166 break; | |
167 case 'aliases': | |
168 if (!$isRootNode) { | |
169 foreach ($cNode->childNodes as $subChildNode) { | |
170 if ($subChildNode->nodeName == 'alias') { | |
171 $obj->aliases[] = trim($subChildNode->nodeValue); | |
172 } | |
173 } | |
174 } | |
175 break; | |
176 case 'messages': | |
177 $obj->messages = self::_messages($cNode); | |
178 break; | |
179 default: | |
180 break; | |
181 } | |
182 } | |
183 return $obj; | |
184 } | |
185 | |
186 // }}} | |
187 // _parseOptionNode() {{{ | |
188 | |
189 /** | |
190 * Parses an option node and returns the constructed | |
191 * Console_CommandLine_Option instance. | |
192 * | |
193 * @param DomDocumentNode $node The node to parse | |
194 * | |
195 * @return Console_CommandLine_Option The built option | |
196 */ | |
197 private static function _parseOptionNode($node) | |
198 { | |
199 include_once 'Console/CommandLine/Option.php'; | |
200 $obj = new Console_CommandLine_Option($node->getAttribute('name')); | |
201 foreach ($node->childNodes as $cNode) { | |
202 $cNodeName = $cNode->nodeName; | |
203 switch ($cNodeName) { | |
204 case 'choices': | |
205 foreach ($cNode->childNodes as $subChildNode) { | |
206 if ($subChildNode->nodeName == 'choice') { | |
207 $obj->choices[] = trim($subChildNode->nodeValue); | |
208 } | |
209 } | |
210 break; | |
211 case 'messages': | |
212 $obj->messages = self::_messages($cNode); | |
213 break; | |
214 default: | |
215 if (property_exists($obj, $cNodeName)) { | |
216 $obj->$cNodeName = trim($cNode->nodeValue); | |
217 } | |
218 break; | |
219 } | |
220 } | |
221 if ($obj->action == 'Password') { | |
222 $obj->argument_optional = true; | |
223 } | |
224 return $obj; | |
225 } | |
226 | |
227 // }}} | |
228 // _parseArgumentNode() {{{ | |
229 | |
230 /** | |
231 * Parses an argument node and returns the constructed | |
232 * Console_CommandLine_Argument instance. | |
233 * | |
234 * @param DomDocumentNode $node The node to parse | |
235 * | |
236 * @return Console_CommandLine_Argument The built argument | |
237 */ | |
238 private static function _parseArgumentNode($node) | |
239 { | |
240 include_once 'Console/CommandLine/Argument.php'; | |
241 $obj = new Console_CommandLine_Argument($node->getAttribute('name')); | |
242 foreach ($node->childNodes as $cNode) { | |
243 $cNodeName = $cNode->nodeName; | |
244 switch ($cNodeName) { | |
245 case 'description': | |
246 case 'help_name': | |
247 case 'default': | |
248 $obj->$cNodeName = trim($cNode->nodeValue); | |
249 break; | |
250 case 'multiple': | |
251 $obj->multiple = self::_bool(trim($cNode->nodeValue)); | |
252 break; | |
253 case 'optional': | |
254 $obj->optional = self::_bool(trim($cNode->nodeValue)); | |
255 break; | |
256 case 'choices': | |
257 foreach ($cNode->childNodes as $subChildNode) { | |
258 if ($subChildNode->nodeName == 'choice') { | |
259 $obj->choices[] = trim($subChildNode->nodeValue); | |
260 } | |
261 } | |
262 break; | |
263 case 'messages': | |
264 $obj->messages = self::_messages($cNode); | |
265 break; | |
266 default: | |
267 break; | |
268 } | |
269 } | |
270 return $obj; | |
271 } | |
272 | |
273 // }}} | |
274 // _bool() {{{ | |
275 | |
276 /** | |
277 * Returns a boolean according to true/false possible strings. | |
278 * | |
279 * @param string $str The string to process | |
280 * | |
281 * @return boolean | |
282 */ | |
283 private static function _bool($str) | |
284 { | |
285 return in_array(strtolower((string)$str), array('true', '1', 'on', 'yes')); | |
286 } | |
287 | |
288 // }}} | |
289 // _messages() {{{ | |
290 | |
291 /** | |
292 * Returns an array of custom messages for the element | |
293 * | |
294 * @param DOMNode $node The messages node to process | |
295 * | |
296 * @return array an array of messages | |
297 * | |
298 * @see Console_CommandLine::$messages | |
299 * @see Console_CommandLine_Element::$messages | |
300 */ | |
301 private static function _messages(DOMNode $node) | |
302 { | |
303 $messages = array(); | |
304 | |
305 foreach ($node->childNodes as $cNode) { | |
306 if ($cNode->nodeType == XML_ELEMENT_NODE) { | |
307 $name = $cNode->getAttribute('name'); | |
308 $value = trim($cNode->nodeValue); | |
309 | |
310 $messages[$name] = $value; | |
311 } | |
312 } | |
313 | |
314 return $messages; | |
315 } | |
316 | |
317 // }}} | |
318 } |