initial commit; version 22.5.12042
This commit is contained in:
257
libs/cli/Table.php
Normal file
257
libs/cli/Table.php
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP Command Line Tools
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this package in the file LICENSE.
|
||||
*
|
||||
* @author James Logsdon <dwarf@girsbrain.org>
|
||||
* @copyright 2010 James Logsdom (http://girsbrain.org)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
|
||||
namespace cli;
|
||||
|
||||
use cli\Shell;
|
||||
use cli\Streams;
|
||||
use cli\table\Ascii;
|
||||
use cli\table\Renderer;
|
||||
use cli\table\Tabular;
|
||||
|
||||
/**
|
||||
* The `Table` class is used to display data in a tabular format.
|
||||
*/
|
||||
class Table {
|
||||
protected $_renderer;
|
||||
protected $_headers = array();
|
||||
protected $_footers = array();
|
||||
protected $_width = array();
|
||||
protected $_rows = array();
|
||||
|
||||
/**
|
||||
* Initializes the `Table` class.
|
||||
*
|
||||
* There are 3 ways to instantiate this class:
|
||||
*
|
||||
* 1. Pass an array of strings as the first parameter for the column headers
|
||||
* and a 2-dimensional array as the second parameter for the data rows.
|
||||
* 2. Pass an array of hash tables (string indexes instead of numerical)
|
||||
* where each hash table is a row and the indexes of the *first* hash
|
||||
* table are used as the header values.
|
||||
* 3. Pass nothing and use `setHeaders()` and `addRow()` or `setRows()`.
|
||||
*
|
||||
* @param array $headers Headers used in this table. Optional.
|
||||
* @param array $rows The rows of data for this table. Optional.
|
||||
* @param array $footers Footers used in this table. Optional.
|
||||
*/
|
||||
public function __construct(array $headers = null, array $rows = null, array $footers = null) {
|
||||
if (!empty($headers)) {
|
||||
// If all the rows is given in $headers we use the keys from the
|
||||
// first row for the header values
|
||||
if ($rows === null) {
|
||||
$rows = $headers;
|
||||
$keys = array_keys(array_shift($headers));
|
||||
$headers = array();
|
||||
|
||||
foreach ($keys as $header) {
|
||||
$headers[$header] = $header;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHeaders($headers);
|
||||
$this->setRows($rows);
|
||||
}
|
||||
|
||||
if (!empty($footers)) {
|
||||
$this->setFooters($footers);
|
||||
}
|
||||
|
||||
if (Shell::isPiped()) {
|
||||
$this->setRenderer(new Tabular());
|
||||
} else {
|
||||
$this->setRenderer(new Ascii());
|
||||
}
|
||||
}
|
||||
|
||||
public function resetTable()
|
||||
{
|
||||
$this->_headers = array();
|
||||
$this->_width = array();
|
||||
$this->_rows = array();
|
||||
$this->_footers = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the renderer used by this table.
|
||||
*
|
||||
* @param table\Renderer $renderer The renderer to use for output.
|
||||
* @see table\Renderer
|
||||
* @see table\Ascii
|
||||
* @see table\Tabular
|
||||
*/
|
||||
public function setRenderer(Renderer $renderer) {
|
||||
$this->_renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the row and sets the maximum width for each column.
|
||||
*
|
||||
* @param array $row The table row.
|
||||
* @return array $row
|
||||
*/
|
||||
protected function checkRow(array $row) {
|
||||
foreach ($row as $column => $str) {
|
||||
$width = Colors::width( $str, $this->isAsciiPreColorized( $column ) );
|
||||
if (!isset($this->_width[$column]) || $width > $this->_width[$column]) {
|
||||
$this->_width[$column] = $width;
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the table to `STDOUT` using `cli\line()`.
|
||||
*
|
||||
* If STDOUT is a pipe or redirected to a file, should output simple
|
||||
* tab-separated text. Otherwise, renders table with ASCII table borders
|
||||
*
|
||||
* @uses cli\Shell::isPiped() Determine what format to output
|
||||
*
|
||||
* @see cli\Table::renderRow()
|
||||
*/
|
||||
public function display() {
|
||||
foreach( $this->getDisplayLines() as $line ) {
|
||||
Streams::line( $line );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table lines to output.
|
||||
*
|
||||
* @see cli\Table::display()
|
||||
* @see cli\Table::renderRow()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDisplayLines() {
|
||||
$this->_renderer->setWidths($this->_width, $fallback = true);
|
||||
$border = $this->_renderer->border();
|
||||
|
||||
$out = array();
|
||||
if (isset($border)) {
|
||||
$out[] = $border;
|
||||
}
|
||||
$out[] = $this->_renderer->row($this->_headers);
|
||||
if (isset($border)) {
|
||||
$out[] = $border;
|
||||
}
|
||||
|
||||
foreach ($this->_rows as $row) {
|
||||
$row = $this->_renderer->row($row);
|
||||
$row = explode( PHP_EOL, $row );
|
||||
$out = array_merge( $out, $row );
|
||||
}
|
||||
|
||||
if (isset($border)) {
|
||||
$out[] = $border;
|
||||
}
|
||||
|
||||
if ($this->_footers) {
|
||||
$out[] = $this->_renderer->row($this->_footers);
|
||||
if (isset($border)) {
|
||||
$out[] = $border;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the table by a column. Must be called before `cli\Table::display()`.
|
||||
*
|
||||
* @param int $column The index of the column to sort by.
|
||||
*/
|
||||
public function sort($column) {
|
||||
if (!isset($this->_headers[$column])) {
|
||||
trigger_error('No column with index ' . $column, E_USER_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
usort($this->_rows, function($a, $b) use ($column) {
|
||||
return strcmp($a[$column], $b[$column]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the headers of the table.
|
||||
*
|
||||
* @param array $headers An array of strings containing column header names.
|
||||
*/
|
||||
public function setHeaders(array $headers) {
|
||||
$this->_headers = $this->checkRow($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the footers of the table.
|
||||
*
|
||||
* @param array $footers An array of strings containing column footers names.
|
||||
*/
|
||||
public function setFooters(array $footers) {
|
||||
$this->_footers = $this->checkRow($footers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a row to the table.
|
||||
*
|
||||
* @param array $row The row data.
|
||||
* @see cli\Table::checkRow()
|
||||
*/
|
||||
public function addRow(array $row) {
|
||||
$this->_rows[] = $this->checkRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all previous rows and adds the given rows.
|
||||
*
|
||||
* @param array $rows A 2-dimensional array of row data.
|
||||
* @see cli\Table::addRow()
|
||||
*/
|
||||
public function setRows(array $rows) {
|
||||
$this->_rows = array();
|
||||
foreach ($rows as $row) {
|
||||
$this->addRow($row);
|
||||
}
|
||||
}
|
||||
|
||||
public function countRows() {
|
||||
return count($this->_rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether items in an Ascii table are pre-colorized.
|
||||
*
|
||||
* @param bool|array $precolorized A boolean to set all columns in the table as pre-colorized, or an array of booleans keyed by column index (number) to set individual columns as pre-colorized.
|
||||
* @see cli\Ascii::setPreColorized()
|
||||
*/
|
||||
public function setAsciiPreColorized( $pre_colorized ) {
|
||||
if ( $this->_renderer instanceof Ascii ) {
|
||||
$this->_renderer->setPreColorized( $pre_colorized );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a column in an Ascii table pre-colorized?
|
||||
*
|
||||
* @param int $column Column index to check.
|
||||
* @return bool True if whole Ascii table is marked as pre-colorized, or if the individual column is pre-colorized; else false.
|
||||
* @see cli\Ascii::isPreColorized()
|
||||
*/
|
||||
private function isAsciiPreColorized( $column ) {
|
||||
if ( $this->_renderer instanceof Ascii ) {
|
||||
return $this->_renderer->isPreColorized( $column );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user