Skip to content

Commit 8d71526

Browse files
committed
Refactor Tabular display to use renderers (currently tabular and ascii).
1 parent 116389e commit 8d71526

7 files changed

Lines changed: 206 additions & 52 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ Tabular Display
3232
* `\cli\Table::__construct(array $headers = null, array $rows = null)`
3333
* `\cli\Table::setHeaders(array $headers)`
3434
* `\cli\Table::setRows(array $rows)`
35+
* `\cli\Table::setRenderer(\cli\table\Renderer $renderer)`
3536
* `\cli\Table::addRow(array $row)`
3637
* `\cli\Table::sort($column)`
3738
* `\cli\Table::display()`
3839

3940
The display function will detect if output is piped and, if it is, render a tab delimited table instead of the ASCII
4041
table rendered for visual display.
4142

43+
You can also explicitly set the renderer used by calling `\cli\Table::setRenderer()` and giving it an instance of one
44+
of the concrete `\cli\table\Renderer` classes.
45+
4246
Usage
4347
-----
4448

example.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ function test_notify(\cli\Notify $notify, $cycle = 1000000, $sleep = null) {
6060
$notify->finish();
6161
}
6262

63+
if (\cli\Shell::isPiped()) {
64+
$table = new \cli\Table();
65+
$table->setHeaders($headers);
66+
$table->setRows($data);
67+
$table->display();
68+
exit;
69+
}
70+
6371
while (true) {
6472
$choice = \cli\menu($menu, null, 'Choose an example');
6573
\cli\line();

lib/cli/Shell.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ class Shell {
2626
static public function columns() {
2727
return exec('/usr/bin/env tput cols');
2828
}
29+
30+
/**
31+
* Checks whether the output of the current script is a TTY or a pipe / redirect
32+
*
33+
* Returns true if STDOUT output is being redirected to a pipe or a file; false is
34+
* output is being sent directly to the terminal.
35+
*
36+
* @return bool
37+
*/
38+
static public function isPiped() {
39+
return (function_exists('posix_isatty') && !posix_isatty(STDOUT));
40+
}
2941
}
3042

3143
?>

lib/cli/Table.php

Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,11 @@
1616
* The `Table` class is used to display data in a tabular format.
1717
*/
1818
class Table {
19+
protected $_renderer;
1920
protected $_headers = array();
2021
protected $_width = array();
2122
protected $_rows = array();
2223

23-
/**
24-
* Checks whether the output of the current script is a TTY or a pipe / redirect
25-
*
26-
* Returns true if STDOUT output is being redirected to a pipe or a file; false is
27-
* output is being sent directly to the terminal.
28-
*
29-
* @return bool
30-
*/
31-
protected function isPiped() {
32-
return ( function_exists( 'posix_isatty' ) && !posix_isatty( STDOUT ) );
33-
}
34-
3524
/**
3625
* Initializes the `Table` class.
3726
*
@@ -64,6 +53,24 @@ public function __construct(array $headers = null, array $rows = null) {
6453
$this->setHeaders($headers);
6554
$this->setRows($rows);
6655
}
56+
57+
if (\cli\Shell::isPiped()) {
58+
$this->setRenderer(new \cli\table\Tabular());
59+
} else {
60+
$this->setRenderer(new \cli\table\Ascii());
61+
}
62+
}
63+
64+
/**
65+
* Sets the renderer used by this table.
66+
*
67+
* @param cli\table\Renderer $renderer The renderer to use for output.
68+
* @see cli\table\Renderer
69+
* @see cli\table\Standard
70+
* @see cli\table\Tabular
71+
*/
72+
public function setRenderer(\cli\table\Renderer $renderer) {
73+
$this->_renderer = $renderer;
6774
}
6875

6976
/**
@@ -88,57 +95,29 @@ protected function checkRow(array $row) {
8895
* If STDOUT is a pipe or redirected to a file, should output simple
8996
* tab-separated text. Otherwise, renders table with ASCII table borders
9097
*
91-
* @uses cli\Table::isPiped() Determine what format to output
98+
* @uses cli\Shell::isPiped() Determine what format to output
9299
*
93100
* @see cli\Table::renderRow()
94101
*/
95102
public function display() {
96-
$borderStr = '+';
97-
foreach ($this->_headers as $column => $header) {
98-
$borderStr .= '-' . str_repeat('-', $this->_width[$column]) . '-+';
99-
}
103+
$this->_renderer->setWidths($this->_width);
104+
$border = $this->_renderer->border();
100105

101-
if ( $this->isPiped() ) {
102-
\cli\line($this->renderPipedRow($this->_headers));
103-
foreach ($this->_rows as $row) {
104-
\cli\line($this->renderPipedRow($row));
105-
}
106-
return;
106+
if (isset($border)) {
107+
\cli\line($border);
108+
}
109+
\cli\line($this->_renderer->row($this->_headers));
110+
if (isset($border)) {
111+
\cli\line($border);
107112
}
108-
109-
\cli\line($borderStr);
110-
\cli\line($this->renderRow($this->_headers));
111-
\cli\line($borderStr);
112113

113114
foreach ($this->_rows as $row) {
114-
\cli\line($this->renderRow($row));
115+
\cli\line($this->_renderer->row($row));
115116
}
116117

117-
\cli\line($borderStr);
118-
}
119-
120-
/**
121-
* Renders a row for output.
122-
*
123-
* @param array $row The table row.
124-
* @return string The formatted table row.
125-
*/
126-
protected function renderRow(array $row) {
127-
$render = '|';
128-
foreach ($row as $column => $val) {
129-
$render .= ' ' . Colors::pad($val, $this->_width[$column]) . ' |';
118+
if (isset($border)) {
119+
\cli\line($border);
130120
}
131-
return $render;
132-
}
133-
134-
/**
135-
* Renders a row for piped output.
136-
*
137-
* @param array $row The table row.
138-
* @return string The formatted table row.
139-
*/
140-
protected function renderPipedRow(array $row) {
141-
return implode( "\t", array_values( $row ) );
142121
}
143122

144123
/**

lib/cli/table/Ascii.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* PHP Command Line Tools
4+
*
5+
* This source file is subject to the MIT license that is bundled
6+
* with this package in the file LICENSE.
7+
*
8+
* @author James Logsdon <dwarf@girsbrain.org>
9+
* @copyright 2010 James Logsdom (http://girsbrain.org)
10+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
11+
*/
12+
13+
namespace cli\table;
14+
15+
/**
16+
* The ASCII renderer renders tables with ASCII borders.
17+
*/
18+
class Ascii extends Renderer {
19+
protected $_characters = array(
20+
'corner' => '+',
21+
'line' => '-',
22+
'border' => '|'
23+
);
24+
protected $_border = null;
25+
26+
/**
27+
* Set the characters used for rendering the Ascii table.
28+
*
29+
* The keys `corner`, `line` and `border` are used in rendering.
30+
*
31+
* @param $characters array Characters used in rendering.
32+
*/
33+
public function setCharacters(array $characters) {
34+
$this->_characters = array_merge($this->_characters, $characters);
35+
}
36+
37+
/**
38+
* Render a border for the top and bottom and separating the headers from the
39+
* table rows.
40+
*
41+
* @return string The table border.
42+
*/
43+
public function border() {
44+
if (!isset($this->_border)) {
45+
$this->_border = $this->_characters['corner'];
46+
foreach ($this->_widths as $width) {
47+
$this->_border .= str_repeat($this->_characters['line'], $width + 2);
48+
$this->_border .= $this->_characters['corner'];
49+
}
50+
}
51+
52+
return $this->_border;
53+
}
54+
55+
/**
56+
* Renders a row for output.
57+
*
58+
* @param array $row The table row.
59+
* @return string The formatted table row.
60+
*/
61+
public function row(array $row) {
62+
$row = array_map(array($this, 'padColumn'), $row, array_keys($row));
63+
array_unshift($row, ''); // First border
64+
array_push($row, ''); // Last border
65+
66+
return join($this->_characters['border'], $row);
67+
}
68+
69+
private function padColumn($content, $column) {
70+
return ' ' . \cli\Colors::pad($content, $this->_widths[$column]) . ' ';
71+
}
72+
}

lib/cli/table/Renderer.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
/**
3+
* PHP Command Line Tools
4+
*
5+
* This source file is subject to the MIT license that is bundled
6+
* with this package in the file LICENSE.
7+
*
8+
* @author James Logsdon <dwarf@girsbrain.org>
9+
* @copyright 2010 James Logsdom (http://girsbrain.org)
10+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
11+
*/
12+
13+
namespace cli\table;
14+
15+
/**
16+
* Table renderers are used to change how a table is displayed.
17+
*/
18+
abstract class Renderer {
19+
protected $_widths = array();
20+
21+
public function __construct(array $widths = array()) {
22+
$this->setWidths($widths);
23+
}
24+
25+
/**
26+
* Set the widths of each column in the table.
27+
*
28+
* @param array $widths The widths of the columns.
29+
*/
30+
public function setWidths(array $widths) {
31+
$this->_widths = $widths;
32+
}
33+
34+
/**
35+
* Render a border for the top and bottom and separating the headers from the
36+
* table rows.
37+
*
38+
* @return string The table border.
39+
*/
40+
public function border() {
41+
return null;
42+
}
43+
44+
/**
45+
* Renders a row for output.
46+
*
47+
* @param array $row The table row.
48+
* @return string The formatted table row.
49+
*/
50+
abstract public function row(array $row);
51+
}

lib/cli/table/Tabular.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* PHP Command Line Tools
4+
*
5+
* This source file is subject to the MIT license that is bundled
6+
* with this package in the file LICENSE.
7+
*
8+
* @author James Logsdon <dwarf@girsbrain.org>
9+
* @copyright 2010 James Logsdom (http://girsbrain.org)
10+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
11+
*/
12+
13+
namespace cli\table;
14+
15+
/**
16+
* The tabular renderer is used for displaying data in a tabular format.
17+
*/
18+
class Tabular extends Renderer {
19+
/**
20+
* Renders a row for output.
21+
*
22+
* @param array $row The table row.
23+
* @return string The formatted table row.
24+
*/
25+
public function row(array $row) {
26+
return implode("\t", array_values($row));
27+
}
28+
}

0 commit comments

Comments
 (0)