7
* This source file is subject to the new BSD license that is bundled
8
* with this package in the file LICENSE.txt.
9
* It is also available through the world-wide-web at this URL:
10
* http://framework.zend.com/license/new-bsd
11
* If you did not receive a copy of the license and are unable to
12
* obtain it through the world-wide-web, please send an email
13
* to license@zend.com so we can send you a copy immediately.
16
* @package Zend_Text_Table
17
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
18
* @license http://framework.zend.com/license/new-bsd New BSD License
19
* @version $Id: Table.php 12550 2008-11-11 15:26:47Z dasprid $
23
* Zend_Text_Table enables developers to create tables out of characters
26
* @package Zend_Text_Table
27
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
28
* @license http://framework.zend.com/license/new-bsd New BSD License
33
* Auto seperator settings
35
const AUTO_SEPARATE_NONE = 0x0;
36
const AUTO_SEPARATE_HEADER = 0x1;
37
const AUTO_SEPARATE_FOOTER = 0x2;
38
const AUTO_SEPARATE_ALL = 0x4;
41
* Decorator used for the table borders
43
* @var Zend_Text_Table_Decorator_Interface
45
protected $_decorator = null;
48
* List of all column widths
52
protected $_columnWidths = null;
59
protected $_rows = array();
62
* Auto separation mode
66
protected $_autoSeparate = self::AUTO_SEPARATE_ALL;
73
protected $_padding = 0;
76
* Default column aligns for rows created by appendRow(array $data)
80
protected $_defaultColumnAligns = array();
83
* Plugin loader for decorators
87
protected $_pluginLoader = null;
90
* Charset which is used for input by default
94
protected static $_inputCharset = 'utf-8';
97
* Charset which is used internally
101
protected static $_outputCharset = 'utf-8';
104
* Option keys to skip when calling setOptions()
108
protected $_skipOptions = array(
111
'defaultColumnAlign',
115
* Create a basic table object
117
* @param array $columnsWidths List of all column widths
118
* @param Zend_Config|array $options Configuration options
119
* @throws Zend_Text_Table_Exception When no columns widths were set
121
public function __construct($options = null)
124
if (is_array($options)) {
125
$this->setOptions($options);
126
} else if ($options instanceof Zend_Config) {
127
$this->setConfig($options);
130
// Check if column widths were set
131
// @todo When column widths were not set, assume auto-sizing
132
if ($this->_columnWidths === null) {
133
require_once 'Zend/Text/Table/Exception.php';
134
throw new Zend_Text_Table_Exception('You must define the column widths');
137
// If no decorator was given, use default unicode decorator
138
if ($this->_decorator === null) {
139
if (self::getOutputCharset() === 'utf-8') {
140
$this->setDecorator('unicode');
142
$this->setDecorator('ascii');
148
* Set options from array
150
* @param array $options Configuration for Zend_Text_Table
151
* @return Zend_Text_Table
153
public function setOptions(array $options)
155
foreach ($options as $key => $value) {
156
if (in_array(strtolower($key), $this->_skipOptions)) {
160
$method = 'set' . ucfirst($key);
161
if (method_exists($this, $method)) {
162
$this->$method($value);
170
* Set options from config object
172
* @param Zend_Config $config Configuration for Zend_Text_Table
173
* @return Zend_Text_Table
175
public function setConfig(Zend_Config $config)
177
return $this->setOptions($config->toArray());
183
* @param array $columnWidths Widths of all columns
184
* @throws Zend_Text_Table_Exception When no columns were supplied
185
* @throws Zend_Text_Table_Exception When a column has an invalid width
186
* @return Zend_Text_Table
188
public function setColumnWidths(array $columnWidths)
190
if (count($columnWidths) === 0) {
191
require_once 'Zend/Text/Table/Exception.php';
192
throw new Zend_Text_Table_Exception('You must supply at least one column');
195
foreach ($columnWidths as $columnNum => $columnWidth) {
196
if (is_int($columnWidth) === false or $columnWidth < 1) {
197
require_once 'Zend/Text/Table/Exception.php';
198
throw new Zend_Text_Table_Exception('Column ' . $columnNum . ' has an invalid'
203
$this->_columnWidths = $columnWidths;
209
* Set auto separation mode
211
* @param integer $autoSeparate Auto separation mode
212
* @return Zend_Text_Table
214
public function setAutoSeparate($autoSeparate)
216
$this->_autoSeparate = (int) $autoSeparate;
223
* @param Zend_Text_Table_Decorator_Interface|string $decorator Decorator to use
224
* @return Zend_Text_Table
226
public function setDecorator($decorator)
228
if ($decorator instanceof Zend_Text_Table_Decorator_Interface) {
229
$this->_decorator = $decorator;
231
$classname = $this->getPluginLoader()->load($decorator);
232
$this->_decorator = new $classname;
239
* Set the column padding
241
* @param integer $padding The padding for the columns
242
* @return Zend_Text_Table
244
public function setPadding($padding)
246
$this->_padding = max(0, (int) $padding);
251
* Get the plugin loader for decorators
253
* @return Zend_Loader_PluginLoader
255
public function getPluginLoader()
257
if ($this->_pluginLoader === null) {
258
$prefix = 'Zend_Text_Table_Decorator_';
259
$pathPrefix = 'Zend/Text/Table/Decorator/';
261
require_once 'Zend/Loader/PluginLoader.php';
262
$this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix));
265
return $this->_pluginLoader;
269
* Set default column align for rows created by appendRow(array $data)
271
* @param integer $columnNum
272
* @param string $align
273
* @return Zend_Text_Table
275
public function setDefaultColumnAlign($columnNum, $align)
277
$this->_defaultColumnAligns[$columnNum] = $align;
283
* Set the input charset for column contents
285
* @param string $charset
287
public static function setInputCharset($charset)
289
self::$_inputCharset = strtolower($charset);
293
* Get the input charset for column contents
295
* @param string $charset
297
public static function getInputCharset()
299
return self::$_inputCharset;
303
* Set the output charset for column contents
305
* @param string $charset
307
public static function setOutputCharset($charset)
309
self::$_outputCharset = strtolower($charset);
313
* Get the output charset for column contents
315
* @param string $charset
317
public static function getOutputCharset()
319
return self::$_outputCharset;
323
* Append a row to the table
325
* @param array|Zend_Text_Table_Row $row The row to append to the table
326
* @throws Zend_Text_Table_Exception When $row is neither an array nor Zend_Zext_Table_Row
327
* @throws Zend_Text_Table_Exception When a row contains too many columns
328
* @return Zend_Text_Table
330
public function appendRow($row)
332
if (!is_array($row) && !($row instanceof Zend_Text_Table_Row)) {
333
require_once 'Zend/Text/Table/Exception.php';
334
throw new Zend_Text_Table_Exception('$row must be an array or instance of Zend_Text_Table_Row');
337
if (is_array($row)) {
338
if (count($row) > count($this->_columnWidths)) {
339
require_once 'Zend/Text/Table/Exception.php';
340
throw new Zend_Text_Table_Exception('Row contains too many columns');
343
require_once 'Zend/Text/Table/Row.php';
346
$row = new Zend_Text_Table_Row();
348
foreach ($data as $columnData) {
349
if (isset($this->_defaultColumnAligns[$colNum])) {
350
$align = $this->_defaultColumnAligns[$colNum];
355
$row->appendColumn(new Zend_Text_Table_Column($columnData, $align));
360
$this->_rows[] = $row;
368
* @throws Zend_Text_Table_Exception When no rows were added to the table
371
public function render()
373
// There should be at least one row
374
if (count($this->_rows) === 0) {
375
require_once 'Zend/Text/Table/Exception.php';
376
throw new Zend_Text_Table_Exception('No rows were added to the table yet');
379
// Initiate the result variable
382
// Count total columns
383
$totalNumColumns = count($this->_columnWidths);
385
// Now render all rows, starting from the first one
386
$numRows = count($this->_rows);
387
foreach ($this->_rows as $rowNum => $row) {
388
// Get all column widths
389
if (isset($columnWidths) === true) {
390
$lastColumnWidths = $columnWidths;
393
$renderedRow = $row->render($this->_columnWidths, $this->_decorator, $this->_padding);
394
$columnWidths = $row->getColumnWidths();
395
$numColumns = count($columnWidths);
397
// Check what we have to draw
399
// If this is the first row, draw the table top
400
$result .= $this->_decorator->getTopLeft();
402
foreach ($columnWidths as $columnNum => $columnWidth) {
403
$result .= str_repeat($this->_decorator->getHorizontal(),
406
if (($columnNum + 1) === $numColumns) {
407
$result .= $this->_decorator->getTopRight();
409
$result .= $this->_decorator->getHorizontalDown();
415
// Else check if we have to draw the row separator
416
if ($this->_autoSeparate & self::AUTO_SEPARATE_ALL) {
417
$drawSeparator = true;
418
} else if ($rowNum === 1 && $this->_autoSeparate & self::AUTO_SEPARATE_HEADER) {
419
$drawSeparator = true;
420
} else if ($rowNum === ($numRows - 1) && $this->_autoSeparate & self::AUTO_SEPARATE_FOOTER) {
421
$drawSeparator = true;
423
$drawSeparator = false;
426
if ($drawSeparator) {
427
$result .= $this->_decorator->getVerticalRight();
429
$currentUpperColumn = 0;
430
$currentLowerColumn = 0;
431
$currentUpperWidth = 0;
432
$currentLowerWidth = 0;
434
// Loop through all column widths
435
foreach ($this->_columnWidths as $columnNum => $columnWidth) {
436
// Add the horizontal line
437
$result .= str_repeat($this->_decorator->getHorizontal(),
440
// If this is the last line, break out
441
if (($columnNum + 1) === $totalNumColumns) {
445
// Else check, which connector style has to be used
447
$currentUpperWidth += $columnWidth;
448
$currentLowerWidth += $columnWidth;
450
if ($lastColumnWidths[$currentUpperColumn] === $currentUpperWidth) {
452
$currentUpperColumn += 1;
453
$currentUpperWidth = 0;
455
$currentUpperWidth += 1;
458
if ($columnWidths[$currentLowerColumn] === $currentLowerWidth) {
460
$currentLowerColumn += 1;
461
$currentLowerWidth = 0;
463
$currentLowerWidth += 1;
466
switch ($connector) {
468
$result .= $this->_decorator->getHorizontal();
472
$result .= $this->_decorator->getHorizontalUp();
476
$result .= $this->_decorator->getHorizontalDown();
480
$result .= $this->_decorator->getCross();
484
// This can never happen, but the CS tells I have to have it ...
489
$result .= $this->_decorator->getVerticalLeft() . "\n";
493
// Add the rendered row to the result
494
$result .= $renderedRow;
496
// If this is the last row, draw the table bottom
497
if (($rowNum + 1) === $numRows) {
498
$result .= $this->_decorator->getBottomLeft();
500
foreach ($columnWidths as $columnNum => $columnWidth) {
501
$result .= str_repeat($this->_decorator->getHorizontal(),
504
if (($columnNum + 1) === $numColumns) {
505
$result .= $this->_decorator->getBottomRight();
507
$result .= $this->_decorator->getHorizontalUp();
519
* Magic method which returns the rendered table
523
public function __toString()
526
return $this->render();
527
} catch (Exception $e) {
528
trigger_error($e->getMessage(), E_USER_ERROR);