Storage.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Storage class for HTML::Table data
  5. *
  6. * This class stores data for tables built with HTML_Table. When having
  7. * more than one instance, it can be used for grouping the table into the
  8. * parts <thead>...</thead>, <tfoot>...</tfoot> and <tbody>...</tbody>.
  9. *
  10. * PHP versions 4 and 5
  11. *
  12. * LICENSE:
  13. *
  14. * Copyright (c) 2005-2007, Adam Daniel <adaniel1@eesus.jnj.com>,
  15. * Bertrand Mansion <bmansion@mamasam.com>,
  16. * Mark Wiesemann <wiesemann@php.net>
  17. * All rights reserved.
  18. *
  19. * Redistribution and use in source and binary forms, with or without
  20. * modification, are permitted provided that the following conditions
  21. * are met:
  22. *
  23. * * Redistributions of source code must retain the above copyright
  24. * notice, this list of conditions and the following disclaimer.
  25. * * Redistributions in binary form must reproduce the above copyright
  26. * notice, this list of conditions and the following disclaimer in the
  27. * documentation and/or other materials provided with the distribution.
  28. * * The names of the authors may not be used to endorse or promote products
  29. * derived from this software without specific prior written permission.
  30. *
  31. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  32. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  33. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  35. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  36. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  37. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  38. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  39. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  40. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. * @category HTML
  44. * @package HTML_Table
  45. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  46. * @author Bertrand Mansion <bmansion@mamasam.com>
  47. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  48. * @version CVS: $Id: Storage.php,v 1.16 2007/04/29 16:31:06 wiesemann Exp $
  49. * @link http://pear.php.net/package/HTML_Table
  50. */
  51. /**
  52. * Storage class for HTML::Table data
  53. *
  54. * This class stores data for tables built with HTML_Table. When having
  55. * more than one instance, it can be used for grouping the table into the
  56. * parts <thead>...</thead>, <tfoot>...</tfoot> and <tbody>...</tbody>.
  57. *
  58. * @category HTML
  59. * @package HTML_Table
  60. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  61. * @author Bertrand Mansion <bmansion@mamasam.com>
  62. * @author Mark Wiesemann <wiesemann@php.net>
  63. * @copyright 2005-2006 The PHP Group
  64. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  65. * @version Release: @package_version@
  66. * @link http://pear.php.net/package/HTML_Table
  67. */
  68. class HTML_Table_Storage extends HTML_Common
  69. {
  70. /**
  71. * Value to insert into empty cells
  72. * @var string
  73. * @access private
  74. */
  75. var $_autoFill = '&nbsp;';
  76. /**
  77. * Automatically adds a new row or column if a given row or column index
  78. * does not exist
  79. * @var bool
  80. * @access private
  81. */
  82. var $_autoGrow = true;
  83. /**
  84. * Array containing the table structure
  85. * @var array
  86. * @access private
  87. */
  88. var $_structure = array();
  89. /**
  90. * Number of rows composing in the table
  91. * @var int
  92. * @access private
  93. */
  94. var $_rows = 0;
  95. /**
  96. * Number of column composing the table
  97. * @var int
  98. * @access private
  99. */
  100. var $_cols = 0;
  101. /**
  102. * Tracks the level of nested tables
  103. * @var int
  104. * @access private
  105. */
  106. var $_nestLevel = 0;
  107. /**
  108. * Whether to use <thead>, <tfoot> and <tbody> or not
  109. * @var bool
  110. * @access private
  111. */
  112. var $_useTGroups = false;
  113. /**
  114. * Class constructor
  115. * @param int $tabOffset
  116. * @param bool $useTGroups Whether to use <thead>, <tfoot> and
  117. * <tbody> or not
  118. * @access public
  119. */
  120. public function __construct($tabOffset = 0, $useTGroups = false)
  121. {
  122. parent::__construct(null, (int)$tabOffset);
  123. $this->_useTGroups = (boolean)$useTGroups;
  124. }
  125. /**
  126. * Sets the useTGroups value
  127. * @param boolean $useTGroups
  128. * @access public
  129. */
  130. public function setUseTGroups($useTGroups)
  131. {
  132. $this->_useTGroups = $useTGroups;
  133. }
  134. /**
  135. * Returns the useTGroups value
  136. * @access public
  137. * @return boolean
  138. */
  139. public function getUseTGroups()
  140. {
  141. return $this->_useTGroups;
  142. }
  143. /**
  144. * Sets the autoFill value
  145. * @param mixed $fill
  146. * @access public
  147. */
  148. public function setAutoFill($fill)
  149. {
  150. $this->_autoFill = $fill;
  151. }
  152. /**
  153. * Returns the autoFill value
  154. * @access public
  155. * @return mixed
  156. */
  157. public function getAutoFill()
  158. {
  159. return $this->_autoFill;
  160. }
  161. /**
  162. * Sets the autoGrow value
  163. * @param bool $fill
  164. * @access public
  165. */
  166. public function setAutoGrow($grow)
  167. {
  168. $this->_autoGrow = $grow;
  169. }
  170. /**
  171. * Returns the autoGrow value
  172. * @access public
  173. * @return mixed
  174. */
  175. public function getAutoGrow()
  176. {
  177. return $this->_autoGrow;
  178. }
  179. /**
  180. * Sets the number of rows in the table
  181. * @param int $rows
  182. * @access public
  183. */
  184. function setRowCount($rows)
  185. {
  186. $this->_rows = $rows;
  187. }
  188. /**
  189. * Sets the number of columns in the table
  190. * @param int $cols
  191. * @access public
  192. */
  193. function setColCount($cols)
  194. {
  195. $this->_cols = $cols;
  196. }
  197. /**
  198. * Returns the number of rows in the table
  199. * @access public
  200. * @return int
  201. */
  202. function getRowCount()
  203. {
  204. return $this->_rows;
  205. }
  206. /**
  207. * Gets the number of columns in the table
  208. *
  209. * If a row index is specified, the count will not take
  210. * the spanned cells into account in the return value.
  211. *
  212. * @param int Row index to serve for cols count
  213. * @access public
  214. * @return int
  215. */
  216. function getColCount($row = null)
  217. {
  218. if (!is_null($row)) {
  219. $count = 0;
  220. foreach ($this->_structure[$row] as $cell) {
  221. if (is_array($cell)) {
  222. $count++;
  223. }
  224. }
  225. return $count;
  226. }
  227. return $this->_cols;
  228. }
  229. /**
  230. * Sets a rows type 'TH' or 'TD'
  231. * @param int $row Row index
  232. * @param string $type 'TH' or 'TD'
  233. * @access public
  234. */
  235. function setRowType($row, $type)
  236. {
  237. for ($counter = 0; $counter < $this->_cols; $counter++) {
  238. $this->_structure[$row][$counter]['type'] = $type;
  239. }
  240. }
  241. /**
  242. * Sets a columns type 'TH' or 'TD'
  243. * @param int $col Column index
  244. * @param string $type 'TH' or 'TD'
  245. * @access public
  246. */
  247. function setColType($col, $type)
  248. {
  249. for ($counter = 0; $counter < $this->_rows; $counter++) {
  250. $this->_structure[$counter][$col]['type'] = $type;
  251. }
  252. }
  253. /**
  254. * Sets the cell attributes for an existing cell.
  255. *
  256. * If the given indices do not exist and autoGrow is true then the given
  257. * row and/or col is automatically added. If autoGrow is false then an
  258. * error is returned.
  259. * @param int $row Row index
  260. * @param int $col Column index
  261. * @param mixed $attributes Associative array or string of table
  262. * row attributes
  263. * @access public
  264. * @throws PEAR_Error
  265. */
  266. function setCellAttributes($row, $col, $attributes)
  267. {
  268. if ( isset($this->_structure[$row][$col])
  269. && $this->_structure[$row][$col] == '__SPANNED__'
  270. ) {
  271. return;
  272. }
  273. $attributes = $this->_parseAttributes($attributes);
  274. $err = $this->_adjustEnds($row, $col, 'setCellAttributes', $attributes);
  275. if (PEAR::isError($err)) {
  276. return $err;
  277. }
  278. $this->_structure[$row][$col]['attr'] = $attributes;
  279. // Fix use of rowspan/colspan
  280. //$this->_updateSpanGrid($row, $col);
  281. }
  282. /**
  283. * Updates the cell attributes passed but leaves other existing attributes
  284. * intact
  285. * @param int $row Row index
  286. * @param int $col Column index
  287. * @param mixed $attributes Associative array or string of table row
  288. * attributes
  289. * @access public
  290. */
  291. function updateCellAttributes($row, $col, $attributes)
  292. {
  293. if ( isset($this->_structure[$row][$col])
  294. && $this->_structure[$row][$col] == '__SPANNED__'
  295. ) {
  296. return;
  297. }
  298. $attributes = $this->_parseAttributes($attributes);
  299. $err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
  300. if (PEAR::isError($err)) {
  301. return $err;
  302. }
  303. $this->_updateAttrArray($this->_structure[$row][$col]['attr'], $attributes);
  304. //$this->_updateSpanGrid($row, $col);
  305. }
  306. /**
  307. * Returns the attributes for a given cell
  308. * @param int $row Row index
  309. * @param int $col Column index
  310. * @return array
  311. * @access public
  312. */
  313. function getCellAttributes($row, $col)
  314. {
  315. if ( isset($this->_structure[$row][$col])
  316. && $this->_structure[$row][$col] != '__SPANNED__'
  317. ) {
  318. return $this->_structure[$row][$col]['attr'];
  319. } elseif (!isset($this->_structure[$row][$col])) {
  320. throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellAttributes');
  321. }
  322. }
  323. /**
  324. * Sets the cell contents for an existing cell
  325. *
  326. * If the given indices do not exist and autoGrow is true then the given
  327. * row and/or col is automatically added. If autoGrow is false then an
  328. * error is returned.
  329. * @param int $row Row index
  330. * @param int $col Column index
  331. * @param mixed $contents May contain html or any object with a
  332. * toHTML() method; if it is an array (with
  333. * strings and/or objects), $col will be used
  334. * as start offset and the array elements will
  335. * be set to this and the following columns
  336. * in $row
  337. * @param string $type (optional) Cell type either 'TH' or 'TD'
  338. * @access public
  339. * @throws PEAR_Error
  340. */
  341. function setCellContents($row, $col, $contents, $type = 'TD')
  342. {
  343. if (is_array($contents)) {
  344. foreach ($contents as $singleContent) {
  345. $ret = $this->_setSingleCellContents($row, $col, $singleContent,
  346. $type);
  347. if (PEAR::isError($ret)) {
  348. return $ret;
  349. }
  350. $col++;
  351. }
  352. } else {
  353. $ret = $this->_setSingleCellContents($row, $col, $contents, $type);
  354. if (PEAR::isError($ret)) {
  355. return $ret;
  356. }
  357. }
  358. }
  359. /**
  360. * Sets the cell contents for a single existing cell
  361. *
  362. * If the given indices do not exist and autoGrow is true then the given
  363. * row and/or col is automatically added. If autoGrow is false then an
  364. * error is returned.
  365. * @param int $row Row index
  366. * @param int $col Column index
  367. * @param mixed $contents May contain html or any object with a
  368. * toHTML() method; if it is an array (with
  369. * strings and/or objects), $col will be used
  370. * as start offset and the array elements will
  371. * be set to this and the following columns
  372. * in $row
  373. * @param string $type (optional) Cell type either 'TH' or 'TD'
  374. * @access private
  375. * @throws PEAR_Error
  376. */
  377. function _setSingleCellContents($row, $col, $contents, $type = 'TD')
  378. {
  379. if ( isset($this->_structure[$row][$col])
  380. && $this->_structure[$row][$col] == '__SPANNED__'
  381. ) {
  382. return;
  383. }
  384. $err = $this->_adjustEnds($row, $col, 'setCellContents');
  385. if (PEAR::isError($err)) {
  386. return $err;
  387. }
  388. $this->_structure[$row][$col]['contents'] = $contents;
  389. $this->_structure[$row][$col]['type'] = $type;
  390. }
  391. /**
  392. * Returns the cell contents for an existing cell
  393. * @param int $row Row index
  394. * @param int $col Column index
  395. * @access public
  396. * @return mixed
  397. */
  398. function getCellContents($row, $col)
  399. {
  400. if ( isset($this->_structure[$row][$col])
  401. && $this->_structure[$row][$col] == '__SPANNED__'
  402. ) {
  403. return;
  404. }
  405. if (!isset($this->_structure[$row][$col])) {
  406. throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellContents');
  407. }
  408. return $this->_structure[$row][$col]['contents'];
  409. }
  410. /**
  411. * Sets the contents of a header cell
  412. * @param int $row
  413. * @param int $col
  414. * @param mixed $contents
  415. * @param mixed $attributes Associative array or string of table row
  416. * attributes
  417. * @access public
  418. */
  419. function setHeaderContents($row, $col, $contents, $attributes = null)
  420. {
  421. $this->setCellContents($row, $col, $contents, 'TH');
  422. if (!is_null($attributes)) {
  423. $this->updateCellAttributes($row, $col, $attributes);
  424. }
  425. }
  426. /**
  427. * Adds a table row and returns the row identifier
  428. * @param array $contents (optional) Must be a indexed array of valid
  429. * cell contents
  430. * @param mixed $attributes (optional) Associative array or string of
  431. * table row attributes. This can
  432. * also be an array of attributes,
  433. * in which case the attributes
  434. * will be repeated in a loop.
  435. * @param string $type (optional) Cell type either 'th' or 'td'
  436. * @param bool $inTR false if attributes are to be
  437. * applied in TD tags; true if
  438. * attributes are to be applied in
  439. * TR tag
  440. * @return int
  441. * @access public
  442. */
  443. function addRow($contents = [], $attributes = null, $type = 'td',
  444. $inTR = false)
  445. {
  446. if (isset($contents) && !is_array($contents)) {
  447. throw new \Exception('First parameter to HTML_Table::addRow must be an array');
  448. }
  449. if (is_null($contents)) {
  450. $contents = array();
  451. }
  452. $type = strtolower($type);
  453. $row = $this->_rows++;
  454. foreach ($contents as $col => $content) {
  455. if ($type == 'td') {
  456. $this->setCellContents($row, $col, $content);
  457. } elseif ($type == 'th') {
  458. $this->setHeaderContents($row, $col, $content);
  459. }
  460. }
  461. $this->setRowAttributes($row, $attributes, $inTR);
  462. return $row;
  463. }
  464. /**
  465. * Sets the row attributes for an existing row
  466. * @param int $row Row index
  467. * @param mixed $attributes Associative array or string of table
  468. * row attributes. This can also be an
  469. * array of attributes, in which case the
  470. * attributes will be repeated in a loop.
  471. * @param bool $inTR false if attributes are to be applied
  472. * in TD tags; true if attributes are to
  473. * be applied in TR tag
  474. * @access public
  475. * @throws PEAR_Error
  476. */
  477. function setRowAttributes($row, $attributes, $inTR = false)
  478. {
  479. if (!$inTR) {
  480. $multiAttr = $this->_isAttributesArray($attributes);
  481. for ($i = 0; $i < $this->_cols; $i++) {
  482. if ($multiAttr) {
  483. $this->setCellAttributes($row, $i,
  484. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  485. } else {
  486. $this->setCellAttributes($row, $i, $attributes);
  487. }
  488. }
  489. } else {
  490. $attributes = $this->_parseAttributes($attributes);
  491. $err = $this->_adjustEnds($row, 0, 'setRowAttributes', $attributes);
  492. if (PEAR::isError($err)) {
  493. return $err;
  494. }
  495. $this->_structure[$row]['attr'] = $attributes;
  496. }
  497. }
  498. /**
  499. * Updates the row attributes for an existing row
  500. * @param int $row Row index
  501. * @param mixed $attributes Associative array or string of table
  502. * row attributes
  503. * @param bool $inTR false if attributes are to be applied
  504. * in TD tags; true if attributes are to
  505. * be applied in TR tag
  506. * @access public
  507. * @throws PEAR_Error
  508. */
  509. function updateRowAttributes($row, $attributes = null, $inTR = false)
  510. {
  511. if (!$inTR) {
  512. $multiAttr = $this->_isAttributesArray($attributes);
  513. for ($i = 0; $i < $this->_cols; $i++) {
  514. if ($multiAttr) {
  515. $this->updateCellAttributes($row, $i,
  516. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  517. } else {
  518. $this->updateCellAttributes($row, $i, $attributes);
  519. }
  520. }
  521. } else {
  522. $attributes = $this->_parseAttributes($attributes);
  523. $err = $this->_adjustEnds($row, 0, 'updateRowAttributes', $attributes);
  524. if (PEAR::isError($err)) {
  525. return $err;
  526. }
  527. $this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
  528. }
  529. }
  530. /**
  531. * Returns the attributes for a given row as contained in the TR tag
  532. * @param int $row Row index
  533. * @return array
  534. * @access public
  535. */
  536. function getRowAttributes($row)
  537. {
  538. if (isset($this->_structure[$row]['attr'])) {
  539. return $this->_structure[$row]['attr'];
  540. }
  541. return;
  542. }
  543. /**
  544. * Alternates the row attributes starting at $start
  545. * @param int $start Row index of row in which alternating
  546. * begins
  547. * @param mixed $attributes1 Associative array or string of table
  548. * row attributes
  549. * @param mixed $attributes2 Associative array or string of table
  550. * row attributes
  551. * @param bool $inTR false if attributes are to be applied
  552. * in TD tags; true if attributes are to
  553. * be applied in TR tag
  554. * @param int $firstAttributes (optional) Which attributes should be
  555. * applied to the first row, 1 or 2.
  556. * @access public
  557. */
  558. function altRowAttributes($start, $attributes1, $attributes2, $inTR = false,
  559. $firstAttributes = 1)
  560. {
  561. for ($row = $start; $row < $this->_rows; $row++) {
  562. if (($row + $start + ($firstAttributes - 1)) % 2 == 0) {
  563. $attributes = $attributes1;
  564. } else {
  565. $attributes = $attributes2;
  566. }
  567. $this->updateRowAttributes($row, $attributes, $inTR);
  568. }
  569. }
  570. /**
  571. * Adds a table column and returns the column identifier
  572. * @param array $contents (optional) Must be a indexed array of valid
  573. * cell contents
  574. * @param mixed $attributes (optional) Associative array or string of
  575. * table row attributes
  576. * @param string $type (optional) Cell type either 'th' or 'td'
  577. * @return int
  578. * @access public
  579. */
  580. function addCol($contents = null, $attributes = null, $type = 'td')
  581. {
  582. if (isset($contents) && !is_array($contents)) {
  583. throw new \Exception('First parameter to HTML_Table::addCol must be an array');
  584. }
  585. if (is_null($contents)) {
  586. $contents = array();
  587. }
  588. $type = strtolower($type);
  589. $col = $this->_cols++;
  590. foreach ($contents as $row => $content) {
  591. if ($type == 'td') {
  592. $this->setCellContents($row, $col, $content);
  593. } elseif ($type == 'th') {
  594. $this->setHeaderContents($row, $col, $content);
  595. }
  596. }
  597. $this->setColAttributes($col, $attributes);
  598. return $col;
  599. }
  600. /**
  601. * Sets the column attributes for an existing column
  602. * @param int $col Column index
  603. * @param mixed $attributes (optional) Associative array or string
  604. * of table row attributes
  605. * @access public
  606. */
  607. function setColAttributes($col, $attributes = null)
  608. {
  609. $multiAttr = $this->_isAttributesArray($attributes);
  610. for ($i = 0; $i < $this->_rows; $i++) {
  611. if ($multiAttr) {
  612. $this->setCellAttributes($i, $col,
  613. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  614. } else {
  615. $this->setCellAttributes($i, $col, $attributes);
  616. }
  617. }
  618. }
  619. /**
  620. * Updates the column attributes for an existing column
  621. * @param int $col Column index
  622. * @param mixed $attributes (optional) Associative array or string
  623. * of table row attributes
  624. * @access public
  625. */
  626. function updateColAttributes($col, $attributes = null)
  627. {
  628. $multiAttr = $this->_isAttributesArray($attributes);
  629. for ($i = 0; $i < $this->_rows; $i++) {
  630. if ($multiAttr) {
  631. $this->updateCellAttributes($i, $col,
  632. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  633. } else {
  634. $this->updateCellAttributes($i, $col, $attributes);
  635. }
  636. }
  637. }
  638. /**
  639. * Sets the attributes for all cells
  640. * @param mixed $attributes (optional) Associative array or
  641. * string of table row attributes
  642. * @access public
  643. */
  644. function setAllAttributes($attributes = null)
  645. {
  646. for ($i = 0; $i < $this->_rows; $i++) {
  647. $this->setRowAttributes($i, $attributes);
  648. }
  649. }
  650. /**
  651. * Updates the attributes for all cells
  652. * @param mixed $attributes (optional) Associative array or
  653. * string of table row attributes
  654. * @access public
  655. */
  656. function updateAllAttributes($attributes = null)
  657. {
  658. for ($i = 0; $i < $this->_rows; $i++) {
  659. $this->updateRowAttributes($i, $attributes);
  660. }
  661. }
  662. /**
  663. * Returns the table rows as HTML
  664. * @access public
  665. * @return string
  666. */
  667. function toHtml($tabs = null, $tab = null)
  668. {
  669. $strHtml = '';
  670. if (is_null($tabs)) {
  671. $tabs = $this->_getTabs();
  672. }
  673. if (is_null($tab)) {
  674. $tab = $this->_getTab();
  675. }
  676. $lnEnd = $this->_getLineEnd();
  677. if ($this->_useTGroups) {
  678. $extraTab = $tab;
  679. } else {
  680. $extraTab = '';
  681. }
  682. if ($this->_cols > 0) {
  683. for ($i = 0 ; $i < $this->_rows ; $i++) {
  684. $attr = '';
  685. if (isset($this->_structure[$i]['attr'])) {
  686. $attr = $this->_getAttrString($this->_structure[$i]['attr']);
  687. }
  688. $strHtml .= $tabs .$tab . $extraTab . '<tr'.$attr.'>' . $lnEnd;
  689. for ($j = 0 ; $j < $this->_cols ; $j++) {
  690. $attr = '';
  691. $contents = '';
  692. $type = 'td';
  693. if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
  694. continue;
  695. }
  696. if (isset($this->_structure[$i][$j]['type'])) {
  697. $type = (strtolower($this->_structure[$i][$j]['type']) == 'th' ? 'th' : 'td');
  698. }
  699. if (isset($this->_structure[$i][$j]['attr'])) {
  700. $attr = $this->_structure[$i][$j]['attr'];
  701. }
  702. if (isset($this->_structure[$i][$j]['contents'])) {
  703. $contents = $this->_structure[$i][$j]['contents'];
  704. }
  705. if (is_object($contents)) {
  706. // changes indent and line end settings on nested tables
  707. if (is_subclass_of($contents, 'html_common')) {
  708. $contents->setTab($tab . $extraTab);
  709. $contents->setTabOffset($this->_tabOffset + 3);
  710. $contents->_nestLevel = $this->_nestLevel + 1;
  711. $contents->setLineEnd($this->_getLineEnd());
  712. }
  713. if (method_exists($contents, 'toHtml')) {
  714. $contents = $contents->toHtml();
  715. } elseif (method_exists($contents, 'toString')) {
  716. $contents = $contents->toString();
  717. }
  718. }
  719. if (is_array($contents)) {
  720. $contents = implode(', ', $contents);
  721. }
  722. $typeContent = $tabs . $tab . $tab . $extraTab . "<$type" . $this->_getAttrString($attr) . '>';
  723. if ($contents || is_numeric($contents)) {
  724. $typeContent .= $contents;
  725. } elseif (empty($contents)) {
  726. if (isset($this->_autoFill) && $this->_autoFill) {
  727. $contents = $this->_autoFill;
  728. }
  729. }
  730. $typeContent .= "</$type>" . $lnEnd;
  731. if (!empty($contents) || is_numeric($contents)) {
  732. $strHtml .= $typeContent;
  733. }
  734. }
  735. $strHtml .= $tabs . $tab . $extraTab . '</tr>' . $lnEnd;
  736. }
  737. }
  738. return $strHtml;
  739. }
  740. /**
  741. * Checks if rows or columns are spanned
  742. * @param int $row Row index
  743. * @param int $col Column index
  744. * @access private
  745. */
  746. function _updateSpanGrid($row, $col)
  747. {
  748. if (isset($this->_structure[$row][$col]['attr']['colspan'])) {
  749. $colspan = $this->_structure[$row][$col]['attr']['colspan'];
  750. }
  751. if (isset($this->_structure[$row][$col]['attr']['rowspan'])) {
  752. $rowspan = $this->_structure[$row][$col]['attr']['rowspan'];
  753. }
  754. if (isset($colspan)) {
  755. for ($j = $col + 1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  756. $this->_structure[$row][$j] = '__SPANNED__';
  757. }
  758. }
  759. if (isset($rowspan)) {
  760. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  761. $this->_structure[$i][$col] = '__SPANNED__';
  762. }
  763. }
  764. if (isset($colspan) && isset($rowspan)) {
  765. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  766. for ($j = $col + 1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  767. $this->_structure[$i][$j] = '__SPANNED__';
  768. }
  769. }
  770. }
  771. }
  772. /**
  773. * Adjusts ends (total number of rows and columns)
  774. * @param int $row Row index
  775. * @param int $col Column index
  776. * @param string $method Method name of caller
  777. * Used to populate PEAR_Error if thrown.
  778. * @param array $attributes Assoc array of attributes
  779. * Default is an empty array.
  780. * @access private
  781. * @throws PEAR_Error
  782. */
  783. function _adjustEnds($row, $col, $method, $attributes = array())
  784. {
  785. $colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
  786. $rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
  787. if (!is_numeric($row) or !is_numeric($col)) {
  788. //throw new Exception('Row or column index is not numerical');
  789. return;
  790. }
  791. if (($row + $rowspan - 1) >= $this->_rows) {
  792. if ($this->_autoGrow) {
  793. $this->_rows = $row + $rowspan;
  794. } else {
  795. /*return PEAR::raiseError('Invalid table row reference[' .
  796. $row . '] in HTML_Table::' . $method);*/
  797. }
  798. }
  799. if (($col + $colspan - 1) >= $this->_cols) {
  800. if ($this->_autoGrow) {
  801. $this->_cols = $col + $colspan;
  802. } else {
  803. /*return PEAR::raiseError('Invalid table column reference[' .
  804. $col . '] in HTML_Table::' . $method);*/
  805. }
  806. }
  807. }
  808. /**
  809. * Tells if the parameter is an array of attribute arrays/strings
  810. * @param mixed $attributes Variable to test
  811. * @access private
  812. * @return bool
  813. */
  814. function _isAttributesArray($attributes)
  815. {
  816. if (is_array($attributes) && isset($attributes[0])) {
  817. if (is_array($attributes[0]) || (is_string($attributes[0]) && count($attributes) > 1)) {
  818. return true;
  819. }
  820. }
  821. return false;
  822. }
  823. }
  824. ?>