PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ezc/ConsoleTools/src/input/help_generators/standard.php

https://bitbucket.org/crevillo/enetcall
PHP | 391 lines | 180 code | 17 blank | 194 comment | 26 complexity | 203af9f5bd5b09d9707d5955b0197db0 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * File containing the ezcConsoleInputStandardHelpGenerator class.
  4. *
  5. * @package ConsoleTools
  6. * @version //autogentag//
  7. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. * @filesource
  10. */
  11. /**
  12. * Standard help generator for {@link ezcConsoleInput}.
  13. *
  14. * Standard help generation as {@link ezcConsoleInput} did from the start.
  15. *
  16. * @package ConsoleTools
  17. * @version //autogen//
  18. *
  19. * @access private
  20. * @TODO Verify interface and make it public to replace the validation in
  21. * {@link ezcConsoleInput}.
  22. */
  23. class ezcConsoleInputStandardHelpGenerator implements ezcConsoleInputHelpGenerator
  24. {
  25. /**
  26. * Input object.
  27. *
  28. * @var ezcConsoleInput
  29. */
  30. private $input;
  31. /**
  32. * Creates a new help generator.
  33. *
  34. * Creates a new help generator for the given $input.
  35. *
  36. * @param ezcConsoleInput $input
  37. */
  38. public function __construct( ezcConsoleInput $input )
  39. {
  40. $this->input = $input;
  41. }
  42. /**
  43. * Generates help information as a multidimensional array.
  44. *
  45. * This method generates a tabular view on the help information of a
  46. * program. The returned array has the following structure:
  47. *
  48. * <code>
  49. * <?php
  50. * array(
  51. * 0 => array(
  52. * 0 => '<option short/long name>',
  53. * 1 => '<option help, depending on the $long parameter>'
  54. * ),
  55. * 1 => array(
  56. * 0 => '<option short name> / <option long name>',
  57. * 1 => '<option help, depending on the $long parameter>'
  58. * ),
  59. * // ...
  60. * );
  61. * ?>
  62. * </code>
  63. *
  64. * Each row of the array represents the help information for a single option.
  65. * The first cell of a row contains the option name (maybe short, long or
  66. * both), the second cell contains the help text of the option.
  67. *
  68. * The returned array is used by {@link ezcConsoleInput} for different
  69. * purposes.
  70. * For example, the user can retrieve it raw through the
  71. * {@link ezcConsoleInput::getHelp()} method, he can generate a help
  72. * {@link ezcConsoleTable} through {@link ezcConsoleInput::getHelpTable()}
  73. * are can generate a printable help text through {@link
  74. * ezcConsoleInput::getHelpText()}.
  75. *
  76. * The parameter $long defines if the long or short help text of the
  77. * options should be used in the second cell of the returned array. The
  78. * $optionsFilter parameter is used to restrict the generated help to a certain
  79. * sub-set of options. It consists of an array of short or long names of
  80. * the options to include.
  81. *
  82. * @param bool $long
  83. * @param array(string) $optionsFilter
  84. * @return array(array(string))
  85. */
  86. public function generateUngroupedOptionHelp( $long = false, array $optionsFilter = null )
  87. {
  88. $help = array();
  89. foreach ( $this->input->getOptions() as $id => $param )
  90. {
  91. if ( $optionsFilter === null || in_array( $param->short, $optionsFilter ) || in_array( $param->long, $optionsFilter ) )
  92. {
  93. $help[] = $this->getOptionHelpRow( $long, $param );
  94. }
  95. }
  96. return $help;
  97. }
  98. /**
  99. * Generates help information as a multidimensional array, grouped in categories.
  100. *
  101. * This method behaves similar to {@link generateUngroupedOptionHelp()}. In
  102. * contrast to the latter one, this method returns an array with 1
  103. * dimension more, grouping options into categories. The $groups parameter
  104. * defines the categories to generate. Each category may contain an
  105. * arbitrary number of options, options might occur in different
  106. * categories.
  107. *
  108. * The returned array has the follorwing format:
  109. *
  110. * <code>
  111. * <?php
  112. * array(
  113. * '<category name>' => array(
  114. * 0 => array(
  115. * 0 => '<option short/long name>',
  116. * 1 => '<option help, depending on the $long parameter>'
  117. * ),
  118. * 1 => array(
  119. * 0 => '<option short name> / <option long name>',
  120. * 1 => '<option help, depending on the $long parameter>'
  121. * ),
  122. * // ...
  123. * ),
  124. * '<category name>' => array(
  125. * // ...
  126. * ),
  127. * // ...
  128. * );
  129. * ?>
  130. * </code>
  131. *
  132. * The $long parameter, as in {@link generateUngroupedOptionHelp()}
  133. * determines if the options short or long help is to be used. The
  134. * $params array can in addition be used to determine if a parameter
  135. * is displayed at all. If $optionsFilter is submitted and is not null,
  136. * only options listed in it will be shown in the help at all.
  137. *
  138. * @param array(string=>array(string)) $groups
  139. * @param bool $long
  140. * @param array(string) $params
  141. * @return array(string=>array(array(string)))
  142. */
  143. public function generateGroupedOptionHelp( array $groups, $long = false, array $optionsFilter = null )
  144. {
  145. $help = array();
  146. foreach ( $groups as $groupName => $groupOptions )
  147. {
  148. foreach ( $groupOptions as $optionName )
  149. {
  150. $option = $this->input->getOption( $optionName );
  151. if ( $optionsFilter === null || in_array( $option->short, $optionsFilter ) || in_array( $option->long, $optionsFilter ) )
  152. {
  153. $help[$groupName][] = $this->getOptionHelpRow(
  154. $long,
  155. $option
  156. );
  157. }
  158. }
  159. }
  160. return $help;
  161. }
  162. /**
  163. * Generates help information as a multi-dimensonal array for the given $argumentDefinition.
  164. *
  165. * This method generates a tabular help information for the given
  166. * $argumentDefinition in the following format:
  167. *
  168. * <code>
  169. * <?php
  170. * array(
  171. * 0 => array(
  172. * 0 => '<argument synopsis>',
  173. * 1 => '<argument help text>'
  174. * ),
  175. * 1 => array(
  176. * 0 => '<argument synopsis>',
  177. * 1 => '<argument help text>'
  178. * ),
  179. * // ...
  180. * )
  181. * ?>
  182. * </code>
  183. *
  184. * The $long parameter defines if the long of short help text should be
  185. * used.
  186. *
  187. * @param bool $long
  188. * @return array(array(string))
  189. */
  190. public function generateArgumentHelp( $long = false )
  191. {
  192. $help = array();
  193. if ( $this->input->argumentDefinition !== null )
  194. {
  195. foreach ( $this->input->argumentDefinition as $arg )
  196. {
  197. $argSynopsis = "<%s:%s>";
  198. switch ( $arg->type )
  199. {
  200. case ezcConsoleInput::TYPE_INT:
  201. $type = "int";
  202. break;
  203. case ezcConsoleInput::TYPE_STRING:
  204. $type = "string";
  205. break;
  206. }
  207. $argSynopsis = sprintf( $argSynopsis, $type, $arg->name );
  208. $help[] = ( $long === true )
  209. ? array(
  210. $argSynopsis,
  211. $arg->longhelp . ( $arg->mandatory === false
  212. ? ' (optional' . ( $arg->default !== null
  213. ? ', default = ' . ( is_array( $arg->default )
  214. ? "'" . implode( "' '", $arg->default ) . "'"
  215. : "'$arg->default'"
  216. )
  217. : ''
  218. ) . ')'
  219. : ''
  220. )
  221. )
  222. : array( $argSynopsis, $arg->shorthelp );
  223. }
  224. }
  225. return $help;
  226. }
  227. /**
  228. * Creates 1 text row for displaying options help.
  229. *
  230. * Returns a single array entry for the {@link getOptionHelpRow()} method.
  231. *
  232. * @param bool $long
  233. * @param ezcConsoleOption $param
  234. * @return string
  235. */
  236. private function getOptionHelpRow( $long, ezcConsoleOption $param )
  237. {
  238. return array(
  239. ( $param->short !== "" ? '-' . $param->short . ' / ' : "" ) . '--' . $param->long,
  240. $long == false ? $param->shorthelp : $param->longhelp,
  241. );
  242. }
  243. /**
  244. * Generates a command line synopsis for the options and arguments.
  245. *
  246. * This method generates a synopsis string that lists the options and
  247. * parameters available, indicating their usage. If $optionsFilter is
  248. * submitted, only the options named in this array (short or long variant)
  249. * will be included in the synopsis.
  250. *
  251. * @param array(string) $optionsFilter
  252. * @return string
  253. */
  254. public function generateSynopsis( array $optionFilter = null )
  255. {
  256. $usedOptions = array( 'short' => array(), 'long' => array() );
  257. $allowsArgs = true;
  258. $synopsis = '$ ' . ( isset( $argv ) && sizeof( $argv ) > 0 ? $argv[0] : $_SERVER['argv'][0] ) . ' ';
  259. foreach ( $this->input->getOptions() as $option )
  260. {
  261. if ( $optionFilter === null || in_array( $option->short, $optionFilter ) || in_array( $option->long, $optionFilter ) )
  262. {
  263. $synopsis .= $this->createOptionSynopsis( $option, $usedOptions, $allowsArgs );
  264. }
  265. }
  266. if ( $this->input->argumentDefinition === null )
  267. {
  268. // Old handling
  269. $synopsis .= " [[--] <args>]";
  270. }
  271. else
  272. {
  273. $synopsis .= "[--] " . $this->createArgumentsSynopsis();
  274. }
  275. return $synopsis;
  276. }
  277. /**
  278. * Returns the synopsis string for a single option and its dependencies.
  279. *
  280. * This method returns a part of the program synopsis, specifically for a
  281. * certain parameter. The method recursively adds depending parameters up
  282. * to the 2nd depth level to the synopsis. The second parameter is used
  283. * to store the short names of all options that have already been used in
  284. * the synopsis (to avoid adding an option twice). The 3rd parameter
  285. * determines the actual deps in the option dependency recursion to
  286. * terminate that after 2 recursions.
  287. *
  288. * @param ezcConsoleOption $option The option to include.
  289. * @param array(string) $usedOptions Array of used option short names.
  290. * @param int $depth Current recursion depth.
  291. * @return string The synopsis for this parameter.
  292. */
  293. private function createOptionSynopsis( ezcConsoleOption $option, &$usedOptions, $depth = 0 )
  294. {
  295. $synopsis = '';
  296. // Break after a nesting level of 2
  297. if ( $depth++ > 2 || ( in_array( $option->short, $usedOptions['short'] ) && in_array( $option->long, $usedOptions['long'] ) ) ) return $synopsis;
  298. $usedOptions['short'][] = $option->short;
  299. $usedOptions['long'][] = $option->long;
  300. $synopsis .= $option->short !== "" ? "-{$option->short}" : "--{$option->long}";
  301. if ( isset( $option->default ) )
  302. {
  303. $synopsis .= " " . ( $option->type === ezcConsoleInput::TYPE_STRING ? '"' : '' ) . $option->default . ( $option->type === ezcConsoleInput::TYPE_STRING ? '"' : '' );
  304. }
  305. else if ( $option->type !== ezcConsoleInput::TYPE_NONE )
  306. {
  307. $synopsis .= " ";
  308. switch ( $option->type )
  309. {
  310. case ezcConsoleInput::TYPE_STRING:
  311. $synopsis .= "<string>";
  312. break;
  313. case ezcConsoleInput::TYPE_INT:
  314. $synopsis .= "<int>";
  315. break;
  316. }
  317. }
  318. foreach ( $option->getDependencies() as $rule )
  319. {
  320. $deeperSynopsis = $this->createOptionSynopsis( $rule->option, $usedOptions, $depth );
  321. $synopsis .= ( iconv_strlen( trim( $deeperSynopsis ), 'UTF-8' ) > 0
  322. ? ' ' . $deeperSynopsis
  323. : ''
  324. );
  325. }
  326. if ( $option->arguments === false )
  327. {
  328. $allowsArgs = false;
  329. }
  330. // Make the whole thing optional?
  331. if ( $option->mandatory === false )
  332. {
  333. $synopsis = "[$synopsis]";
  334. }
  335. return $synopsis . ' ';
  336. }
  337. /**
  338. * Generate synopsis for arguments.
  339. *
  340. * @return string The synopsis string.
  341. */
  342. private function createArgumentsSynopsis()
  343. {
  344. $mandatory = true;
  345. $synopsises = array();
  346. foreach ( $this->input->argumentDefinition as $arg )
  347. {
  348. $argSynopsis = "";
  349. if ( $arg->mandatory === false )
  350. {
  351. $mandatory = false;
  352. }
  353. $argSynopsis .= "<%s:%s>";
  354. switch ( $arg->type )
  355. {
  356. case ezcConsoleInput::TYPE_INT:
  357. $type = "int";
  358. break;
  359. case ezcConsoleInput::TYPE_STRING:
  360. $type = "string";
  361. break;
  362. }
  363. $argSynopsis = sprintf( $argSynopsis, $type, $arg->name );
  364. $synopsises[] = $mandatory === false ? "[$argSynopsis]" : $argSynopsis;
  365. if ( $arg->multiple === true )
  366. {
  367. $synopsises[] = "[$argSynopsis ...]";
  368. break;
  369. }
  370. }
  371. return implode( " ", $synopsises );
  372. }
  373. }
  374. ?>