TableHelper.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @since 3.1.0
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Cake\Shell\Helper;
  15. use Cake\Console\Helper;
  16. /**
  17. * Create a visually pleasing ASCII art table
  18. * from 2 dimensional array data.
  19. */
  20. class TableHelper extends Helper
  21. {
  22. /**
  23. * Default config for this helper.
  24. *
  25. * @var array
  26. */
  27. protected $_defaultConfig = [
  28. 'headers' => true,
  29. 'rowSeparator' => false,
  30. 'headerStyle' => 'info',
  31. ];
  32. /**
  33. * Calculate the column widths
  34. *
  35. * @param array $rows The rows on which the columns width will be calculated on.
  36. * @return array
  37. */
  38. protected function _calculateWidths($rows)
  39. {
  40. $widths = [];
  41. foreach ($rows as $line) {
  42. for ($i = 0, $len = count($line); $i < $len; $i++) {
  43. $columnLength = mb_strlen($line[$i]);
  44. if ($columnLength > (isset($widths[$i]) ? $widths[$i] : 0)) {
  45. $widths[$i] = $columnLength;
  46. }
  47. }
  48. }
  49. return $widths;
  50. }
  51. /**
  52. * Output a row separator.
  53. *
  54. * @param array $widths The widths of each column to output.
  55. * @return void
  56. */
  57. protected function _rowSeparator($widths)
  58. {
  59. $out = '';
  60. foreach ($widths as $column) {
  61. $out .= '+' . str_repeat('-', $column + 2);
  62. }
  63. $out .= '+';
  64. $this->_io->out($out);
  65. }
  66. /**
  67. * Output a row.
  68. *
  69. * @param array $row The row to output.
  70. * @param array $widths The widths of each column to output.
  71. * @param array $options Options to be passed.
  72. * @return void
  73. */
  74. protected function _render($row, $widths, $options = [])
  75. {
  76. $out = '';
  77. foreach ($row as $i => $column) {
  78. $pad = $widths[$i] - mb_strlen($column);
  79. if (!empty($options['style'])) {
  80. $column = $this->_addStyle($column, $options['style']);
  81. }
  82. $out .= '| ' . $column . str_repeat(' ', $pad) . ' ';
  83. }
  84. $out .= '|';
  85. $this->_io->out($out);
  86. }
  87. /**
  88. * Output a table.
  89. *
  90. * @param array $rows The data to render out.
  91. * @return void
  92. */
  93. public function output($rows)
  94. {
  95. $config = $this->config();
  96. $widths = $this->_calculateWidths($rows);
  97. $this->_rowSeparator($widths);
  98. if ($config['headers'] === true) {
  99. $this->_render(array_shift($rows), $widths, ['style' => $config['headerStyle']]);
  100. $this->_rowSeparator($widths);
  101. }
  102. foreach ($rows as $line) {
  103. $this->_render($line, $widths);
  104. if ($config['rowSeparator'] === true) {
  105. $this->_rowSeparator($widths);
  106. }
  107. }
  108. if ($config['rowSeparator'] !== true) {
  109. $this->_rowSeparator($widths);
  110. }
  111. }
  112. /**
  113. * Add style tags
  114. *
  115. * @param string $text The text to be surrounded
  116. * @param string $style The style to be applied
  117. * @return string
  118. */
  119. protected function _addStyle($text, $style)
  120. {
  121. return '<' . $style . '>' . $text . '</' . $style . '>';
  122. }
  123. }