PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/pear/php/PEAR/Command.php

https://github.com/hnw/phpbugs
PHP | 416 lines | 302 code | 8 blank | 106 comment | 5 complexity | 7147a5789e7f15c85f3b23d4ffb6b236 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * PEAR_Command, command pattern class
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * LICENSE: This source file is subject to version 3.0 of the PHP license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  10. * the PHP License and are unable to obtain it through the web, please
  11. * send a note to license@php.net so we can mail you a copy immediately.
  12. *
  13. * @category pear
  14. * @package PEAR
  15. * @author Stig Bakken <ssb@php.net>
  16. * @author Greg Beaver <cellog@php.net>
  17. * @copyright 1997-2008 The PHP Group
  18. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  19. * @version CVS: $Id: Command.php,v 1.39 2008/01/03 20:26:34 cellog Exp $
  20. * @link http://pear.php.net/package/PEAR
  21. * @since File available since Release 0.1
  22. */
  23. /**
  24. * Needed for error handling
  25. */
  26. require_once 'PEAR.php';
  27. require_once 'PEAR/Frontend.php';
  28. require_once 'PEAR/XMLParser.php';
  29. /**
  30. * List of commands and what classes they are implemented in.
  31. * @var array command => implementing class
  32. */
  33. $GLOBALS['_PEAR_Command_commandlist'] = array();
  34. /**
  35. * List of commands and their descriptions
  36. * @var array command => description
  37. */
  38. $GLOBALS['_PEAR_Command_commanddesc'] = array();
  39. /**
  40. * List of shortcuts to common commands.
  41. * @var array shortcut => command
  42. */
  43. $GLOBALS['_PEAR_Command_shortcuts'] = array();
  44. /**
  45. * Array of command objects
  46. * @var array class => object
  47. */
  48. $GLOBALS['_PEAR_Command_objects'] = array();
  49. /**
  50. * PEAR command class, a simple factory class for administrative
  51. * commands.
  52. *
  53. * How to implement command classes:
  54. *
  55. * - The class must be called PEAR_Command_Nnn, installed in the
  56. * "PEAR/Common" subdir, with a method called getCommands() that
  57. * returns an array of the commands implemented by the class (see
  58. * PEAR/Command/Install.php for an example).
  59. *
  60. * - The class must implement a run() function that is called with three
  61. * params:
  62. *
  63. * (string) command name
  64. * (array) assoc array with options, freely defined by each
  65. * command, for example:
  66. * array('force' => true)
  67. * (array) list of the other parameters
  68. *
  69. * The run() function returns a PEAR_CommandResponse object. Use
  70. * these methods to get information:
  71. *
  72. * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
  73. * *_PARTIAL means that you need to issue at least
  74. * one more command to complete the operation
  75. * (used for example for validation steps).
  76. *
  77. * string getMessage() Returns a message for the user. Remember,
  78. * no HTML or other interface-specific markup.
  79. *
  80. * If something unexpected happens, run() returns a PEAR error.
  81. *
  82. * - DON'T OUTPUT ANYTHING! Return text for output instead.
  83. *
  84. * - DON'T USE HTML! The text you return will be used from both Gtk,
  85. * web and command-line interfaces, so for now, keep everything to
  86. * plain text.
  87. *
  88. * - DON'T USE EXIT OR DIE! Always use pear errors. From static
  89. * classes do PEAR::raiseError(), from other classes do
  90. * $this->raiseError().
  91. * @category pear
  92. * @package PEAR
  93. * @author Stig Bakken <ssb@php.net>
  94. * @author Greg Beaver <cellog@php.net>
  95. * @copyright 1997-2008 The PHP Group
  96. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  97. * @version Release: 1.7.2
  98. * @link http://pear.php.net/package/PEAR
  99. * @since Class available since Release 0.1
  100. */
  101. class PEAR_Command
  102. {
  103. // {{{ factory()
  104. /**
  105. * Get the right object for executing a command.
  106. *
  107. * @param string $command The name of the command
  108. * @param object $config Instance of PEAR_Config object
  109. *
  110. * @return object the command object or a PEAR error
  111. *
  112. * @access public
  113. * @static
  114. */
  115. function &factory($command, &$config)
  116. {
  117. if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  118. PEAR_Command::registerCommands();
  119. }
  120. if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
  121. $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
  122. }
  123. if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
  124. $a = PEAR::raiseError("unknown command `$command'");
  125. return $a;
  126. }
  127. $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
  128. if (!class_exists($class)) {
  129. require_once $GLOBALS['_PEAR_Command_objects'][$class];
  130. }
  131. if (!class_exists($class)) {
  132. $a = PEAR::raiseError("unknown command `$command'");
  133. return $a;
  134. }
  135. $ui =& PEAR_Command::getFrontendObject();
  136. $obj = &new $class($ui, $config);
  137. return $obj;
  138. }
  139. // }}}
  140. // {{{ & getObject()
  141. function &getObject($command)
  142. {
  143. $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
  144. if (!class_exists($class)) {
  145. require_once $GLOBALS['_PEAR_Command_objects'][$class];
  146. }
  147. if (!class_exists($class)) {
  148. return PEAR::raiseError("unknown command `$command'");
  149. }
  150. $ui =& PEAR_Command::getFrontendObject();
  151. $config = &PEAR_Config::singleton();
  152. $obj = &new $class($ui, $config);
  153. return $obj;
  154. }
  155. // }}}
  156. // {{{ & getFrontendObject()
  157. /**
  158. * Get instance of frontend object.
  159. *
  160. * @return object|PEAR_Error
  161. * @static
  162. */
  163. function &getFrontendObject()
  164. {
  165. $a = &PEAR_Frontend::singleton();
  166. return $a;
  167. }
  168. // }}}
  169. // {{{ & setFrontendClass()
  170. /**
  171. * Load current frontend class.
  172. *
  173. * @param string $uiclass Name of class implementing the frontend
  174. *
  175. * @return object the frontend object, or a PEAR error
  176. * @static
  177. */
  178. function &setFrontendClass($uiclass)
  179. {
  180. $a = &PEAR_Frontend::setFrontendClass($uiclass);
  181. return $a;
  182. }
  183. // }}}
  184. // {{{ setFrontendType()
  185. /**
  186. * Set current frontend.
  187. *
  188. * @param string $uitype Name of the frontend type (for example "CLI")
  189. *
  190. * @return object the frontend object, or a PEAR error
  191. * @static
  192. */
  193. function setFrontendType($uitype)
  194. {
  195. $uiclass = 'PEAR_Frontend_' . $uitype;
  196. return PEAR_Command::setFrontendClass($uiclass);
  197. }
  198. // }}}
  199. // {{{ registerCommands()
  200. /**
  201. * Scan through the Command directory looking for classes
  202. * and see what commands they implement.
  203. *
  204. * @param bool (optional) if FALSE (default), the new list of
  205. * commands should replace the current one. If TRUE,
  206. * new entries will be merged with old.
  207. *
  208. * @param string (optional) where (what directory) to look for
  209. * classes, defaults to the Command subdirectory of
  210. * the directory from where this file (__FILE__) is
  211. * included.
  212. *
  213. * @return bool TRUE on success, a PEAR error on failure
  214. *
  215. * @access public
  216. * @static
  217. */
  218. function registerCommands($merge = false, $dir = null)
  219. {
  220. $parser = new PEAR_XMLParser;
  221. if ($dir === null) {
  222. $dir = dirname(__FILE__) . '/Command';
  223. }
  224. if (!is_dir($dir)) {
  225. return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
  226. }
  227. $dp = @opendir($dir);
  228. if (empty($dp)) {
  229. return PEAR::raiseError("registerCommands: opendir($dir) failed");
  230. }
  231. if (!$merge) {
  232. $GLOBALS['_PEAR_Command_commandlist'] = array();
  233. }
  234. while ($entry = readdir($dp)) {
  235. if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
  236. continue;
  237. }
  238. $class = "PEAR_Command_".substr($entry, 0, -4);
  239. $file = "$dir/$entry";
  240. $parser->parse(file_get_contents($file));
  241. $implements = $parser->getData();
  242. // List of commands
  243. if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
  244. $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) .
  245. '.php';
  246. }
  247. foreach ($implements as $command => $desc) {
  248. if ($command == 'attribs') {
  249. continue;
  250. }
  251. if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
  252. return PEAR::raiseError('Command "' . $command . '" already registered in ' .
  253. 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
  254. }
  255. $GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
  256. $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
  257. if (isset($desc['shortcut'])) {
  258. $shortcut = $desc['shortcut'];
  259. if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
  260. return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
  261. 'registered to command "' . $command . '" in class "' .
  262. $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
  263. }
  264. $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
  265. }
  266. if (isset($desc['options']) && $desc['options']) {
  267. foreach ($desc['options'] as $oname => $option) {
  268. if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
  269. return PEAR::raiseError('Option "' . $oname . '" short option "' .
  270. $option['shortopt'] . '" must be ' .
  271. 'only 1 character in Command "' . $command . '" in class "' .
  272. $class . '"');
  273. }
  274. }
  275. }
  276. }
  277. }
  278. ksort($GLOBALS['_PEAR_Command_shortcuts']);
  279. ksort($GLOBALS['_PEAR_Command_commandlist']);
  280. @closedir($dp);
  281. return true;
  282. }
  283. // }}}
  284. // {{{ getCommands()
  285. /**
  286. * Get the list of currently supported commands, and what
  287. * classes implement them.
  288. *
  289. * @return array command => implementing class
  290. *
  291. * @access public
  292. * @static
  293. */
  294. function getCommands()
  295. {
  296. if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  297. PEAR_Command::registerCommands();
  298. }
  299. return $GLOBALS['_PEAR_Command_commandlist'];
  300. }
  301. // }}}
  302. // {{{ getShortcuts()
  303. /**
  304. * Get the list of command shortcuts.
  305. *
  306. * @return array shortcut => command
  307. *
  308. * @access public
  309. * @static
  310. */
  311. function getShortcuts()
  312. {
  313. if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
  314. PEAR_Command::registerCommands();
  315. }
  316. return $GLOBALS['_PEAR_Command_shortcuts'];
  317. }
  318. // }}}
  319. // {{{ getGetoptArgs()
  320. /**
  321. * Compiles arguments for getopt.
  322. *
  323. * @param string $command command to get optstring for
  324. * @param string $short_args (reference) short getopt format
  325. * @param array $long_args (reference) long getopt format
  326. *
  327. * @return void
  328. *
  329. * @access public
  330. * @static
  331. */
  332. function getGetoptArgs($command, &$short_args, &$long_args)
  333. {
  334. if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  335. PEAR_Command::registerCommands();
  336. }
  337. if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
  338. $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
  339. }
  340. if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
  341. return null;
  342. }
  343. $obj = &PEAR_Command::getObject($command);
  344. return $obj->getGetoptArgs($command, $short_args, $long_args);
  345. }
  346. // }}}
  347. // {{{ getDescription()
  348. /**
  349. * Get description for a command.
  350. *
  351. * @param string $command Name of the command
  352. *
  353. * @return string command description
  354. *
  355. * @access public
  356. * @static
  357. */
  358. function getDescription($command)
  359. {
  360. if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
  361. return null;
  362. }
  363. return $GLOBALS['_PEAR_Command_commanddesc'][$command];
  364. }
  365. // }}}
  366. // {{{ getHelp()
  367. /**
  368. * Get help for command.
  369. *
  370. * @param string $command Name of the command to return help for
  371. *
  372. * @access public
  373. * @static
  374. */
  375. function getHelp($command)
  376. {
  377. $cmds = PEAR_Command::getCommands();
  378. if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
  379. $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
  380. }
  381. if (isset($cmds[$command])) {
  382. $obj = &PEAR_Command::getObject($command);
  383. return $obj->getHelp($command);
  384. }
  385. return false;
  386. }
  387. // }}}
  388. }
  389. ?>