package.xml 0000664 0001750 0001750 00000023424 12226220733 011303 0 ustar jan jan
Console_Table
pear.php.net
Class that makes it easy to build console style tables
Provides methods such as addRow(), insertRow(), addCol() etc. to build console tables with or without headers and with user defined table rules and padding.
Jan Schneider
yunosh
jan@horde.org
yes
Richard Heyes
richard
richard@phpguru.org
no
Tal Peer
tal
tal@php.net
no
Xavier Noguer
xnoguer
xnoguer@php.net
no
2013-10-12
1.1.6
1.1.1
stable
stable
BSD
Use line breaks dependent on the current operating system.
4.3.10
1.4.0b1
Console_Color
pear.php.net
0.0.4
0.8
0.8
beta
beta
2002-09-02
BSD
Initial release
1.0
1.0.1
stable
stable
2003-01-24
BSD
Removed a few options and added addData() method
1.0.1
1.0.0
stable
stable
2003-03-03
BSD
Fixed a caching bug
1.0.2
1.0.0
stable
stable
2005-07-16
BSD
Added support for column alignment. Patch from Michael Richter
1.0.3
1.0.0
stable
stable
2006-03-13
BSD
* Fix cell width calculation if setting header with associative array (Bug 4299).
* Fix fatal reference error with some PHP versions (Bug 5309).
* Fix notice if no data has been provided (Bug 5851).
* Added multibyte support (Requests 2934 and 7014).
1.0.4
1.0.0
stable
stable
2006-04-08
BSD
* Add support for multi-line cells (koto at webworkers dot pl, Request #7017).
1.0.5
1.0.0
stable
stable
2006-08-28
BSD
* Allow to specify separator rules in addData().
* Fix warnings when combining separator rules and callback filters (Bug #8566).
1.0.6
1.0.0
stable
stable
2007-01-19
BSD
* Add support for multi-line headers (Request #8615).
2007-05-17
1.0.7
1.0.0
stable
stable
BSD
* Fix header height if first data row has more than one line (Bug #11064).
* Fix notice if header is not set.
2008-01-09
1.0.8
1.0.0
stable
stable
BSD
* Fix cell padding with multibyte strings under certain circumstances (Bug #12853).
2008-03-28
1.1.0
1.1.0
stable
stable
BSD
* Add option to set table border character.
* Extend constructor to set table borders, padding, and charset on instantiation.
2008-04-09
1.1.1
1.1.0
stable
stable
BSD
Fix rendering of multiline rows with cells that contain zeros (Bug #13629).
2008-07-27
1.1.2
1.1.0
stable
stable
BSD
Don't render anything if no data has been provided (Bug #14405).
2008-10-20
1.1.3
1.1.1
stable
stable
BSD
Add option to render data with ANSI color codes (Igor Feghali, Request #14835).
1.1.4
1.1.1
stable
stable
2010-10-25
BSD
Automatically built QA release
Req #14835 Add Console_Color support - yunosh
Doc #15006 Console_table docs are totally worthless - cweiske
2012-12-07
1.1.5
1.1.1
stable
stable
BSD
Use mb_strwidth() instead of mb_strlen() to determine lengths of multi-byte strings (Bug #19423).
2013-10-12
1.1.6
1.1.1
stable
stable
BSD
Use line breaks dependent on the current operating system.
Console_Table-1.1.6/tests/assoziative_arrays.phpt 0000664 0001750 0001750 00000001032 12226220733 020310 0 ustar jan jan --TEST--
Header and data as associative arrays.
--FILE--
'foo',
'two' => 'bar'
);
$data = array(
array(
'x' => 'baz',
)
);
$table = new Console_Table();
$table->setHeaders($headers);
$table->addData($data);
echo $table->getTable();
?>
--EXPECT--
+-----+-----+
| foo | bar |
+-----+-----+
| baz | |
+-----+-----+
Console_Table-1.1.6/tests/colors.phpt 0000664 0001750 0001750 00000001241 12226220733 015671 0 ustar jan jan --TEST--
Data with ANSI color codes
--SKIPIF--
--FILE--
setHeaders(array('foo', 'bar'));
$table->addRow(array('baz', Console_Color::convert("%bblue%n")));
echo $table->getTable();
?>
--EXPECT--
+-----+------+
| foo | bar |
+-----+------+
| baz | [34mblue[0m |
+-----+------+
Console_Table-1.1.6/tests/filters.phpt 0000664 0001750 0001750 00000001315 12226220733 016042 0 ustar jan jan --TEST--
Callback filters
--FILE--
setHeaders(array('foo', 'bar'));
$table->addData($data);
$table->addFilter(0, $filter);
echo $table->getTable();
?>
--EXPECT--
+-------+-------+
| foo | bar |
+-------+-------+
| ONE | two |
| THREE | four |
+-------+-------+
| FIVE | six |
| SEVEN | eight |
+-------+-------+
Console_Table-1.1.6/tests/multibyte.phpt 0000664 0001750 0001750 00000001432 12226220733 016410 0 ustar jan jan --TEST--
Multibyte strings
--FILE--
setHeaders(array('Schön', 'Häßlich'));
$table->addData(array(array('Ich', 'Du'), array('Ä', 'Ü')));
echo $table->getTable();
$table = new Console_Table();
$table->addRow(array("I'm from 中国"));
$table->addRow(array("我是中国人"));
$table->addRow(array("I'm from China"));
echo $table->getTable();
?>
--EXPECT--
+-------+---------+
| Schön | Häßlich |
+-------+---------+
| Ich | Du |
| Ä | Ü |
+-------+---------+
+----------------+
| I'm from 中国 |
| 我是中国人 |
| I'm from China |
+----------------+
Console_Table-1.1.6/tests/multiline.phpt 0000664 0001750 0001750 00000003103 12226220733 016371 0 ustar jan jan --TEST--
Multiline table cells
--FILE--
setHeaders(array("h1\nmultiline", 'h2', "h3", 'h4'));
$table->addData($data);
echo $table->getTable();
echo Console_Table::fromArray(array('one line header'),
array(array("multiple\nlines"),
array('one line')));
?>
--EXPECT--
+-----------+--------+-----------+--------+
| h1 | h2 | h3 | h4 |
| multiline | | | |
+-----------+--------+-----------+--------+
| col1 | 0 | col3 | col4 |
| | | multiline | |
| r2col1 | r2col2 | r2col3 | r2col4 |
| | | multiline | |
| r3col1 | r3col2 | r3col3 | r3col4 |
| | | multiline | |
| | | verymuch | |
| r4col1 | r4col2 | r4col3 | r4col4 |
| r5col1 | r5col2 | r5col3 | r5col4 |
+-----------+--------+-----------+--------+
+-----------------+
| one line header |
+-----------------+
| multiple |
| lines |
| one line |
+-----------------+
Console_Table-1.1.6/tests/no_header.phpt 0000664 0001750 0001750 00000000554 12226220733 016322 0 ustar jan jan --TEST--
Table without header
--FILE--
addData(array(array('foo', 'bar')));
echo $table->getTable();
?>
--EXPECT--
+-----+-----+
| foo | bar |
+-----+-----+
Console_Table-1.1.6/tests/no_rows.phpt 0000664 0001750 0001750 00000000671 12226220733 016064 0 ustar jan jan --TEST--
Table without data
--FILE--
setHeaders(array('foo', 'bar'));
echo $table->getTable();
$table = new Console_Table();
echo $table->getTable();
?>
--EXPECT--
+-----+-----+
| foo | bar |
+-----+-----+
| | |
+-----+-----+
Console_Table-1.1.6/tests/rules.phpt 0000664 0001750 0001750 00000002766 12226220733 015537 0 ustar jan jan --TEST--
Horizontal rules
--FILE--
setHeaders(array('foo', 'bar'));
$table->addData($data);
$table->addSeparator();
echo $table->getTable();
echo "=========================\n";
$table = new Console_Table(CONSOLE_TABLE_ALIGN_LEFT, '');
$table->setHeaders(array('foo', 'bar'));
$table->addData($data);
$table->addSeparator();
echo $table->getTable();
echo "=========================\n";
$table = new Console_Table(CONSOLE_TABLE_ALIGN_LEFT, '#', 0);
$table->setHeaders(array('foo', 'bar'));
$table->addData($data);
$table->addSeparator();
echo $table->getTable();
?>
--EXPECT--
+-------+-------+
| foo | bar |
+-------+-------+
| one | two |
+-------+-------+
| three | four |
+-------+-------+
+-------+-------+
| five | six |
| seven | eight |
+-------+-------+
+-------+-------+
=========================
foo bar
one two
three four
five six
seven eight
=========================
#############
#foo #bar #
#############
#one #two #
#############
#three#four #
#############
#############
#five #six #
#seven#eight#
#############
#############
Console_Table-1.1.6/Table.php 0000775 0001750 0001750 00000063332 12226220733 014105 0 ustar jan jan
* @author Jan Schneider
* @copyright 2002-2005 Richard Heyes
* @copyright 2006-2008 Jan Schneider
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id$
* @link http://pear.php.net/package/Console_Table
*/
define('CONSOLE_TABLE_HORIZONTAL_RULE', 1);
define('CONSOLE_TABLE_ALIGN_LEFT', -1);
define('CONSOLE_TABLE_ALIGN_CENTER', 0);
define('CONSOLE_TABLE_ALIGN_RIGHT', 1);
define('CONSOLE_TABLE_BORDER_ASCII', -1);
/**
* The main class.
*
* @category Console
* @package Console_Table
* @author Jan Schneider
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @link http://pear.php.net/package/Console_Table
*/
class Console_Table
{
/**
* The table headers.
*
* @var array
*/
var $_headers = array();
/**
* The data of the table.
*
* @var array
*/
var $_data = array();
/**
* The maximum number of columns in a row.
*
* @var integer
*/
var $_max_cols = 0;
/**
* The maximum number of rows in the table.
*
* @var integer
*/
var $_max_rows = 0;
/**
* Lengths of the columns, calculated when rows are added to the table.
*
* @var array
*/
var $_cell_lengths = array();
/**
* Heights of the rows.
*
* @var array
*/
var $_row_heights = array();
/**
* How many spaces to use to pad the table.
*
* @var integer
*/
var $_padding = 1;
/**
* Column filters.
*
* @var array
*/
var $_filters = array();
/**
* Columns to calculate totals for.
*
* @var array
*/
var $_calculateTotals;
/**
* Alignment of the columns.
*
* @var array
*/
var $_col_align = array();
/**
* Default alignment of columns.
*
* @var integer
*/
var $_defaultAlign;
/**
* Character set of the data.
*
* @var string
*/
var $_charset = 'utf-8';
/**
* Border character.
*
* @var string
*/
var $_border = CONSOLE_TABLE_BORDER_ASCII;
/**
* Whether the data has ANSI colors.
*
* @var boolean
*/
var $_ansiColor = false;
/**
* Constructor.
*
* @param integer $align Default alignment. One of
* CONSOLE_TABLE_ALIGN_LEFT,
* CONSOLE_TABLE_ALIGN_CENTER or
* CONSOLE_TABLE_ALIGN_RIGHT.
* @param string $border The character used for table borders or
* CONSOLE_TABLE_BORDER_ASCII.
* @param integer $padding How many spaces to use to pad the table.
* @param string $charset A charset supported by the mbstring PHP
* extension.
* @param boolean $color Whether the data contains ansi color codes.
*/
function Console_Table($align = CONSOLE_TABLE_ALIGN_LEFT,
$border = CONSOLE_TABLE_BORDER_ASCII, $padding = 1,
$charset = null, $color = false)
{
$this->_defaultAlign = $align;
$this->_border = $border;
$this->_padding = $padding;
$this->_ansiColor = $color;
if ($this->_ansiColor) {
include_once 'Console/Color.php';
}
if (!empty($charset)) {
$this->setCharset($charset);
}
}
/**
* Converts an array to a table.
*
* @param array $headers Headers for the table.
* @param array $data A two dimensional array with the table
* data.
* @param boolean $returnObject Whether to return the Console_Table object
* instead of the rendered table.
*
* @static
*
* @return Console_Table|string A Console_Table object or the generated
* table.
*/
function fromArray($headers, $data, $returnObject = false)
{
if (!is_array($headers) || !is_array($data)) {
return false;
}
$table = new Console_Table();
$table->setHeaders($headers);
foreach ($data as $row) {
$table->addRow($row);
}
return $returnObject ? $table : $table->getTable();
}
/**
* Adds a filter to a column.
*
* Filters are standard PHP callbacks which are run on the data before
* table generation is performed. Filters are applied in the order they
* are added. The callback function must accept a single argument, which
* is a single table cell.
*
* @param integer $col Column to apply filter to.
* @param mixed &$callback PHP callback to apply.
*
* @return void
*/
function addFilter($col, &$callback)
{
$this->_filters[] = array($col, &$callback);
}
/**
* Sets the charset of the provided table data.
*
* @param string $charset A charset supported by the mbstring PHP
* extension.
*
* @return void
*/
function setCharset($charset)
{
$locale = setlocale(LC_CTYPE, 0);
setlocale(LC_CTYPE, 'en_US');
$this->_charset = strtolower($charset);
setlocale(LC_CTYPE, $locale);
}
/**
* Sets the alignment for the columns.
*
* @param integer $col_id The column number.
* @param integer $align Alignment to set for this column. One of
* CONSOLE_TABLE_ALIGN_LEFT
* CONSOLE_TABLE_ALIGN_CENTER
* CONSOLE_TABLE_ALIGN_RIGHT.
*
* @return void
*/
function setAlign($col_id, $align = CONSOLE_TABLE_ALIGN_LEFT)
{
switch ($align) {
case CONSOLE_TABLE_ALIGN_CENTER:
$pad = STR_PAD_BOTH;
break;
case CONSOLE_TABLE_ALIGN_RIGHT:
$pad = STR_PAD_LEFT;
break;
default:
$pad = STR_PAD_RIGHT;
break;
}
$this->_col_align[$col_id] = $pad;
}
/**
* Specifies which columns are to have totals calculated for them and
* added as a new row at the bottom.
*
* @param array $cols Array of column numbers (starting with 0).
*
* @return void
*/
function calculateTotalsFor($cols)
{
$this->_calculateTotals = $cols;
}
/**
* Sets the headers for the columns.
*
* @param array $headers The column headers.
*
* @return void
*/
function setHeaders($headers)
{
$this->_headers = array(array_values($headers));
$this->_updateRowsCols($headers);
}
/**
* Adds a row to the table.
*
* @param array $row The row data to add.
* @param boolean $append Whether to append or prepend the row.
*
* @return void
*/
function addRow($row, $append = true)
{
if ($append) {
$this->_data[] = array_values($row);
} else {
array_unshift($this->_data, array_values($row));
}
$this->_updateRowsCols($row);
}
/**
* Inserts a row after a given row number in the table.
*
* If $row_id is not given it will prepend the row.
*
* @param array $row The data to insert.
* @param integer $row_id Row number to insert before.
*
* @return void
*/
function insertRow($row, $row_id = 0)
{
array_splice($this->_data, $row_id, 0, array($row));
$this->_updateRowsCols($row);
}
/**
* Adds a column to the table.
*
* @param array $col_data The data of the column.
* @param integer $col_id The column index to populate.
* @param integer $row_id If starting row is not zero, specify it here.
*
* @return void
*/
function addCol($col_data, $col_id = 0, $row_id = 0)
{
foreach ($col_data as $col_cell) {
$this->_data[$row_id++][$col_id] = $col_cell;
}
$this->_updateRowsCols();
$this->_max_cols = max($this->_max_cols, $col_id + 1);
}
/**
* Adds data to the table.
*
* @param array $data A two dimensional array with the table data.
* @param integer $col_id Starting column number.
* @param integer $row_id Starting row number.
*
* @return void
*/
function addData($data, $col_id = 0, $row_id = 0)
{
foreach ($data as $row) {
if ($row === CONSOLE_TABLE_HORIZONTAL_RULE) {
$this->_data[$row_id] = CONSOLE_TABLE_HORIZONTAL_RULE;
$row_id++;
continue;
}
$starting_col = $col_id;
foreach ($row as $cell) {
$this->_data[$row_id][$starting_col++] = $cell;
}
$this->_updateRowsCols();
$this->_max_cols = max($this->_max_cols, $starting_col);
$row_id++;
}
}
/**
* Adds a horizontal seperator to the table.
*
* @return void
*/
function addSeparator()
{
$this->_data[] = CONSOLE_TABLE_HORIZONTAL_RULE;
}
/**
* Returns the generated table.
*
* @return string The generated table.
*/
function getTable()
{
$this->_applyFilters();
$this->_calculateTotals();
$this->_validateTable();
return $this->_buildTable();
}
/**
* Calculates totals for columns.
*
* @return void
*/
function _calculateTotals()
{
if (empty($this->_calculateTotals)) {
return;
}
$this->addSeparator();
$totals = array();
foreach ($this->_data as $row) {
if (is_array($row)) {
foreach ($this->_calculateTotals as $columnID) {
$totals[$columnID] += $row[$columnID];
}
}
}
$this->_data[] = $totals;
$this->_updateRowsCols();
}
/**
* Applies any column filters to the data.
*
* @return void
*/
function _applyFilters()
{
if (empty($this->_filters)) {
return;
}
foreach ($this->_filters as $filter) {
$column = $filter[0];
$callback = $filter[1];
foreach ($this->_data as $row_id => $row_data) {
if ($row_data !== CONSOLE_TABLE_HORIZONTAL_RULE) {
$this->_data[$row_id][$column] =
call_user_func($callback, $row_data[$column]);
}
}
}
}
/**
* Ensures that column and row counts are correct.
*
* @return void
*/
function _validateTable()
{
if (!empty($this->_headers)) {
$this->_calculateRowHeight(-1, $this->_headers[0]);
}
for ($i = 0; $i < $this->_max_rows; $i++) {
for ($j = 0; $j < $this->_max_cols; $j++) {
if (!isset($this->_data[$i][$j]) &&
(!isset($this->_data[$i]) ||
$this->_data[$i] !== CONSOLE_TABLE_HORIZONTAL_RULE)) {
$this->_data[$i][$j] = '';
}
}
$this->_calculateRowHeight($i, $this->_data[$i]);
if ($this->_data[$i] !== CONSOLE_TABLE_HORIZONTAL_RULE) {
ksort($this->_data[$i]);
}
}
$this->_splitMultilineRows();
// Update cell lengths.
for ($i = 0; $i < count($this->_headers); $i++) {
$this->_calculateCellLengths($this->_headers[$i]);
}
for ($i = 0; $i < $this->_max_rows; $i++) {
$this->_calculateCellLengths($this->_data[$i]);
}
ksort($this->_data);
}
/**
* Splits multiline rows into many smaller one-line rows.
*
* @return void
*/
function _splitMultilineRows()
{
ksort($this->_data);
$sections = array(&$this->_headers, &$this->_data);
$max_rows = array(count($this->_headers), $this->_max_rows);
$row_height_offset = array(-1, 0);
for ($s = 0; $s <= 1; $s++) {
$inserted = 0;
$new_data = $sections[$s];
for ($i = 0; $i < $max_rows[$s]; $i++) {
// Process only rows that have many lines.
$height = $this->_row_heights[$i + $row_height_offset[$s]];
if ($height > 1) {
// Split column data into one-liners.
$split = array();
for ($j = 0; $j < $this->_max_cols; $j++) {
$split[$j] = preg_split('/\r?\n|\r/',
$sections[$s][$i][$j]);
}
$new_rows = array();
// Construct new 'virtual' rows - insert empty strings for
// columns that have less lines that the highest one.
for ($i2 = 0; $i2 < $height; $i2++) {
for ($j = 0; $j < $this->_max_cols; $j++) {
$new_rows[$i2][$j] = !isset($split[$j][$i2])
? ''
: $split[$j][$i2];
}
}
// Replace current row with smaller rows. $inserted is
// used to take account of bigger array because of already
// inserted rows.
array_splice($new_data, $i + $inserted, 1, $new_rows);
$inserted += count($new_rows) - 1;
}
}
// Has the data been modified?
if ($inserted > 0) {
$sections[$s] = $new_data;
$this->_updateRowsCols();
}
}
}
/**
* Builds the table.
*
* @return string The generated table string.
*/
function _buildTable()
{
if (!count($this->_data)) {
return '';
}
$rule = $this->_border == CONSOLE_TABLE_BORDER_ASCII
? '|'
: $this->_border;
$separator = $this->_getSeparator();
$return = array();
for ($i = 0; $i < count($this->_data); $i++) {
for ($j = 0; $j < count($this->_data[$i]); $j++) {
if ($this->_data[$i] !== CONSOLE_TABLE_HORIZONTAL_RULE &&
$this->_strlen($this->_data[$i][$j]) <
$this->_cell_lengths[$j]) {
$this->_data[$i][$j] = $this->_strpad($this->_data[$i][$j],
$this->_cell_lengths[$j],
' ',
$this->_col_align[$j]);
}
}
if ($this->_data[$i] !== CONSOLE_TABLE_HORIZONTAL_RULE) {
$row_begin = $rule . str_repeat(' ', $this->_padding);
$row_end = str_repeat(' ', $this->_padding) . $rule;
$implode_char = str_repeat(' ', $this->_padding) . $rule
. str_repeat(' ', $this->_padding);
$return[] = $row_begin
. implode($implode_char, $this->_data[$i]) . $row_end;
} elseif (!empty($separator)) {
$return[] = $separator;
}
}
$return = implode(PHP_EOL, $return);
if (!empty($separator)) {
$return = $separator . PHP_EOL . $return . PHP_EOL . $separator;
}
$return .= PHP_EOL;
if (!empty($this->_headers)) {
$return = $this->_getHeaderLine() . PHP_EOL . $return;
}
return $return;
}
/**
* Creates a horizontal separator for header separation and table
* start/end etc.
*
* @return string The horizontal separator.
*/
function _getSeparator()
{
if (!$this->_border) {
return;
}
if ($this->_border == CONSOLE_TABLE_BORDER_ASCII) {
$rule = '-';
$sect = '+';
} else {
$rule = $sect = $this->_border;
}
$return = array();
foreach ($this->_cell_lengths as $cl) {
$return[] = str_repeat($rule, $cl);
}
$row_begin = $sect . str_repeat($rule, $this->_padding);
$row_end = str_repeat($rule, $this->_padding) . $sect;
$implode_char = str_repeat($rule, $this->_padding) . $sect
. str_repeat($rule, $this->_padding);
return $row_begin . implode($implode_char, $return) . $row_end;
}
/**
* Returns the header line for the table.
*
* @return string The header line of the table.
*/
function _getHeaderLine()
{
// Make sure column count is correct
for ($j = 0; $j < count($this->_headers); $j++) {
for ($i = 0; $i < $this->_max_cols; $i++) {
if (!isset($this->_headers[$j][$i])) {
$this->_headers[$j][$i] = '';
}
}
}
for ($j = 0; $j < count($this->_headers); $j++) {
for ($i = 0; $i < count($this->_headers[$j]); $i++) {
if ($this->_strlen($this->_headers[$j][$i]) <
$this->_cell_lengths[$i]) {
$this->_headers[$j][$i] =
$this->_strpad($this->_headers[$j][$i],
$this->_cell_lengths[$i],
' ',
$this->_col_align[$i]);
}
}
}
$rule = $this->_border == CONSOLE_TABLE_BORDER_ASCII
? '|'
: $this->_border;
$row_begin = $rule . str_repeat(' ', $this->_padding);
$row_end = str_repeat(' ', $this->_padding) . $rule;
$implode_char = str_repeat(' ', $this->_padding) . $rule
. str_repeat(' ', $this->_padding);
$separator = $this->_getSeparator();
if (!empty($separator)) {
$return[] = $separator;
}
for ($j = 0; $j < count($this->_headers); $j++) {
$return[] = $row_begin
. implode($implode_char, $this->_headers[$j]) . $row_end;
}
return implode(PHP_EOL, $return);
}
/**
* Updates values for maximum columns and rows.
*
* @param array $rowdata Data array of a single row.
*
* @return void
*/
function _updateRowsCols($rowdata = null)
{
// Update maximum columns.
$this->_max_cols = max($this->_max_cols, count($rowdata));
// Update maximum rows.
ksort($this->_data);
$keys = array_keys($this->_data);
$this->_max_rows = end($keys) + 1;
switch ($this->_defaultAlign) {
case CONSOLE_TABLE_ALIGN_CENTER:
$pad = STR_PAD_BOTH;
break;
case CONSOLE_TABLE_ALIGN_RIGHT:
$pad = STR_PAD_LEFT;
break;
default:
$pad = STR_PAD_RIGHT;
break;
}
// Set default column alignments
for ($i = count($this->_col_align); $i < $this->_max_cols; $i++) {
$this->_col_align[$i] = $pad;
}
}
/**
* Calculates the maximum length for each column of a row.
*
* @param array $row The row data.
*
* @return void
*/
function _calculateCellLengths($row)
{
for ($i = 0; $i < count($row); $i++) {
if (!isset($this->_cell_lengths[$i])) {
$this->_cell_lengths[$i] = 0;
}
$this->_cell_lengths[$i] = max($this->_cell_lengths[$i],
$this->_strlen($row[$i]));
}
}
/**
* Calculates the maximum height for all columns of a row.
*
* @param integer $row_number The row number.
* @param array $row The row data.
*
* @return void
*/
function _calculateRowHeight($row_number, $row)
{
if (!isset($this->_row_heights[$row_number])) {
$this->_row_heights[$row_number] = 1;
}
// Do not process horizontal rule rows.
if ($row === CONSOLE_TABLE_HORIZONTAL_RULE) {
return;
}
for ($i = 0, $c = count($row); $i < $c; ++$i) {
$lines = preg_split('/\r?\n|\r/', $row[$i]);
$this->_row_heights[$row_number] = max($this->_row_heights[$row_number],
count($lines));
}
}
/**
* Returns the character length of a string.
*
* @param string $str A multibyte or singlebyte string.
*
* @return integer The string length.
*/
function _strlen($str)
{
static $mbstring;
// Strip ANSI color codes if requested.
if ($this->_ansiColor) {
$str = Console_Color::strip($str);
}
// Cache expensive function_exists() calls.
if (!isset($mbstring)) {
$mbstring = function_exists('mb_strwidth');
}
if ($mbstring) {
return mb_strwidth($str, $this->_charset);
}
return strlen($str);
}
/**
* Returns part of a string.
*
* @param string $string The string to be converted.
* @param integer $start The part's start position, zero based.
* @param integer $length The part's length.
*
* @return string The string's part.
*/
function _substr($string, $start, $length = null)
{
static $mbstring;
// Cache expensive function_exists() calls.
if (!isset($mbstring)) {
$mbstring = function_exists('mb_substr');
}
if (is_null($length)) {
$length = $this->_strlen($string);
}
if ($mbstring) {
$ret = @mb_substr($string, $start, $length, $this->_charset);
if (!empty($ret)) {
return $ret;
}
}
return substr($string, $start, $length);
}
/**
* Returns a string padded to a certain length with another string.
*
* This method behaves exactly like str_pad but is multibyte safe.
*
* @param string $input The string to be padded.
* @param integer $length The length of the resulting string.
* @param string $pad The string to pad the input string with. Must
* be in the same charset like the input string.
* @param const $type The padding type. One of STR_PAD_LEFT,
* STR_PAD_RIGHT, or STR_PAD_BOTH.
*
* @return string The padded string.
*/
function _strpad($input, $length, $pad = ' ', $type = STR_PAD_RIGHT)
{
$mb_length = $this->_strlen($input);
$sb_length = strlen($input);
$pad_length = $this->_strlen($pad);
/* Return if we already have the length. */
if ($mb_length >= $length) {
return $input;
}
/* Shortcut for single byte strings. */
if ($mb_length == $sb_length && $pad_length == strlen($pad)) {
return str_pad($input, $length, $pad, $type);
}
switch ($type) {
case STR_PAD_LEFT:
$left = $length - $mb_length;
$output = $this->_substr(str_repeat($pad, ceil($left / $pad_length)),
0, $left, $this->_charset) . $input;
break;
case STR_PAD_BOTH:
$left = floor(($length - $mb_length) / 2);
$right = ceil(($length - $mb_length) / 2);
$output = $this->_substr(str_repeat($pad, ceil($left / $pad_length)),
0, $left, $this->_charset) .
$input .
$this->_substr(str_repeat($pad, ceil($right / $pad_length)),
0, $right, $this->_charset);
break;
case STR_PAD_RIGHT:
$right = $length - $mb_length;
$output = $input .
$this->_substr(str_repeat($pad, ceil($right / $pad_length)),
0, $right, $this->_charset);
break;
}
return $output;
}
}