PageRenderTime 27ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/s3db3.5.10/pearlib/Console/Table.php

https://github.com/drobbins/s3db
PHP | 312 lines | 137 code | 39 blank | 136 comment | 12 complexity | 111436b09ed47446fe447ec33e2bcd3f MD5 | raw file
  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002-2003 Richard Heyes |
  4. // | All rights reserved. |
  5. // | |
  6. // | Redistribution and use in source and binary forms, with or without |
  7. // | modification, are permitted provided that the following conditions |
  8. // | are met: |
  9. // | |
  10. // | o Redistributions of source code must retain the above copyright |
  11. // | notice, this list of conditions and the following disclaimer. |
  12. // | o Redistributions in binary form must reproduce the above copyright |
  13. // | notice, this list of conditions and the following disclaimer in the |
  14. // | documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote |
  16. // | products derived from this software without specific prior written |
  17. // | permission. |
  18. // | |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
  30. // | |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard@phpguru.org> |
  33. // +-----------------------------------------------------------------------+
  34. //
  35. // $Id: Table.php,v 1.4 2003/03/03 11:37:26 richard Exp $
  36. //
  37. // Utility for printing tables from cmdline scripts
  38. //
  39. class Console_Table
  40. {
  41. /**
  42. * The table headers
  43. * @var array
  44. */
  45. var $_headers;
  46. /**
  47. * The data of the table
  48. * @var array
  49. */
  50. var $_data;
  51. /**
  52. * The max number of columns in a row
  53. * @var integer
  54. */
  55. var $_max_cols;
  56. /**
  57. * The max number of rows in the table
  58. * @var integer
  59. */
  60. var $_max_rows;
  61. /**
  62. * Lengths of the columns, calculated
  63. * when rows are added to the table.
  64. * @var array
  65. */
  66. var $_cell_lengths;
  67. /**
  68. * Some options that configure various
  69. * things
  70. * @var array;
  71. */
  72. var $_options;
  73. /**
  74. * How many spaces to use to pad the table
  75. * @var integer
  76. */
  77. var $_padding;
  78. /**
  79. * Constructor
  80. */
  81. function Console_Table()
  82. {
  83. $this->_headers = array();
  84. $this->_data = array();
  85. $this->_cell_lengths = array();
  86. $this->_max_cols = 0;
  87. $this->_max_rows = 0;
  88. $this->_padding = 1;
  89. }
  90. /**
  91. * Sets the headers for the columns
  92. *
  93. * @param array $headers The column headers
  94. */
  95. function setHeaders($headers)
  96. {
  97. $this->_headers = $headers;
  98. $this->_updateRowsCols($headers);
  99. }
  100. /**
  101. * Adds a row to the table
  102. *
  103. * @param array $row The row data to add
  104. * @param array $append Whether to append or prepend the row
  105. */
  106. function addRow($row, $append = true)
  107. {
  108. $append ? $this->_data[] = array_values($row) : array_unshift($this->_data, array_values($row));
  109. $this->_updateRowsCols($row);
  110. }
  111. /**
  112. * Inserts a row after a given row number in the table. If $row_id
  113. * is not given it will prepend the row.
  114. *
  115. * @param array $row The data to insert
  116. * @param integer $row_id Row number to insert before
  117. */
  118. function insertRow($row, $row_id = 0)
  119. {
  120. array_splice($this->_data, $row_id, 0, array($row));
  121. $this->_updateRowsCols($row);
  122. }
  123. /**
  124. * Adds a column to the table
  125. *
  126. * @param array $col_data The data of the column. Can be numeric or associative array
  127. * @param integer $col_id The column index to populate
  128. * @param integer $row_id If starting row is not zero, specify it here
  129. */
  130. function addCol($col_data, $col_id = 0, $row_id = 0)
  131. {
  132. foreach ($col_data as $col_cell) {
  133. $this->_data[$row_id++][$col_id] = $col_cell;
  134. }
  135. $this->_updateRowsCols();
  136. $this->_max_cols = max($this->_max_cols, $col_id + 1);
  137. }
  138. /**
  139. * Adds data to the table. Argument should be
  140. * a two dimensional array containing the data
  141. * to be added.
  142. *
  143. * @param array $data The data to add to the table
  144. * @param integer $col_id Optional starting column ID
  145. * @param integer $row_id Optional starting row ID
  146. */
  147. function addData($data, $col_id = 0, $row_id = 0)
  148. {
  149. foreach ($data as $row) {
  150. $starting_col = $col_id;
  151. foreach ($row as $cell) {
  152. $this->_data[$row_id][$starting_col++] = $cell;
  153. }
  154. $this->_updateRowsCols();
  155. $this->_max_cols = max($this->_max_cols, $starting_col);
  156. $row_id++;
  157. }
  158. }
  159. /**
  160. * Returns the table in wonderful
  161. * ASCII art
  162. */
  163. function getTable()
  164. {
  165. $this->_validateTable();
  166. return $this->_buildTable();
  167. }
  168. /**
  169. * Ensures column and row counts are correct
  170. */
  171. function _validateTable()
  172. {
  173. for ($i=0; $i<$this->_max_rows; $i++) {
  174. for ($j=0; $j<$this->_max_cols; $j++) {
  175. if (!isset($this->_data[$i][$j])) {
  176. $this->_data[$i][$j] = '';
  177. }
  178. // Update cell lengths
  179. $this->_calculateCellLengths($this->_data[$i]);
  180. }
  181. ksort($this->_data[$i]);
  182. }
  183. ksort($this->_data);
  184. }
  185. /**
  186. * Builds the table
  187. */
  188. function _buildTable()
  189. {
  190. $return = array();
  191. $rows = $this->_data;
  192. for ($i=0; $i<count($rows); $i++) {
  193. for ($j=0; $j<count($rows[$i]); $j++) {
  194. if (strlen($rows[$i][$j]) < $this->_cell_lengths[$j]) {
  195. $rows[$i][$j] = str_pad($rows[$i][$j], $this->_cell_lengths[$j], ' ');
  196. }
  197. }
  198. $row_begin = '|' . str_repeat(' ', $this->_padding);
  199. $row_end = str_repeat(' ', $this->_padding) . '|';
  200. $implode_char = str_repeat(' ', $this->_padding) . '|' . str_repeat(' ', $this->_padding);
  201. $return[] = $row_begin . implode($implode_char, $rows[$i]) . $row_end;
  202. }
  203. $return = $this->_getSeparator() . "\r\n" . implode("\n", $return) . "\r\n" . $this->_getSeparator() . "\r\n";
  204. if (!empty($this->_headers)) {
  205. $return = $this->_getHeaderLine() . "\r\n" . $return;
  206. }
  207. return $return;
  208. }
  209. /**
  210. * Creates a horizontal separator for header
  211. * separation and table start/end etc
  212. *
  213. */
  214. function _getSeparator()
  215. {
  216. foreach ($this->_cell_lengths as $cl) {
  217. $return[] = str_repeat('-', $cl);
  218. }
  219. $row_begin = '+' . str_repeat('-', $this->_padding);
  220. $row_end = str_repeat('-', $this->_padding) . '+';
  221. $implode_char = str_repeat('-', $this->_padding) . '+' . str_repeat('-', $this->_padding);
  222. $return = $row_begin . implode($implode_char, $return) . $row_end;
  223. return $return;
  224. }
  225. /**
  226. * Returns header line for the table
  227. */
  228. function _getHeaderLine()
  229. {
  230. // Make sure column count is correct
  231. for ($i=0; $i<$this->_max_cols; $i++) {
  232. if (!isset($this->_headers[$i])) {
  233. $this->_headers[$i] = '';
  234. }
  235. }
  236. for ($i=0; $i<count($this->_headers); $i++) {
  237. if (strlen($this->_headers[$i]) < $this->_cell_lengths[$i]) {
  238. $this->_headers[$i] = str_pad($this->_headers[$i], $this->_cell_lengths[$i], ' ');
  239. }
  240. }
  241. $row_begin = '|' . str_repeat(' ', $this->_padding);
  242. $row_end = str_repeat(' ', $this->_padding) . '|';
  243. $implode_char = str_repeat(' ', $this->_padding) . '|' . str_repeat(' ', $this->_padding);
  244. $return[] = $this->_getSeparator();
  245. $return[] = $row_begin . implode($implode_char, $this->_headers) . $row_end;
  246. return implode("\r\n", $return);
  247. }
  248. /**
  249. * Update max cols/rows
  250. */
  251. function _updateRowsCols($rowdata = null)
  252. {
  253. // Update max cols
  254. $this->_max_cols = max($this->_max_cols, count($rowdata));
  255. // Update max rows
  256. ksort($this->_data);
  257. $this->_max_rows = end(array_keys($this->_data)) + 1;
  258. }
  259. /**
  260. * This function given a row of data will
  261. * calculate the max length for each column
  262. * and store it in the _cell_lengths array.
  263. *
  264. * @param array $row The row data
  265. */
  266. function _calculateCellLengths($row)
  267. {
  268. for ($i=0; $i<count($row); $i++) {
  269. $this->_cell_lengths[$i] = max(strlen(@$this->_headers[$i]), @$this->_cell_lengths[$i], strlen(@$row[$i]));
  270. }
  271. }
  272. }
  273. ?>