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 }