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. * Value to insert into empty cells
  71. * @var string
  72. * @access private
  73. */
  74. var $_autoFill = '&nbsp;';
  75. /**
  76. * Automatically adds a new row or column if a given row or column index
  77. * does not exist
  78. * @var bool
  79. * @access private
  80. */
  81. var $_autoGrow = true;
  82. /**
  83. * Array containing the table structure
  84. * @var array
  85. * @access private
  86. */
  87. var $_structure = array();
  88. /**
  89. * Number of rows composing in the table
  90. * @var int
  91. * @access private
  92. */
  93. var $_rows = 0;
  94. /**
  95. * Number of column composing the table
  96. * @var int
  97. * @access private
  98. */
  99. var $_cols = 0;
  100. /**
  101. * Tracks the level of nested tables
  102. * @var int
  103. * @access private
  104. */
  105. var $_nestLevel = 0;
  106. /**
  107. * Whether to use <thead>, <tfoot> and <tbody> or not
  108. * @var bool
  109. * @access private
  110. */
  111. var $_useTGroups = false;
  112. /**
  113. * Class constructor
  114. * @param int $tabOffset
  115. * @param bool $useTGroups Whether to use <thead>, <tfoot> and
  116. * <tbody> or not
  117. * @access public
  118. */
  119. function HTML_Table_Storage($tabOffset = 0, $useTGroups = false)
  120. {
  121. parent::__construct(null, (int)$tabOffset);
  122. $this->_useTGroups = (boolean)$useTGroups;
  123. }
  124. /**
  125. * Sets the useTGroups value
  126. * @param boolean $useTGroups
  127. * @access public
  128. */
  129. function setUseTGroups($useTGroups)
  130. {
  131. $this->_useTGroups = $useTGroups;
  132. }
  133. /**
  134. * Returns the useTGroups value
  135. * @access public
  136. * @return boolean
  137. */
  138. function getUseTGroups()
  139. {
  140. return $this->_useTGroups;
  141. }
  142. /**
  143. * Sets the autoFill value
  144. * @param mixed $fill
  145. * @access public
  146. */
  147. function setAutoFill($fill)
  148. {
  149. $this->_autoFill = $fill;
  150. }
  151. /**
  152. * Returns the autoFill value
  153. * @access public
  154. * @return mixed
  155. */
  156. function getAutoFill()
  157. {
  158. return $this->_autoFill;
  159. }
  160. /**
  161. * Sets the autoGrow value
  162. * @param bool $fill
  163. * @access public
  164. */
  165. function setAutoGrow($grow)
  166. {
  167. $this->_autoGrow = $grow;
  168. }
  169. /**
  170. * Returns the autoGrow value
  171. * @access public
  172. * @return mixed
  173. */
  174. function getAutoGrow()
  175. {
  176. return $this->_autoGrow;
  177. }
  178. /**
  179. * Sets the number of rows in the table
  180. * @param int $rows
  181. * @access public
  182. */
  183. function setRowCount($rows)
  184. {
  185. $this->_rows = $rows;
  186. }
  187. /**
  188. * Sets the number of columns in the table
  189. * @param int $cols
  190. * @access public
  191. */
  192. function setColCount($cols)
  193. {
  194. $this->_cols = $cols;
  195. }
  196. /**
  197. * Returns the number of rows in the table
  198. * @access public
  199. * @return int
  200. */
  201. function getRowCount()
  202. {
  203. return $this->_rows;
  204. }
  205. /**
  206. * Gets the number of columns in the table
  207. *
  208. * If a row index is specified, the count will not take
  209. * the spanned cells into account in the return value.
  210. *
  211. * @param int Row index to serve for cols count
  212. * @access public
  213. * @return int
  214. */
  215. function getColCount($row = null)
  216. {
  217. if (!is_null($row)) {
  218. $count = 0;
  219. foreach ($this->_structure[$row] as $cell) {
  220. if (is_array($cell)) {
  221. $count++;
  222. }
  223. }
  224. return $count;
  225. }
  226. return $this->_cols;
  227. }
  228. /**
  229. * Sets a rows type 'TH' or 'TD'
  230. * @param int $row Row index
  231. * @param string $type 'TH' or 'TD'
  232. * @access public
  233. */
  234. function setRowType($row, $type)
  235. {
  236. for ($counter = 0; $counter < $this->_cols; $counter++) {
  237. $this->_structure[$row][$counter]['type'] = $type;
  238. }
  239. }
  240. /**
  241. * Sets a columns type 'TH' or 'TD'
  242. * @param int $col Column index
  243. * @param string $type 'TH' or 'TD'
  244. * @access public
  245. */
  246. function setColType($col, $type)
  247. {
  248. for ($counter = 0; $counter < $this->_rows; $counter++) {
  249. $this->_structure[$counter][$col]['type'] = $type;
  250. }
  251. }
  252. /**
  253. * Sets the cell attributes for an existing cell.
  254. *
  255. * If the given indices do not exist and autoGrow is true then the given
  256. * row and/or col is automatically added. If autoGrow is false then an
  257. * error is returned.
  258. * @param int $row Row index
  259. * @param int $col Column index
  260. * @param mixed $attributes Associative array or string of table
  261. * row attributes
  262. * @access public
  263. * @throws PEAR_Error
  264. */
  265. function setCellAttributes($row, $col, $attributes)
  266. {
  267. if ( isset($this->_structure[$row][$col])
  268. && $this->_structure[$row][$col] == '__SPANNED__'
  269. ) {
  270. return;
  271. }
  272. $attributes = $this->_parseAttributes($attributes);
  273. $err = $this->_adjustEnds($row, $col, 'setCellAttributes', $attributes);
  274. if (PEAR::isError($err)) {
  275. return $err;
  276. }
  277. $this->_structure[$row][$col]['attr'] = $attributes;
  278. // Fix use of rowspan/colspan
  279. //$this->_updateSpanGrid($row, $col);
  280. }
  281. /**
  282. * Updates the cell attributes passed but leaves other existing attributes
  283. * intact
  284. * @param int $row Row index
  285. * @param int $col Column index
  286. * @param mixed $attributes Associative array or string of table row
  287. * attributes
  288. * @access public
  289. */
  290. function updateCellAttributes($row, $col, $attributes)
  291. {
  292. if ( isset($this->_structure[$row][$col])
  293. && $this->_structure[$row][$col] == '__SPANNED__'
  294. ) {
  295. return;
  296. }
  297. $attributes = $this->_parseAttributes($attributes);
  298. $err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
  299. if (PEAR::isError($err)) {
  300. return $err;
  301. }
  302. $this->_updateAttrArray($this->_structure[$row][$col]['attr'], $attributes);
  303. //$this->_updateSpanGrid($row, $col);
  304. }
  305. /**
  306. * Returns the attributes for a given cell
  307. * @param int $row Row index
  308. * @param int $col Column index
  309. * @return array
  310. * @access public
  311. */
  312. function getCellAttributes($row, $col)
  313. {
  314. if ( isset($this->_structure[$row][$col])
  315. && $this->_structure[$row][$col] != '__SPANNED__'
  316. ) {
  317. return $this->_structure[$row][$col]['attr'];
  318. } elseif (!isset($this->_structure[$row][$col])) {
  319. return PEAR::raiseError('Invalid table cell reference[' .
  320. $row . '][' . $col . '] in HTML_Table::getCellAttributes');
  321. }
  322. return;
  323. }
  324. /**
  325. * Sets the cell contents for an existing cell
  326. *
  327. * If the given indices do not exist and autoGrow is true then the given
  328. * row and/or col is automatically added. If autoGrow is false then an
  329. * error is returned.
  330. * @param int $row Row index
  331. * @param int $col Column index
  332. * @param mixed $contents May contain html or any object with a
  333. * toHTML() method; if it is an array (with
  334. * strings and/or objects), $col will be used
  335. * as start offset and the array elements will
  336. * be set to this and the following columns
  337. * in $row
  338. * @param string $type (optional) Cell type either 'TH' or 'TD'
  339. * @access public
  340. * @throws PEAR_Error
  341. */
  342. function setCellContents($row, $col, $contents, $type = 'TD')
  343. {
  344. if (is_array($contents)) {
  345. foreach ($contents as $singleContent) {
  346. $ret = $this->_setSingleCellContents($row, $col, $singleContent,
  347. $type);
  348. if (PEAR::isError($ret)) {
  349. return $ret;
  350. }
  351. $col++;
  352. }
  353. } else {
  354. $ret = $this->_setSingleCellContents($row, $col, $contents, $type);
  355. if (PEAR::isError($ret)) {
  356. return $ret;
  357. }
  358. }
  359. }
  360. /**
  361. * Sets the cell contents for a single existing cell
  362. *
  363. * If the given indices do not exist and autoGrow is true then the given
  364. * row and/or col is automatically added. If autoGrow is false then an
  365. * error is returned.
  366. * @param int $row Row index
  367. * @param int $col Column index
  368. * @param mixed $contents May contain html or any object with a
  369. * toHTML() method; if it is an array (with
  370. * strings and/or objects), $col will be used
  371. * as start offset and the array elements will
  372. * be set to this and the following columns
  373. * in $row
  374. * @param string $type (optional) Cell type either 'TH' or 'TD'
  375. * @access private
  376. * @throws PEAR_Error
  377. */
  378. function _setSingleCellContents($row, $col, $contents, $type = 'TD')
  379. {
  380. if ( isset($this->_structure[$row][$col])
  381. && $this->_structure[$row][$col] == '__SPANNED__'
  382. ) {
  383. return;
  384. }
  385. $err = $this->_adjustEnds($row, $col, 'setCellContents');
  386. if (PEAR::isError($err)) {
  387. return $err;
  388. }
  389. $this->_structure[$row][$col]['contents'] = $contents;
  390. $this->_structure[$row][$col]['type'] = $type;
  391. }
  392. /**
  393. * Returns the cell contents for an existing cell
  394. * @param int $row Row index
  395. * @param int $col Column index
  396. * @access public
  397. * @return mixed
  398. */
  399. function getCellContents($row, $col)
  400. {
  401. if ( isset($this->_structure[$row][$col])
  402. && $this->_structure[$row][$col] == '__SPANNED__'
  403. ) {
  404. return;
  405. }
  406. if (!isset($this->_structure[$row][$col])) {
  407. return PEAR::raiseError('Invalid table cell reference[' .
  408. $row . '][' . $col . '] in HTML_Table::getCellContents');
  409. }
  410. return $this->_structure[$row][$col]['contents'];
  411. }
  412. /**
  413. * Sets the contents of a header cell
  414. * @param int $row
  415. * @param int $col
  416. * @param mixed $contents
  417. * @param mixed $attributes Associative array or string of table row
  418. * attributes
  419. * @access public
  420. */
  421. function setHeaderContents($row, $col, $contents, $attributes = null)
  422. {
  423. $this->setCellContents($row, $col, $contents, 'TH');
  424. if (!is_null($attributes)) {
  425. $this->updateCellAttributes($row, $col, $attributes);
  426. }
  427. }
  428. /**
  429. * Adds a table row and returns the row identifier
  430. * @param array $contents (optional) Must be a indexed array of valid
  431. * cell contents
  432. * @param mixed $attributes (optional) Associative array or string of
  433. * table row attributes. This can
  434. * also be an array of attributes,
  435. * in which case the attributes
  436. * will be repeated in a loop.
  437. * @param string $type (optional) Cell type either 'th' or 'td'
  438. * @param bool $inTR false if attributes are to be
  439. * applied in TD tags; true if
  440. * attributes are to be applied in
  441. * TR tag
  442. * @return int
  443. * @access public
  444. */
  445. function addRow($contents = null, $attributes = null, $type = 'td',
  446. $inTR = false)
  447. {
  448. if (isset($contents) && !is_array($contents)) {
  449. return PEAR::raiseError('First parameter to HTML_Table::addRow ' .
  450. 'must be an array');
  451. }
  452. if (is_null($contents)) {
  453. $contents = array();
  454. }
  455. $type = strtolower($type);
  456. $row = $this->_rows++;
  457. foreach ($contents as $col => $content) {
  458. if ($type == 'td') {
  459. $this->setCellContents($row, $col, $content);
  460. } elseif ($type == 'th') {
  461. $this->setHeaderContents($row, $col, $content);
  462. }
  463. }
  464. $this->setRowAttributes($row, $attributes, $inTR);
  465. return $row;
  466. }
  467. /**
  468. * Sets the row attributes for an existing row
  469. * @param int $row Row index
  470. * @param mixed $attributes Associative array or string of table
  471. * row attributes. This can also be an
  472. * array of attributes, in which case the
  473. * attributes will be repeated in a loop.
  474. * @param bool $inTR false if attributes are to be applied
  475. * in TD tags; true if attributes are to
  476. * be applied in TR tag
  477. * @access public
  478. * @throws PEAR_Error
  479. */
  480. function setRowAttributes($row, $attributes, $inTR = false)
  481. {
  482. if (!$inTR) {
  483. $multiAttr = $this->_isAttributesArray($attributes);
  484. for ($i = 0; $i < $this->_cols; $i++) {
  485. if ($multiAttr) {
  486. $this->setCellAttributes($row, $i,
  487. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  488. } else {
  489. $this->setCellAttributes($row, $i, $attributes);
  490. }
  491. }
  492. } else {
  493. $attributes = $this->_parseAttributes($attributes);
  494. $err = $this->_adjustEnds($row, 0, 'setRowAttributes', $attributes);
  495. if (PEAR::isError($err)) {
  496. return $err;
  497. }
  498. $this->_structure[$row]['attr'] = $attributes;
  499. }
  500. }
  501. /**
  502. * Updates the row attributes for an existing row
  503. * @param int $row Row index
  504. * @param mixed $attributes Associative array or string of table
  505. * row attributes
  506. * @param bool $inTR false if attributes are to be applied
  507. * in TD tags; true if attributes are to
  508. * be applied in TR tag
  509. * @access public
  510. * @throws PEAR_Error
  511. */
  512. function updateRowAttributes($row, $attributes = null, $inTR = false)
  513. {
  514. if (!$inTR) {
  515. $multiAttr = $this->_isAttributesArray($attributes);
  516. for ($i = 0; $i < $this->_cols; $i++) {
  517. if ($multiAttr) {
  518. $this->updateCellAttributes($row, $i,
  519. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  520. } else {
  521. $this->updateCellAttributes($row, $i, $attributes);
  522. }
  523. }
  524. } else {
  525. $attributes = $this->_parseAttributes($attributes);
  526. $err = $this->_adjustEnds($row, 0, 'updateRowAttributes', $attributes);
  527. if (PEAR::isError($err)) {
  528. return $err;
  529. }
  530. $this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
  531. }
  532. }
  533. /**
  534. * Returns the attributes for a given row as contained in the TR tag
  535. * @param int $row Row index
  536. * @return array
  537. * @access public
  538. */
  539. function getRowAttributes($row)
  540. {
  541. if (isset($this->_structure[$row]['attr'])) {
  542. return $this->_structure[$row]['attr'];
  543. }
  544. return;
  545. }
  546. /**
  547. * Alternates the row attributes starting at $start
  548. * @param int $start Row index of row in which alternating
  549. * begins
  550. * @param mixed $attributes1 Associative array or string of table
  551. * row attributes
  552. * @param mixed $attributes2 Associative array or string of table
  553. * row attributes
  554. * @param bool $inTR false if attributes are to be applied
  555. * in TD tags; true if attributes are to
  556. * be applied in TR tag
  557. * @param int $firstAttributes (optional) Which attributes should be
  558. * applied to the first row, 1 or 2.
  559. * @access public
  560. */
  561. function altRowAttributes($start, $attributes1, $attributes2, $inTR = false,
  562. $firstAttributes = 1)
  563. {
  564. for ($row = $start; $row < $this->_rows; $row++) {
  565. if (($row + $start + ($firstAttributes - 1)) % 2 == 0) {
  566. $attributes = $attributes1;
  567. } else {
  568. $attributes = $attributes2;
  569. }
  570. $this->updateRowAttributes($row, $attributes, $inTR);
  571. }
  572. }
  573. /**
  574. * Adds a table column and returns the column identifier
  575. * @param array $contents (optional) Must be a indexed array of valid
  576. * cell contents
  577. * @param mixed $attributes (optional) Associative array or string of
  578. * table row attributes
  579. * @param string $type (optional) Cell type either 'th' or 'td'
  580. * @return int
  581. * @access public
  582. */
  583. function addCol($contents = null, $attributes = null, $type = 'td')
  584. {
  585. if (isset($contents) && !is_array($contents)) {
  586. return PEAR::raiseError('First parameter to HTML_Table::addCol ' .
  587. 'must be an array');
  588. }
  589. if (is_null($contents)) {
  590. $contents = array();
  591. }
  592. $type = strtolower($type);
  593. $col = $this->_cols++;
  594. foreach ($contents as $row => $content) {
  595. if ($type == 'td') {
  596. $this->setCellContents($row, $col, $content);
  597. } elseif ($type == 'th') {
  598. $this->setHeaderContents($row, $col, $content);
  599. }
  600. }
  601. $this->setColAttributes($col, $attributes);
  602. return $col;
  603. }
  604. /**
  605. * Sets the column attributes for an existing column
  606. * @param int $col Column index
  607. * @param mixed $attributes (optional) Associative array or string
  608. * of table row attributes
  609. * @access public
  610. */
  611. function setColAttributes($col, $attributes = null)
  612. {
  613. $multiAttr = $this->_isAttributesArray($attributes);
  614. for ($i = 0; $i < $this->_rows; $i++) {
  615. if ($multiAttr) {
  616. $this->setCellAttributes($i, $col,
  617. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  618. } else {
  619. $this->setCellAttributes($i, $col, $attributes);
  620. }
  621. }
  622. }
  623. /**
  624. * Updates the column attributes for an existing column
  625. * @param int $col Column index
  626. * @param mixed $attributes (optional) Associative array or string
  627. * of table row attributes
  628. * @access public
  629. */
  630. function updateColAttributes($col, $attributes = null)
  631. {
  632. $multiAttr = $this->_isAttributesArray($attributes);
  633. for ($i = 0; $i < $this->_rows; $i++) {
  634. if ($multiAttr) {
  635. $this->updateCellAttributes($i, $col,
  636. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  637. } else {
  638. $this->updateCellAttributes($i, $col, $attributes);
  639. }
  640. }
  641. }
  642. /**
  643. * Sets the attributes for all cells
  644. * @param mixed $attributes (optional) Associative array or
  645. * string of table row attributes
  646. * @access public
  647. */
  648. function setAllAttributes($attributes = null)
  649. {
  650. for ($i = 0; $i < $this->_rows; $i++) {
  651. $this->setRowAttributes($i, $attributes);
  652. }
  653. }
  654. /**
  655. * Updates the attributes for all cells
  656. * @param mixed $attributes (optional) Associative array or
  657. * string of table row attributes
  658. * @access public
  659. */
  660. function updateAllAttributes($attributes = null)
  661. {
  662. for ($i = 0; $i < $this->_rows; $i++) {
  663. $this->updateRowAttributes($i, $attributes);
  664. }
  665. }
  666. /**
  667. * Returns the table rows as HTML
  668. * @access public
  669. * @return string
  670. */
  671. function toHtml($tabs = null, $tab = null)
  672. {
  673. $strHtml = '';
  674. if (is_null($tabs)) {
  675. $tabs = $this->_getTabs();
  676. }
  677. if (is_null($tab)) {
  678. $tab = $this->_getTab();
  679. }
  680. $lnEnd = $this->_getLineEnd();
  681. if ($this->_useTGroups) {
  682. $extraTab = $tab;
  683. } else {
  684. $extraTab = '';
  685. }
  686. if ($this->_cols > 0) {
  687. for ($i = 0 ; $i < $this->_rows ; $i++) {
  688. $attr = '';
  689. if (isset($this->_structure[$i]['attr'])) {
  690. $attr = $this->_getAttrString($this->_structure[$i]['attr']);
  691. }
  692. $strHtml .= $tabs .$tab . $extraTab . '<tr'.$attr.'>' . $lnEnd;
  693. for ($j = 0 ; $j < $this->_cols ; $j++) {
  694. $attr = '';
  695. $contents = '';
  696. $type = 'td';
  697. if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
  698. continue;
  699. }
  700. if (isset($this->_structure[$i][$j]['type'])) {
  701. $type = (strtolower($this->_structure[$i][$j]['type']) == 'th' ? 'th' : 'td');
  702. }
  703. if (isset($this->_structure[$i][$j]['attr'])) {
  704. $attr = $this->_structure[$i][$j]['attr'];
  705. }
  706. if (isset($this->_structure[$i][$j]['contents'])) {
  707. $contents = $this->_structure[$i][$j]['contents'];
  708. }
  709. if (is_object($contents)) {
  710. // changes indent and line end settings on nested tables
  711. if (is_subclass_of($contents, 'html_common')) {
  712. $contents->setTab($tab . $extraTab);
  713. $contents->setTabOffset($this->_tabOffset + 3);
  714. $contents->_nestLevel = $this->_nestLevel + 1;
  715. $contents->setLineEnd($this->_getLineEnd());
  716. }
  717. if (method_exists($contents, 'toHtml')) {
  718. $contents = $contents->toHtml();
  719. } elseif (method_exists($contents, 'toString')) {
  720. $contents = $contents->toString();
  721. }
  722. }
  723. if (is_array($contents)) {
  724. $contents = implode(', ', $contents);
  725. }
  726. $typeContent = $tabs . $tab . $tab . $extraTab . "<$type" . $this->_getAttrString($attr) . '>';
  727. if (empty($contents)) {
  728. if (isset($this->_autoFill) && $this->_autoFill) {
  729. $contents = $this->_autoFill;
  730. }
  731. } else {
  732. $typeContent .= $contents;
  733. }
  734. $typeContent .= "</$type>" . $lnEnd;
  735. if (!empty($contents)) {
  736. $strHtml .= $typeContent;
  737. }
  738. }
  739. $strHtml .= $tabs . $tab . $extraTab . '</tr>' . $lnEnd;
  740. }
  741. }
  742. return $strHtml;
  743. }
  744. /**
  745. * Checks if rows or columns are spanned
  746. * @param int $row Row index
  747. * @param int $col Column index
  748. * @access private
  749. */
  750. function _updateSpanGrid($row, $col)
  751. {
  752. if (isset($this->_structure[$row][$col]['attr']['colspan'])) {
  753. $colspan = $this->_structure[$row][$col]['attr']['colspan'];
  754. }
  755. if (isset($this->_structure[$row][$col]['attr']['rowspan'])) {
  756. $rowspan = $this->_structure[$row][$col]['attr']['rowspan'];
  757. }
  758. if (isset($colspan)) {
  759. for ($j = $col + 1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  760. $this->_structure[$row][$j] = '__SPANNED__';
  761. }
  762. }
  763. if (isset($rowspan)) {
  764. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  765. $this->_structure[$i][$col] = '__SPANNED__';
  766. }
  767. }
  768. if (isset($colspan) && isset($rowspan)) {
  769. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  770. for ($j = $col + 1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  771. $this->_structure[$i][$j] = '__SPANNED__';
  772. }
  773. }
  774. }
  775. }
  776. /**
  777. * Adjusts ends (total number of rows and columns)
  778. * @param int $row Row index
  779. * @param int $col Column index
  780. * @param string $method Method name of caller
  781. * Used to populate PEAR_Error if thrown.
  782. * @param array $attributes Assoc array of attributes
  783. * Default is an empty array.
  784. * @access private
  785. * @throws PEAR_Error
  786. */
  787. function _adjustEnds($row, $col, $method, $attributes = array())
  788. {
  789. $colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
  790. $rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
  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. ?>