output.inc

  1. 8.0.x includes/output.inc
  2. 6.x includes/output.inc
  3. 7.x includes/output.inc
  4. 5.x includes/output.inc
  5. master includes/output.inc

Functions

Namesort descending Description
drush_format Prepares a variable for printing.
drush_html_to_text Convert html to readable text. Compatible API to drupal_html_to_text, but less functional. Caller might prefer to call drupal_html_to_text if there is a bootstrapped Drupal site available.
drush_json_decode Converts an HTML-safe JSON string into its PHP equivalent.
drush_json_encode Converts a PHP variable into its Javascript equivalent.
drush_key_value_to_array_table Convert an associative array of key : value pairs into a table suitable for processing by drush_print_table.
drush_print_file Print the contents of a file.
drush_print_pipe Stores a message which is printed during drush_shutdown() if in compact mode.
drush_print_prompt Print a prompt -- that is, a message with no trailing newline.
drush_print_r Prints an array or string.
drush_print_table Print a formatted table.
drush_table_column_autowidth Determine the best fit for column widths.
dt Rudimentary replacement for Drupal API t() function.

File

includes/output.inc
View source
  1. <?php
  2. /**
  3. * @defgroup outputfunctions Process output text.
  4. * @{
  5. /**
  6. * Prints a message with optional indentation. In general,
  7. * drush_log($message, 'ok') is often a better choice than this function.
  8. * That gets your confirmation message (for example) into the logs for this
  9. * drush request. Consider that drush requests may be executed remotely and
  10. * non interactively.
  11. *
  12. * @param $message
  13. * The message to print.
  14. * @param $indent
  15. * The indentation (space chars)
  16. * @param $handle
  17. * File handle to write to. NULL will write
  18. * to standard output, STDERR will write to the standard
  19. * error. See http://php.net/manual/en/features.commandline.io-streams.php
  20. * @param $newline
  21. * Add a "\n" to the end of the output. Defaults to TRUE.
  22. */
  23. function drush_print($message = '', $indent = 0, $handle = NULL, $newline = TRUE) {
  24. $msg = str_repeat(' ', $indent) . (string)$message;
  25. if ($newline) {
  26. $msg .= "\n";
  27. }
  28. if (($charset = drush_get_option('output_charset')) && function_exists('iconv')) {
  29. $msg = iconv('UTF-8', $charset, $msg);
  30. }
  31. if (isset($handle)) {
  32. fwrite($handle, $msg);
  33. }
  34. else {
  35. print $msg;
  36. }
  37. }
  38. /**
  39. * Print a prompt -- that is, a message with no trailing newline.
  40. */
  41. function drush_print_prompt($message, $indent = 0, $handle = NULL) {
  42. drush_print($message, $indent, $handle, FALSE);
  43. }
  44. /**
  45. * Stores a message which is printed during drush_shutdown() if in compact mode.
  46. * @param $message
  47. * The message to print. If $message is an array,
  48. * then each element of the array is printed on a
  49. * separate line.
  50. */
  51. function drush_print_pipe($message = '') {
  52. $buffer = &drush_get_context('DRUSH_PIPE_BUFFER' , '');
  53. if (is_array($message)) {
  54. $message = implode("\n", $message) . "\n";
  55. }
  56. $buffer .= $message;
  57. }
  58. /**
  59. * Prints an array or string.
  60. * @param $array
  61. * The array to print.
  62. * @param $newline
  63. * Add a "\n" to the end of the output. Defaults to TRUE.
  64. */
  65. function drush_print_r($array, $handle = NULL, $newline = TRUE) {
  66. drush_print(print_r($array, TRUE), 0, $handle, $newline);
  67. }
  68. /**
  69. * Prepares a variable for printing.
  70. * @param mixed $input
  71. * A variable.
  72. * @param string $label
  73. * Optional prefix. Not used by JSON format.
  74. * @return string
  75. * The variable formatted according to specified format. Ready for drush_print().
  76. */
  77. function drush_format($input, $label = NULL, $format = NULL) {
  78. if (is_null(($format))) {
  79. $format = drush_get_option('format', 'print_r');
  80. }
  81. if ($format != 'export' && $format != 'config') {
  82. if ($input === TRUE) {
  83. $input = 'TRUE';
  84. }
  85. elseif ($input === FALSE) {
  86. $input = 'FALSE';
  87. }
  88. }
  89. switch ($format) {
  90. case 'config':
  91. if ($label) {
  92. $output = "\$config['$label'] = " . var_export($input, TRUE) . ';';
  93. }
  94. else {
  95. $output = var_export($input, TRUE);
  96. }
  97. break;
  98. case 'export':
  99. if ($label) {
  100. $output = "\$variables['$label'] = " . var_export($input, TRUE) . ';';
  101. }
  102. else {
  103. $output = var_export($input, TRUE);
  104. }
  105. break;
  106. case 'json':
  107. $output = drush_json_encode($input);
  108. break;
  109. case 'print_r':
  110. default:
  111. if (is_string($input)) {
  112. $input = '"' . $input . '"';
  113. }
  114. elseif (is_array($input) || is_object($input)) {
  115. $input = print_r($input, TRUE);
  116. }
  117. if ($label) {
  118. $input = $label . ': ' . $input;
  119. }
  120. $output = $input;
  121. break;
  122. }
  123. return $output;
  124. }
  125. /**
  126. * Rudimentary replacement for Drupal API t() function.
  127. *
  128. * @param string
  129. * String to process, possibly with replacement item.
  130. * @param array
  131. * An associative array of replacement items.
  132. *
  133. * @return
  134. * The processed string.
  135. *
  136. * @see t()
  137. */
  138. function dt($string, $args = array()) {
  139. if (function_exists('t') && (drush_drupal_version() == 7 || function_exists('theme'))) {
  140. return t($string, $args);
  141. }
  142. else {
  143. if (!empty($args)) {
  144. return strtr($string, $args);
  145. }
  146. else {
  147. return $string;
  148. }
  149. }
  150. }
  151. /**
  152. * Convert html to readable text. Compatible API to
  153. * drupal_html_to_text, but less functional. Caller
  154. * might prefer to call drupal_html_to_text if there
  155. * is a bootstrapped Drupal site available.
  156. *
  157. * @param string $html
  158. * The html text to convert.
  159. *
  160. * @return string
  161. * The plain-text representation of the input.
  162. */
  163. function drush_html_to_text($html, $allowed_tags = NULL) {
  164. $replacements = array(
  165. '<hr>' => '------------------------------------------------------------------------------',
  166. '<li>' => ' * ',
  167. '<h1>' => '===== ',
  168. '</h1>' => ' =====',
  169. '<h2>' => '---- ',
  170. '</h2>' => ' ----',
  171. '<h3>' => '::: ',
  172. '</h3>' => ' :::',
  173. '<br/>' => "\n",
  174. );
  175. $text = str_replace(array_keys($replacements), array_values($replacements), $html);
  176. return html_entity_decode(preg_replace('/ *<[^>]*> */', ' ', $text));
  177. }
  178. /**
  179. * Print a formatted table.
  180. *
  181. * @param $rows
  182. * The rows to print.
  183. * @param $header
  184. * If TRUE, the first line will be treated as table header.
  185. * @param $widths
  186. * The widths of each column (in characters) to use - if not specified this
  187. * will be determined automatically, based on a "best fit" algorithm.
  188. * @param $handle
  189. * File handle to write to. NULL will write
  190. * to standard output, STDERR will write to the standard
  191. * error. See http://php.net/manual/en/features.commandline.io-streams.php
  192. * @return $tbl
  193. * Use $tbl->getTable() to get the output from the return value.
  194. */
  195. function drush_print_table($rows, $header = FALSE, $widths = array(), $handle = NULL) {
  196. $tbl = new Console_Table(CONSOLE_TABLE_ALIGN_LEFT , '');
  197. $auto_widths = drush_table_column_autowidth($rows, $widths);
  198. // Do wordwrap on all cells.
  199. $newrows = array();
  200. foreach ($rows as $rowkey => $row) {
  201. foreach ($row as $col_num => $cell) {
  202. $newrows[$rowkey][$col_num] = wordwrap($cell, $auto_widths[$col_num], "\n", TRUE);
  203. if (isset($widths[$col_num])) {
  204. $newrows[$rowkey][$col_num] = str_pad($newrows[$rowkey][$col_num], $widths[$col_num]);
  205. }
  206. }
  207. }
  208. if ($header) {
  209. $headers = array_shift($newrows);
  210. $tbl->setHeaders($headers);
  211. }
  212. $tbl->addData($newrows);
  213. $output = $tbl->getTable();
  214. if (!stristr(PHP_OS, 'WIN')) {
  215. $output = str_replace("\r\n", PHP_EOL, $output);
  216. }
  217. drush_print($output, 0, $handle);
  218. return $tbl;
  219. }
  220. /**
  221. * Convert an associative array of key : value pairs into
  222. * a table suitable for processing by drush_print_table.
  223. *
  224. * @param $keyvalue_table
  225. * An associative array of key : value pairs.
  226. * @return
  227. * An array of arrays, where the keys from the input
  228. * array are stored in the first column, and the values
  229. * are stored in the third. A second colum is created
  230. * specifically to hold the ':' separator.
  231. */
  232. function drush_key_value_to_array_table($keyvalue_table) {
  233. $table = array();
  234. foreach ($keyvalue_table as $key => $value) {
  235. if (isset($value)) {
  236. $table[] = array($key, ' :', $value);
  237. }
  238. else {
  239. $table[] = array($key . ':', '', '');
  240. }
  241. }
  242. return $table;
  243. }
  244. /**
  245. * Determine the best fit for column widths.
  246. *
  247. * @param $rows
  248. * The rows to use for calculations.
  249. * @param $widths
  250. * Manually specified widths of each column (in characters) - these will be
  251. * left as is.
  252. */
  253. function drush_table_column_autowidth($rows, $widths) {
  254. $auto_widths = $widths;
  255. // First we determine the distribution of row lengths in each column.
  256. // This is an array of descending character length keys (i.e. starting at
  257. // the rightmost character column), with the value indicating the number
  258. // of rows where that character column is present.
  259. $col_dist = array();
  260. foreach ($rows as $rowkey => $row) {
  261. foreach ($row as $col_num => $cell) {
  262. if (empty($widths[$col_num])) {
  263. $length = strlen($cell);
  264. while ($length > 0) {
  265. if (!isset($col_dist[$col_num][$length])) {
  266. $col_dist[$col_num][$length] = 0;
  267. }
  268. $col_dist[$col_num][$length]++;
  269. $length--;
  270. }
  271. }
  272. }
  273. }
  274. foreach ($col_dist as $col_num => $count) {
  275. // Sort the distribution in decending key order.
  276. krsort($col_dist[$col_num]);
  277. // Initially we set all columns to their "ideal" longest width
  278. // - i.e. the width of their longest column.
  279. $auto_widths[$col_num] = max(array_keys($col_dist[$col_num]));
  280. }
  281. // We determine what width we have available to use, and what width the
  282. // above "ideal" columns take up.
  283. $available_width = drush_get_context('DRUSH_COLUMNS', 80) - (count($auto_widths) * 2);
  284. $auto_width_current = array_sum($auto_widths);
  285. // If we need to reduce a column so that we can fit the space we use this
  286. // loop to figure out which column will cause the "least wrapping",
  287. // (relative to the other columns) and reduce the width of that column.
  288. while ($auto_width_current > $available_width) {
  289. $count = 0;
  290. $width = 0;
  291. foreach ($col_dist as $col_num => $counts) {
  292. // If we are just starting out, select the first column.
  293. if ($count == 0 ||
  294. // OR: if this column would cause less wrapping than the currently
  295. // selected column, then select it.
  296. (current($counts) < $count) ||
  297. // OR: if this column would cause the same amount of wrapping, but is
  298. // longer, then we choose to wrap the longer column (proportionally
  299. // less wrapping, and helps avoid triple line wraps).
  300. (current($counts) == $count && key($counts) > $width)) {
  301. // Select the column number, and record the count and current width
  302. // for later comparisons.
  303. $column = $col_num;
  304. $count = current($counts);
  305. $width = key($counts);
  306. }
  307. }
  308. if ($width <= 1) {
  309. // If we have reached a width of 1 then give up, so wordwrap can still progress.
  310. break;
  311. }
  312. // Reduce the width of the selected column.
  313. $auto_widths[$column]--;
  314. // Reduce our overall table width counter.
  315. $auto_width_current--;
  316. // Remove the corresponding data from the disctribution, so next time
  317. // around we use the data for the row to the left.
  318. unset($col_dist[$column][$width]);
  319. }
  320. return $auto_widths;
  321. }
  322. /**
  323. * Print the contents of a file.
  324. *
  325. * @param string $file
  326. * Full path to a file.
  327. */
  328. function drush_print_file($file) {
  329. // Don't even bother to print the file in --no mode
  330. if (drush_get_context('DRUSH_NEGATIVE')) {
  331. return;
  332. }
  333. if ((substr($file,-4) == ".htm") || (substr($file,-5) == ".html")) {
  334. $tmp_file = drush_tempnam(basename($file));
  335. file_put_contents($tmp_file, drush_html_to_text(file_get_contents($file)));
  336. $file = $tmp_file;
  337. }
  338. // Do not wait for user input in --yes or --pipe modes
  339. if (drush_get_context('DRUSH_PIPE')) {
  340. drush_print_pipe(file_get_contents($file));
  341. }
  342. elseif (drush_get_context('DRUSH_AFFIRMATIVE')) {
  343. drush_print(file_get_contents($file));
  344. }
  345. elseif (drush_shell_exec_interactive("less %s", $file)) {
  346. return;
  347. }
  348. elseif (drush_shell_exec_interactive("more %s", $file)) {
  349. return;
  350. }
  351. else {
  352. drush_print(file_get_contents($file));
  353. }
  354. }
  355. /**
  356. * Converts a PHP variable into its Javascript equivalent.
  357. *
  358. * We provide a copy of D7's drupal_json_encode since this function is
  359. * unavailable on earlier versions of Drupal.
  360. *
  361. * @see drupal_json_decode()
  362. * @ingroup php_wrappers
  363. */
  364. function drush_json_encode($var) {
  365. // json_encode() does not escape <, > and &, so we do it with str_replace().
  366. return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
  367. }
  368. /**
  369. * Converts an HTML-safe JSON string into its PHP equivalent.
  370. *
  371. * We provide a copy of D7's drupal_json_decode since this function is
  372. * unavailable on earlier versions of Drupal.
  373. *
  374. * @see drupal_json_encode()
  375. * @ingroup php_wrappers
  376. */
  377. function drush_json_decode($var) {
  378. return json_decode($var, TRUE);
  379. }
  380. /**
  381. * @} End of "defgroup outputfunctions".
  382. */