/library/Zend/Text/Table/Row.php

https://github.com/zucchi/zf2 · PHP · 199 lines · 88 code · 32 blank · 79 comment · 9 complexity · 557c5e54c311b49253a07c7faf7dfb67 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Text
  9. */
  10. namespace Zend\Text\Table;
  11. use Zend\Text\Table\Decorator\DecoratorInterface as Decorator;
  12. /**
  13. * Row class for Zend\Text\Table
  14. *
  15. * @category Zend
  16. * @package Zend_Text_Table
  17. */
  18. class Row
  19. {
  20. /**
  21. * List of all columns
  22. *
  23. * @var array
  24. */
  25. protected $columns = array();
  26. /**
  27. * Temporary stored column widths
  28. *
  29. * @var array
  30. */
  31. protected $columnWidths = null;
  32. /**
  33. * Create a new column and append it to the row
  34. *
  35. * @param string $content
  36. * @param array $options
  37. * @return Row
  38. */
  39. public function createColumn($content, array $options = null)
  40. {
  41. $align = null;
  42. $colSpan = null;
  43. $encoding = null;
  44. if ($options !== null) {
  45. extract($options, EXTR_IF_EXISTS);
  46. }
  47. $column = new Column($content, $align, $colSpan, $encoding);
  48. $this->appendColumn($column);
  49. return $this;
  50. }
  51. /**
  52. * Append a column to the row
  53. *
  54. * @param \Zend\Text\Table\Column $column The column to append to the row
  55. * @return Row
  56. */
  57. public function appendColumn(Column $column)
  58. {
  59. $this->columns[] = $column;
  60. return $this;
  61. }
  62. /**
  63. * Get a column by it's index
  64. *
  65. * Returns null, when the index is out of range
  66. *
  67. * @param integer $index
  68. * @return Column|null
  69. */
  70. public function getColumn($index)
  71. {
  72. if (!isset($this->columns[$index])) {
  73. return null;
  74. }
  75. return $this->columns[$index];
  76. }
  77. /**
  78. * Get all columns of the row
  79. *
  80. * @return array
  81. */
  82. public function getColumns()
  83. {
  84. return $this->columns;
  85. }
  86. /**
  87. * Get the widths of all columns, which were rendered last
  88. *
  89. * @throws Exception\UnexpectedValueException When no columns were rendered yet
  90. * @return integer
  91. */
  92. public function getColumnWidths()
  93. {
  94. if ($this->columnWidths === null) {
  95. throw new Exception\UnexpectedValueException('render() must be called before columnWidths can be populated');
  96. }
  97. return $this->columnWidths;
  98. }
  99. /**
  100. * Render the row
  101. *
  102. * @param array $columnWidths Width of all columns
  103. * @param Decorator $decorator Decorator for the row borders
  104. * @param integer $padding Padding for the columns
  105. * @throws Exception\OverflowException When there are too many columns
  106. * @return string
  107. */
  108. public function render(array $columnWidths, Decorator $decorator, $padding = 0)
  109. {
  110. // Prepare an array to store all column widths
  111. $this->columnWidths = array();
  112. // If there is no single column, create a column which spans over the
  113. // entire row
  114. if (count($this->columns) === 0) {
  115. $this->appendColumn(new Column(null, null, count($columnWidths)));
  116. }
  117. // First we have to render all columns, to get the maximum height
  118. $renderedColumns = array();
  119. $maxHeight = 0;
  120. $colNum = 0;
  121. foreach ($this->columns as $column) {
  122. // Get the colspan of the column
  123. $colSpan = $column->getColSpan();
  124. // Verify if there are enough column widths defined
  125. if (($colNum + $colSpan) > count($columnWidths)) {
  126. throw new Exception\OverflowException('Too many columns');
  127. }
  128. // Calculate the column width
  129. $columnWidth = ($colSpan - 1 + array_sum(array_slice($columnWidths,
  130. $colNum,
  131. $colSpan)));
  132. // Render the column and split it's lines into an array
  133. $result = explode("\n", $column->render($columnWidth, $padding));
  134. // Store the width of the rendered column
  135. $this->columnWidths[] = $columnWidth;
  136. // Store the rendered column and calculate the new max height
  137. $renderedColumns[] = $result;
  138. $maxHeight = max($maxHeight, count($result));
  139. // Set up the internal column number
  140. $colNum += $colSpan;
  141. }
  142. // If the row doesnt contain enough columns to fill the entire row, fill
  143. // it with an empty column
  144. if ($colNum < count($columnWidths)) {
  145. $remainingWidth = (count($columnWidths) - $colNum - 1) +
  146. array_sum(array_slice($columnWidths,
  147. $colNum));
  148. $renderedColumns[] = array(str_repeat(' ', $remainingWidth));
  149. $this->columnWidths[] = $remainingWidth;
  150. }
  151. // Add each single column line to the result
  152. $result = '';
  153. for ($line = 0; $line < $maxHeight; $line++) {
  154. $result .= $decorator->getVertical();
  155. foreach ($renderedColumns as $index => $renderedColumn) {
  156. if (isset($renderedColumn[$line]) === true) {
  157. $result .= $renderedColumn[$line];
  158. } else {
  159. $result .= str_repeat(' ', $this->columnWidths[$index]);
  160. }
  161. $result .= $decorator->getVertical();
  162. }
  163. $result .= "\n";
  164. }
  165. return $result;
  166. }
  167. }