HelpFormatter.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /**
  3. * HelpFormatter
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * For full copyright and license information, please see the LICENSE.txt
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://cakephp.org CakePHP(tm) Project
  16. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  17. */
  18. App::uses('String', 'Utility');
  19. /**
  20. * HelpFormatter formats help for console shells. Can format to either
  21. * text or XML formats. Uses ConsoleOptionParser methods to generate help.
  22. *
  23. * Generally not directly used. Using $parser->help($command, 'xml'); is usually
  24. * how you would access help. Or via the `--help=xml` option on the command line.
  25. *
  26. * Xml output is useful for integration with other tools like IDE's or other build tools.
  27. *
  28. * @package Cake.Console
  29. * @since CakePHP(tm) v 2.0
  30. */
  31. class HelpFormatter {
  32. /**
  33. * The maximum number of arguments shown when generating usage.
  34. *
  35. * @var integer
  36. */
  37. protected $_maxArgs = 6;
  38. /**
  39. * The maximum number of options shown when generating usage.
  40. *
  41. * @var integer
  42. */
  43. protected $_maxOptions = 6;
  44. /**
  45. * Build the help formatter for a an OptionParser
  46. *
  47. * @param ConsoleOptionParser $parser The option parser help is being generated for.
  48. */
  49. public function __construct(ConsoleOptionParser $parser) {
  50. $this->_parser = $parser;
  51. }
  52. /**
  53. * Get the help as formatted text suitable for output on the command line.
  54. *
  55. * @param integer $width The width of the help output.
  56. * @return string
  57. */
  58. public function text($width = 72) {
  59. $parser = $this->_parser;
  60. $out = array();
  61. $description = $parser->description();
  62. if (!empty($description)) {
  63. $out[] = String::wrap($description, $width);
  64. $out[] = '';
  65. }
  66. $out[] = __d('cake_console', '<info>Usage:</info>');
  67. $out[] = $this->_generateUsage();
  68. $out[] = '';
  69. $subcommands = $parser->subcommands();
  70. if (!empty($subcommands)) {
  71. $out[] = __d('cake_console', '<info>Subcommands:</info>');
  72. $out[] = '';
  73. $max = $this->_getMaxLength($subcommands) + 2;
  74. foreach ($subcommands as $command) {
  75. $out[] = String::wrap($command->help($max), array(
  76. 'width' => $width,
  77. 'indent' => str_repeat(' ', $max),
  78. 'indentAt' => 1
  79. ));
  80. }
  81. $out[] = '';
  82. $out[] = __d('cake_console', 'To see help on a subcommand use <info>`cake %s [subcommand] --help`</info>', $parser->command());
  83. $out[] = '';
  84. }
  85. $options = $parser->options();
  86. if (!empty($options)) {
  87. $max = $this->_getMaxLength($options) + 8;
  88. $out[] = __d('cake_console', '<info>Options:</info>');
  89. $out[] = '';
  90. foreach ($options as $option) {
  91. $out[] = String::wrap($option->help($max), array(
  92. 'width' => $width,
  93. 'indent' => str_repeat(' ', $max),
  94. 'indentAt' => 1
  95. ));
  96. }
  97. $out[] = '';
  98. }
  99. $arguments = $parser->arguments();
  100. if (!empty($arguments)) {
  101. $max = $this->_getMaxLength($arguments) + 2;
  102. $out[] = __d('cake_console', '<info>Arguments:</info>');
  103. $out[] = '';
  104. foreach ($arguments as $argument) {
  105. $out[] = String::wrap($argument->help($max), array(
  106. 'width' => $width,
  107. 'indent' => str_repeat(' ', $max),
  108. 'indentAt' => 1
  109. ));
  110. }
  111. $out[] = '';
  112. }
  113. $epilog = $parser->epilog();
  114. if (!empty($epilog)) {
  115. $out[] = String::wrap($epilog, $width);
  116. $out[] = '';
  117. }
  118. return implode("\n", $out);
  119. }
  120. /**
  121. * Generate the usage for a shell based on its arguments and options.
  122. * Usage strings favor short options over the long ones. and optional args will
  123. * be indicated with []
  124. *
  125. * @return string
  126. */
  127. protected function _generateUsage() {
  128. $usage = array('cake ' . $this->_parser->command());
  129. $subcommands = $this->_parser->subcommands();
  130. if (!empty($subcommands)) {
  131. $usage[] = '[subcommand]';
  132. }
  133. $options = array();
  134. foreach ($this->_parser->options() as $option) {
  135. $options[] = $option->usage();
  136. }
  137. if (count($options) > $this->_maxOptions) {
  138. $options = array('[options]');
  139. }
  140. $usage = array_merge($usage, $options);
  141. $args = array();
  142. foreach ($this->_parser->arguments() as $argument) {
  143. $args[] = $argument->usage();
  144. }
  145. if (count($args) > $this->_maxArgs) {
  146. $args = array('[arguments]');
  147. }
  148. $usage = array_merge($usage, $args);
  149. return implode(' ', $usage);
  150. }
  151. /**
  152. * Iterate over a collection and find the longest named thing.
  153. *
  154. * @param array $collection
  155. * @return integer
  156. */
  157. protected function _getMaxLength($collection) {
  158. $max = 0;
  159. foreach ($collection as $item) {
  160. $max = (strlen($item->name()) > $max) ? strlen($item->name()) : $max;
  161. }
  162. return $max;
  163. }
  164. /**
  165. * Get the help as an xml string.
  166. *
  167. * @param boolean $string Return the SimpleXml object or a string. Defaults to true.
  168. * @return string|SimpleXmlElement See $string
  169. */
  170. public function xml($string = true) {
  171. $parser = $this->_parser;
  172. $xml = new SimpleXmlElement('<shell></shell>');
  173. $xml->addChild('command', $parser->command());
  174. $xml->addChild('description', $parser->description());
  175. $xml->addChild('epilog', $parser->epilog());
  176. $subcommands = $xml->addChild('subcommands');
  177. foreach ($parser->subcommands() as $command) {
  178. $command->xml($subcommands);
  179. }
  180. $options = $xml->addChild('options');
  181. foreach ($parser->options() as $option) {
  182. $option->xml($options);
  183. }
  184. $arguments = $xml->addChild('arguments');
  185. foreach ($parser->arguments() as $argument) {
  186. $argument->xml($arguments);
  187. }
  188. return $string ? $xml->asXml() : $xml;
  189. }
  190. }