## Apache Zeta Components Manual :: File Source for table.php

## Source for file table.php

Documentation is available at table.php

1. <?php
2. /**
3. * File containing the ezcConsoleTable class.
4. *
5. * Licensed to the Apache Software Foundation (ASF) under one
6. * or more contributor license agreements. See the NOTICE file
7. * distributed with this work for additional information
8. * regarding copyright ownership. The ASF licenses this file
9. * to you under the Apache License, Version 2.0 (the
10. * "License"); you may not use this file except in compliance
11. * with the License. You may obtain a copy of the License at
12. *
13. * http://www.apache.org/licenses/LICENSE-2.0
14. *
15. * Unless required by applicable law or agreed to in writing,
16. * software distributed under the License is distributed on an
17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18. * KIND, either express or implied. See the License for the
19. * specific language governing permissions and limitations
20. * under the License.
21. *
22. * @package ConsoleTools
23. * @version //autogentag//
24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
25. * @filesource
26. */
28. /**
29. * Creating tables to be printed to the console.
30. *
31. * Every ezcConsoleTable object can be accessed as if it was a multidimensional,
32. * numerically indexed array. The first dimension represents the rows of the
33. * table, so $table[0] gives you access to the first row of the table, which is
34. * represented by a {@link ezcConsoleTableRow} object. You can access its
35. * properties directly, using e.g. $table[0]->format. The second dimension gives
36. * you direct access to the cells of your table, like $table[0][0] accesses the
37. * first cell in the first row of your table. You can access its properties
38. * diretly here, too. This works like e.g. $table[0][0]->format. Table row and
39. * cell objects are created on the fly, when you access them for the first time.
40. * You can also create them as if you simply create new array elements. E.g.
41. * $table[] creates a new row in the table.
42. *
43. * <code>
44. * // Initialize the console output handler
45. * $out = new ezcConsoleOutput();
46. * // Define a new format "headline"
47. * $out->formats->headline->color = 'red';
48. * $out->formats->headline->style = array( 'bold' );
49. * // Define a new format "sum"
50. * $out->formats->sum->color = 'blue';
51. * $out->formats->sum->style = array( 'negative' );
52. *
53. * // Create a new table
54. * $table = new ezcConsoleTable( $out, 60 );
55. *
56. * // Create first row and in it the first cell
57. * $table[0][0]->content = 'Headline 1';
58. *
59. * // Create 3 more cells in row 0
60. * for ( $i = 2; $i < 5; $i++ )
61. * {
62. * $table[0][]->content = "Headline $i";
63. * }
64. *
65. * $data = array( 1, 2, 3, 4 );
66. *
67. * // Create some more data in the table...
68. * foreach ( $data as $value )
69. * {
70. * // Create a new row each time and set it's contents to the actual value
71. * $table[][0]->content = $value;
72. * }
73. *
74. * // Set another border format for our headline row
75. * $table[0]->borderFormat = 'headline';
76. *
77. * // Set the content format for all cells of the 3rd row to "sum"
78. * $table[2]->format = 'sum';
79. *
80. * $table->outputTable();
81. * </code>
82. *
83. * @property ezcConsoleTableOptions $options
84. * Contains the options for this class.
85. * @property int $width
86. * Width of the table.
87. *
88. * @see ezcConsoleOutput
89. * @package ConsoleTools
90. * @version //autogen//
91. * @mainclass
92. */
93. class ezcConsoleTable implements Countable, Iterator, ArrayAccess
94. {
95. /**
96. * Automatically wrap text to fit into a column.
97. * @see ezcConsoleTable::$options
98. */
99. const WRAP_AUTO = 1;
101. /**
102. * Do not wrap text. Columns will be extended to fit the largest text.
103. * ATTENTION: This is risky!
104. * @see ezcConsoleTable::$options
105. */
106. const WRAP_NONE = 2;
108. /**
109. * Text will be cut to fit into a column.
110. * @see ezcConsoleTable::$options
111. */
112. const WRAP_CUT = 3;
114. /**
115. * Align text in the default direction.
116. */
117. const ALIGN_DEFAULT = -1;
118. /**
119. * Align text in cells to the right.
120. */
121. const ALIGN_LEFT = STR_PAD_RIGHT;
122. /**
123. * Align text in cells to the left.
124. */
125. const ALIGN_RIGHT = STR_PAD_LEFT;
126. /**
127. * Align text in cells to the center.
128. */
129. const ALIGN_CENTER = STR_PAD_BOTH;
131. /**
132. * The width given by settings must be used even if the data allows it smaller.
133. */
134. const WIDTH_FIXED = 1;
135. /**
136. * The width given by settings is a maximum value, if data allows it, the table gets smaller.
137. */
138. const WIDTH_MAX = 2;
140. /**
141. * Container to hold the properties
142. *
143. * @var array(string=>mixed)
144. */
145. protected $properties ;
147. /**
148. * The ezcConsoleOutput object to use.
149. *
150. * @var ezcConsoleOutput
151. */
152. protected $outputHandler ;
154. /**
155. * Collection of the rows that are contained in the table.
156. *
157. * @var array(ezcConsoleTableRow)
158. */
159. protected $rows ;
161. /**
162. * Tool object for multi-byte encoding safe string operations.
163. *
164. * @var ezcConsoleStringTool
165. */
166. private $stringTool;
168. /**
169. * Creates a new table.
170. *
171. * @param ezcConsoleOutput $outHandler Output handler to utilize
172. * @param int $width Overall width of the table (chars).
173. * @param array $options Options
174. *
175. * @see ezcConsoleTable::$options
176. *
177. * @throws ezcBaseValueException On an invalid setting.
178. */
179. public function __construct ( ezcConsoleOutput $outHandler, $width, $options = array() )
180. {
181. $this-> rows = array();
182. $this-> outputHandler = $outHandler;
183. $this->stringTool = new ezcConsoleStringTool();
185. $this->__set( 'width', $width );
186. if ( $options instanceof ezcConsoleTableOptions )
187. {
188. $this-> properties ['options'] = $options;
189. }
190. else if ( is_array ( $options ) )
191. {
192. $this-> properties ['options'] = new ezcConsoleTableOptions ( $options );
193. }
194. else
195. {
196. throw new ezcBaseValueException ( "options", $options, "array" );
197. }
198. }
200. /**
201. * Set new options.
202. * This method allows you to change the options of the table.
203. *
204. * @param ezcConsoleTableOptions $options The options to set.
205. *
206. * @throws ezcBaseSettingNotFoundException
207. * If you tried to set a non-existent option value.
208. * @throws ezcBaseSettingValueException
209. * If the value is not valid for the desired option.
210. * @throws ezcBaseValueException
211. * If you submit neither an array nor an instance of
212. * ezcConsoleTableOptions.
213. */
214. public function setOptions ( $options = array() )
215. {
216. if ( is_array ( $options ) )
217. {
218. $this-> properties ['options']->merge( $options );
219. }
220. else if ( $options instanceof ezcConsoleTableOptions )
221. {
222. $this-> properties ['options'] = $options;
223. }
224. else
225. {
226. throw new ezcBaseValueException ( "options", $options, "instance of ezcConsoleTableOptions" );
227. }
228. }
230. /**
231. * Returns the current options.
232. * Returns the options currently set for this table.
233. *
234. * @return ezcConsoleTableOptions The current options.
235. */
236. public function getOptions ()
237. {
238. return $this-> properties ['options'];
239. }
241. /**
242. * Returns the table in an array.
243. *
244. * Returns the entire table as an array of printable lines. Each element of
245. * the array represents a physical line of the drawn table, including all
246. * borders and stuff, so you can simply print the table using
247. * <code>
248. * echo implode( "\n" , $table->getTable() ):
249. * </code>
250. * which is basically what {@link ezcConsoleTable::outputTable()} does.
251. *
252. * @return array An array representation of the table.
253. */
254. public function getTable ()
255. {
256. return $this->generateTable();
257. }
259. /**
260. * Output the table.
261. * Prints the complete table to the console.
262. *
263. * @return void
264. */
265. public function outputTable ()
266. {
267. echo implode ( PHP_EOL, $this->generateTable() );
268. }
270. /**
271. * Returns the table in a string.
272. *
273. * @return string
274. */
275. public function __toString ()
276. {
277. return implode ( PHP_EOL, $this->generateTable() );
278. }
280. /**
281. * Returns if the given offset exists.
282. * This method is part of the ArrayAccess interface to allow access to the
283. * data of this object as if it was an array.
284. *
285. * @param int $offset The offset to check.
286. * @return bool True when the offset exists, otherwise false.
287. *
288. * @throws ezcBaseValueException
289. * If a non numeric row ID is requested.
290. */
291. public function offsetExists ( $offset )
292. {
293. if ( ! is_int ( $offset ) || $offset < 0 )
294. {
295. throw new ezcBaseValueException ( 'offset', $offset, 'int >= 0' );
296. }
297. return isset( $this-> rows [$offset] );
298. }
300. // From here only interface method implementations follow, which are not intended for direct usage
302. /**
303. * Returns the element with the given offset.
304. * This method is part of the ArrayAccess interface to allow access to the
305. * data of this object as if it was an array. In case of the
306. * ezcConsoleTable class this method always returns a valid row object
307. * since it creates them on the fly, if a given item does not exist.
308. *
309. * @param int $offset The offset to check.
310. * @return ezcConsoleTableCell
311. *
312. * @throws ezcBaseValueException
313. * If a non numeric row ID is requested.
314. */
315. public function offsetGet ( $offset )
316. {
317. $offset = ( $offset === null ) ? count ( $this-> rows ) : $offset;
318. if ( ! is_int ( $offset ) || $offset < 0 )
319. {
320. throw new ezcBaseValueException ( 'offset', $offset, 'int >= 0 or null' );
321. }
322. if ( !isset( $this-> rows [$offset] ) )
323. {
324. $this-> rows [$offset] = new ezcConsoleTableRow ();
325. }
326. return $this-> rows [$offset];
327. }
329. /**
330. * Set the element with the given offset.
331. * This method is part of the ArrayAccess interface to allow access to the
332. * data of this object as if it was an array.
333. *
334. * @param int $offset The offset to assign an item to.
335. * @param ezcConsoleTableRow $value The row to assign.
336. * @return void
337. *
338. * @throws ezcBaseValueException
339. * If a non numeric row ID is requested.
340. * @throws ezcBaseValueException
341. * If the provided value is not of type {@link ezcConsoleTableRow}.
342. */
343. public function offsetSet ( $offset, $value )
344. {
345. if ( !( $value instanceof ezcConsoleTableRow ) )
346. {
347. throw new ezcBaseValueException ( 'value', $value, 'ezcConsoleTableRow' );
348. }
349. if ( !isset( $offset ) )
350. {
351. $offset = count ( $this );
352. }
353. if ( ! is_int ( $offset ) || $offset < 0 )
354. {
355. throw new ezcBaseValueException ( 'offset', $offset, 'int >= 0' );
356. }
357. $this-> rows [$offset] = $value;
358. }
360. /**
361. * Unset the element with the given offset.
362. * This method is part of the ArrayAccess interface to allow access to the
363. * data of this object as if it was an array.
364. *
365. * @param int $offset The offset to unset the value for.
366. * @return void
367. *
368. * @throws ezcBaseValueException
369. * If a non numeric row ID is requested.
370. */
371. public function offsetUnset ( $offset )
372. {
373. if ( ! is_int ( $offset ) || $offset < 0 )
374. {
375. throw new ezcBaseValueException ( 'offset', $offset, 'int >= 0' );
376. }
377. if ( isset( $this-> rows [$offset] ) )
378. {
379. unset( $this-> rows [$offset] );
380. }
381. }
383. /**
384. * Returns the number of cells in the row.
385. * This method is part of the Countable interface to allow the usage of
386. * PHP's count() function to check how many cells this row has.
387. *
388. * @return int Number of cells in this row.
389. */
390. public function count ()
391. {
392. $keys = array_keys ( $this-> rows );
393. return count ( $keys ) > 0 ? ( end ( $keys ) + 1 ) : 0;
394. }
396. /**
397. * Returns the currently selected cell.
398. * This method is part of the Iterator interface to allow access to the
399. * cells of this row by iterating over it like an array (e.g. using
400. * foreach).
401. *
402. * @return ezcConsoleTableCell The currently selected cell.
403. */
404. public function current ()
405. {
406. return current ( $this-> rows );
407. }
409. /**
410. * Returns the key of the currently selected cell.
411. * This method is part of the Iterator interface to allow access to the
412. * cells of this row by iterating over it like an array (e.g. using
413. * foreach).
414. *
415. * @return int The key of the currently selected cell.
416. */
417. public function key ()
418. {
419. return key ( $this-> rows );
420. }
422. /**
423. * Returns the next cell and selects it or false on the last cell.
424. * This method is part of the Iterator interface to allow access to the
425. * cells of this row by iterating over it like an array (e.g. using
426. * foreach).
427. *
428. * @return mixed ezcConsoleTableCell if the next cell exists, or false.
429. */
430. public function next ()
431. {
432. return next ( $this-> rows );
433. }
435. /**
436. * Selects the very first cell and returns it.
437. * This method is part of the Iterator interface to allow access to the
438. * cells of this row by iterating over it like an array (e.g. using
439. * foreach).
440. *
441. * @return ezcConsoleTableCell The very first cell of this row.
442. */
443. public function rewind ()
444. {
445. return reset ( $this-> rows );
446. }
448. /**
449. * Returns if the current cell is valid.
450. * This method is part of the Iterator interface to allow access to the
451. * cells of this row by iterating over it like an array (e.g. using
452. * foreach).
453. *
454. * @return ezcConsoleTableCell The very first cell of this row.
455. */
456. public function valid ()
457. {
458. return current ( $this-> rows ) !== false;
459. }
461. /**
462. * Property read access.
463. *
464. * @param string $key Name of the property.
465. * @return mixed Value of the property or null.
466. *
467. * @throws ezcBasePropertyNotFoundException
468. * If the the desired property is not found.
469. * @ignore
470. */
471. public function __get( $key )
472. {
473. switch ( $key )
474. {
475. case 'options':
476. case 'width':
477. return $this-> properties [$key];
478. default:
479. break;
480. }
481. throw new ezcBasePropertyNotFoundException ( $key );
482. }
484. /**
485. * Property write access.
486. *
487. * @param string $key Name of the property.
488. * @param mixed $val The value for the property.
489. *
490. * @throws ezcBasePropertyNotFoundException
491. * If a the value for the property options is not an instance of
492. * @throws ezcBaseValueException
493. * If a the value for a property is out of range.
494. * @ignore
495. */
496. public function __set( $key, $val )
497. {
498. switch ( $key )
499. {
500. case 'options':
501. if ( !( $val instanceof ezcConsoleTableOptions ) )
502. {
503. throw new ezcBaseValueException ( $key, $val, 'ezcConsoleTableOptions' );
504. }
505. $this-> properties ['options'] = $val;
506. return;
507. case 'width':
508. if ( $val < 1 )
509. {
510. throw new ezcBaseValueException ( $key, $val, 'int > 0' );
511. }
512. $this-> properties [$key] = $val;
513. return;
514. default:
515. break;
516. }
517. throw new ezcBasePropertyNotFoundException ( $key );
518. }
520. /**
521. * Property isset access.
522. *
523. * @param string $key Name of the property.
524. * @return bool True is the property is set, otherwise false.
525. * @ignore
526. */
527. public function __isset( $key )
528. {
529. switch ( $key )
530. {
531. case 'options':
532. case 'width':
533. case 'cols':
534. return true;
535. }
536. return false;
537. }
539. /**
540. * Generate the complete table as an array.
541. *
542. * @return array(string) The table.
543. */
544. private function generateTable()
545. {
546. $colWidth = $this->getColWidths();
547. $table = array();
549. if ( $this->options->lineVertical !== null )
550. {
551. $table[] = $this->generateBorder(
552. $colWidth,
553. ( isset( $this[0] ) ? $this[0]->borderFormat : 'default' )
554. );
555. }
557. // Rows submitted by the user
558. for ( $i = 0; $i < count ( $this-> rows ); $i++ )
559. {
560. // Auto broken rows
561. foreach ( $this->breakRows( $this-> rows [$i], $colWidth ) as $brkRow => $brkCells )
562. {
563. $table[] = $this->generateRow( $brkCells, $colWidth, $this-> rows [$i] );
564. }
565. $afterBorderFormat = isset( $this-> rows [$i + 1] ) && $this-> rows [$i + 1]->borderFormat != 'default' ? $this-> rows [$i + 1]->borderFormat : $this-> rows [$i]->borderFormat;
566. if ( $this->options->lineVertical !== null )
567. {
568. $table[] = $this->generateBorder( $colWidth, $afterBorderFormat );
569. }
570. }
572. // Empty tables need closing border
573. if ( $this->options->lineVertical !== null && count ( $this-> rows ) == null )
574. {
575. $table[] = $this->generateBorder( $colWidth, 'default' );
576. }
578. return $table;
579. }
581. /**
582. * Generate top/bottom borders of rows.
583. *
584. * @param array(int) $colWidth Array of column width.
585. * @param string $format Format name.
586. * @return string The Border string.
587. */
588. private function generateBorder( $colWidth, $format )
589. {
590. $border = '';
591. foreach ( $colWidth as $col => $width )
592. {
593. $border .= ( $this->options->lineHorizontal !== null ? $this-> properties ['options']->corner : '' )
594. . str_repeat (
595. $this-> properties ['options']->lineVertical,
596. $width + (
597. 2 * iconv_strlen ( $this-> properties ['options']->colPadding, 'UTF-8' )
598. )
599. );
600. }
601. $border .= ( $this->options->lineHorizontal !== null ? $this-> properties ['options']->corner : '' );
603. return $this->formatText( $border, $format );
604. }
606. /**
607. * Generate a single physical row.
608. * This method generates the string for a single physical table row.
609. *
610. * @param array(string) $cells Cells of the row.
611. * @param array(int) $colWidth Calculated columns widths.
612. * @param ezcConsoleTableRow $row The row to generate.
613. * @return string The row.
614. */
615. private function generateRow( $cells, $colWidth, $row )
616. {
617. $rowData = '';
618. for ( $cell = 0; $cell < count ( $colWidth ); $cell++ )
619. {
620. $align = $this->determineAlign( $row, $cell );
621. $format = $this->determineFormat( $row, $cell );
622. $borderFormat = $this->determineBorderFormat( $row );
624. $data = isset( $cells[$cell] ) ? $cells[$cell] : '';
625. $rowData .= $this->formatText(
626. $this-> properties ['options']->lineHorizontal,
627. $borderFormat
628. );
629. $rowData .= $this-> properties ['options']->colPadding;
630. $rowData .= $this->formatText(
631. $this->stringTool->strPad( $data, $colWidth[$cell], ' ', $align ),
632. $format
633. );
634. $rowData .= $this-> properties ['options']->colPadding;
635. }
636. $rowData .= $this->formatText( $this-> properties ['options']->lineHorizontal, $row->borderFormat );
637. return $rowData;
638. }
640. /**
641. * Determine the alignment of a cell.
642. * Walks the inheritance path upwards to determine the alignment of a
643. * cell. Checks first, if the cell has it's own alignment (apart from
644. * ezcConsoleTable::ALIGN_DEFAULT). If not, checks the row for an
645. * alignment setting and uses the default alignment if not found.
646. *
647. * @param ezcConsoleTableRow $row The row this cell belongs to.
648. * @param int $cellId Index of the desired cell.
649. * @return int An alignement constant (ezcConsoleTable::ALIGN_*).
650. */
651. private function determineAlign( $row, $cellId = 0 )
652. {
653. return ( $row[$cellId]->align !== ezcConsoleTable ::ALIGN_DEFAULT
654. ? $row[$cellId]->align
655. : ( $row->align !== ezcConsoleTable ::ALIGN_DEFAULT
656. ? $row->align
657. : ( $this-> properties ['options']->defaultAlign !== ezcConsoleTable ::ALIGN_DEFAULT
658. ? $this-> properties ['options']->defaultAlign
659. : ezcConsoleTable ::ALIGN_LEFT ) ) );
660. }
662. /**
663. * Determine the format of a cells content.
664. * Walks the inheritance path upwards to determine the format of a
665. * cells content. Checks first, if the cell has it's own format (apart
666. * from 'default'). If not, checks the row for a format setting and
667. * uses the default format if not found.
668. *
669. * @param ezcConsoleTableRow $row The row this cell belongs to.
670. * @param int $cellId Index of the desired cell.
671. * @return string A format name.
672. */
673. private function determineFormat( $row, $cellId )
674. {
675. return ( $row[$cellId]->format != 'default'
676. ? $row[$cellId]->format
677. : ( $row->format !== 'default'
678. ? $row->format
679. : $this-> properties ['options']->defaultFormat ) );
680. }
682. /**
683. * Determine the format of a rows border.
684. * Walks the inheritance path upwards to determine the format of a
685. * rows border. Checks first, if the row has it's own format (apart
686. * from 'default'). If not, uses the default format.
687. *
688. * @param ezcConsoleTableRow $row The row this cell belongs to.
689. * @return string A format name.
690. */
691. private function determineBorderFormat( $row )
692. {
693. return $row->borderFormat !== 'default'
694. ? $row->borderFormat
695. : $this-> properties ['options']->defaultBorderFormat;
696. }
698. /**
699. * Returns auto broken rows from an array of cells.
700. * The data provided by a user may not fit into a cell calculated by the
701. * class. In this case, the data can be automatically wrapped. The table
702. * row then spans over multiple physical console lines.
703. *
704. * @param array(string) $cells Array of cells in one row.
705. * @param array(int) $colWidth Columns widths array.
706. * @return array(string) Physical rows generated out of this row.
707. */
708. private function breakRows( $cells, $colWidth )
709. {
710. $rows = array();
711. // Iterate through cells of the row
712. foreach ( $colWidth as $cell => $width )
713. {
714. $data = $cells[$cell]->content;
715. // Physical row id, start with 0 for each row
716. $row = 0;
717. // Split into multiple physical rows if manual breaks exist
718. $dataLines = explode ( "\n", $data );
719. foreach ( $dataLines as $dataLine )
720. {
721. // Does the physical row fit?
722. if ( iconv_strlen ( $dataLine, 'UTF-8' ) > ( $colWidth[$cell] ) )
723. {
724. switch ( $this-> properties ['options']->colWrap )
725. {
726. case ezcConsoleTable ::WRAP_AUTO:
727. $subLines = explode (
728. "\n",
729. $this->stringTool->wordwrap( $dataLine, $colWidth[$cell], "\n", true )
730. );
731. foreach ( $subLines as $lineNo => $line )
732. {
733. $rows[$row++][$cell] = $line;
734. }
735. break;
736. case ezcConsoleTable ::WRAP_CUT:
737. $rows[$row++][$cell] = iconv_substr ( $dataLine, 0, $colWidth[$cell], 'UTF-8' );
738. break;
739. case ezcConsoleTable ::WRAP_NONE:
740. default:
741. $rows[$row++][$cell] = $dataLine;
742. break;
743. }
744. }
745. else
746. {
747. $rows[$row++][$cell] = $dataLine;
748. }
749. }
750. }
751. return $rows;
752. }
754. /**
755. * Determine width of each single column.
756. *
757. * @return void
758. */
759. private function getColWidths()
760. {
761. if ( is_array ( $this-> properties ['options']->colWidth ) )
762. {
763. return $this-> properties ['options']->colWidth;
764. }
766. // Determine number of columns:
767. $colCount = 0;
768. foreach ( $this-> rows as $row )
769. {
770. $colCount = max ( sizeof ( $row ), $colCount );
771. }
773. if ( $colCount === 0 )
774. {
775. return array( $this->width );
776. }
778. $borderWidth = iconv_strlen (
779. $this-> properties ['options']->lineHorizontal,
780. 'UTF-8'
781. );
783. // Subtract border and padding chars from global width
784. $globalWidth = $this->width
785. - (
786. // Per column: 2 * border padding + 1 border
787. $colCount * (
788. 2 * iconv_strlen ( $this-> properties ['options']->colPadding, 'UTF-8' )
789. + $borderWidth
790. )
791. // 1 Additional border
792. ) - $borderWidth;
794. // Width of a column if each is made equal
795. $colNormWidth = round ( $globalWidth / $colCount );
796. $colMaxWidth = array();
798. // Determine the longest data for each column
799. foreach ( $this-> rows as $row => $cells )
800. {
801. foreach ( $cells as $col => $cell )
802. {
803. $contentLength = 0;
804. foreach ( explode ( PHP_EOL, $cell->content ) as $contentRow )
805. {
806. $contentLength = max (
807. $contentLength,
808. iconv_strlen ( $contentRow, 'UTF-8' )
809. );
810. }
811. $colMaxWidth[$col] = isset( $colMaxWidth[$col] ) ? max ( $colMaxWidth[$col], $contentLength ) : $contentLength;
812. }
813. }
814. $colWidth = array();
815. $colWidthOverflow = array();
816. $spareWidth = 0;
818. // Make columns best fit
819. foreach ( $colMaxWidth as $col => $maxWidth )
820. {
821. // Does the largest data of the column fit into the average size
822. // + what we have in spare from earlier columns?
823. if ( $maxWidth <= ( $colNormWidth + $spareWidth ) )
824. {
825. // We fit in, make the column as large as necessary
826. $colWidth[$col] = $maxWidth;
827. $spareWidth += ( $colNormWidth - $maxWidth );
828. }
829. else
830. {
831. // Does not fit, use maximal possible width
832. $colWidth[$col] = $colNormWidth + $spareWidth;
833. $spareWidth = 0;
834. // Store overflow for second processing step
835. $colWidthOverflow[$col] = $maxWidth - $colWidth[$col];
836. }
837. }
839. // Do we have spare to give to the columns again?
840. if ( $spareWidth > 0 )
841. {
842. // Second processing step
843. if ( count ( $colWidthOverflow ) > 0 )
844. {
845. $overflowSum = array_sum ( $colWidthOverflow );
846. foreach ( $colWidthOverflow as $col => $overflow );
847. {
848. $colWidth[$col] += floor ( $overflow / $overflowSum * $spareWidth );
849. }
850. }
851. elseif ( $this-> properties ['options']->widthType === ezcConsoleTable ::WIDTH_FIXED )
852. {
853. $widthSum = array_sum ( $colWidth );
854. foreach ( $colWidth as $col => $width )
855. {
856. $colWidth[$col] += floor ( $width / $widthSum * $spareWidth );
857. }
858. }
859. }
861. // Finally sanitize values from rounding issues, if necessary
862. if ( ( $colSum = array_sum ( $colWidth ) ) != $globalWidth && $this-> properties ['options']->widthType === ezcConsoleTable ::WIDTH_FIXED )
863. {
864. $colWidth[ count ( $colWidth ) - 1] -= $colSum - $globalWidth;
865. }
866. return $colWidth;
867. }
869. /**
870. * Returns the given $text formatted with $format.
871. *
872. * In case $useFormats is set to false in the output handler, the text is
873. * returned as given, without any formatting.
874. *
875. * @param string $text
876. * @param string $format
877. * @return string
878. */
879. private function formatText( $text, $format )
880. {
881. if ( $this-> outputHandler ->options->useFormats )
882. {
883. return $this-> outputHandler -> formatText ( $text, $format );
884. }
885. else
886. {
887. return $text;
888. }
889. }
890. }
891. ?>

Documentation generated by phpDocumentor 1.4.3