Storage.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  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. HTML_Common::HTML_Common(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. $this->_updateSpanGrid($row, $col);
  279. }
  280. /**
  281. * Updates the cell attributes passed but leaves other existing attributes
  282. * intact
  283. * @param int $row Row index
  284. * @param int $col Column index
  285. * @param mixed $attributes Associative array or string of table row
  286. * attributes
  287. * @access public
  288. */
  289. function updateCellAttributes($row, $col, $attributes)
  290. {
  291. if ( isset($this->_structure[$row][$col])
  292. && $this->_structure[$row][$col] == '__SPANNED__'
  293. ) {
  294. return;
  295. }
  296. $attributes = $this->_parseAttributes($attributes);
  297. $err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
  298. if (PEAR::isError($err)) {
  299. return $err;
  300. }
  301. $this->_updateAttrArray($this->_structure[$row][$col]['attr'], $attributes);
  302. $this->_updateSpanGrid($row, $col);
  303. }
  304. /**
  305. * Returns the attributes for a given cell
  306. * @param int $row Row index
  307. * @param int $col Column index
  308. * @return array
  309. * @access public
  310. */
  311. function getCellAttributes($row, $col)
  312. {
  313. if ( isset($this->_structure[$row][$col])
  314. && $this->_structure[$row][$col] != '__SPANNED__'
  315. ) {
  316. return $this->_structure[$row][$col]['attr'];
  317. } elseif (!isset($this->_structure[$row][$col])) {
  318. return PEAR::raiseError('Invalid table cell reference[' .
  319. $row . '][' . $col . '] in HTML_Table::getCellAttributes');
  320. }
  321. return;
  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. return PEAR::raiseError('Invalid table cell reference[' .
  407. $row . '][' . $col . '] in HTML_Table::getCellContents');
  408. }
  409. return $this->_structure[$row][$col]['contents'];
  410. }
  411. /**
  412. * Sets the contents of a header cell
  413. * @param int $row
  414. * @param int $col
  415. * @param mixed $contents
  416. * @param mixed $attributes Associative array or string of table row
  417. * attributes
  418. * @access public
  419. */
  420. function setHeaderContents($row, $col, $contents, $attributes = null)
  421. {
  422. $this->setCellContents($row, $col, $contents, 'TH');
  423. if (!is_null($attributes)) {
  424. $this->updateCellAttributes($row, $col, $attributes);
  425. }
  426. }
  427. /**
  428. * Adds a table row and returns the row identifier
  429. * @param array $contents (optional) Must be a indexed array of valid
  430. * cell contents
  431. * @param mixed $attributes (optional) Associative array or string of
  432. * table row attributes. This can
  433. * also be an array of attributes,
  434. * in which case the attributes
  435. * will be repeated in a loop.
  436. * @param string $type (optional) Cell type either 'th' or 'td'
  437. * @param bool $inTR false if attributes are to be
  438. * applied in TD tags; true if
  439. * attributes are to be applied in
  440. * TR tag
  441. * @return int
  442. * @access public
  443. */
  444. function addRow($contents = null, $attributes = null, $type = 'td',
  445. $inTR = false)
  446. {
  447. if (isset($contents) && !is_array($contents)) {
  448. return PEAR::raiseError('First parameter to HTML_Table::addRow ' .
  449. 'must be an array');
  450. }
  451. if (is_null($contents)) {
  452. $contents = array();
  453. }
  454. $type = strtolower($type);
  455. $row = $this->_rows++;
  456. foreach ($contents as $col => $content) {
  457. if ($type == 'td') {
  458. $this->setCellContents($row, $col, $content);
  459. } elseif ($type == 'th') {
  460. $this->setHeaderContents($row, $col, $content);
  461. }
  462. }
  463. $this->setRowAttributes($row, $attributes, $inTR);
  464. return $row;
  465. }
  466. /**
  467. * Sets the row attributes for an existing row
  468. * @param int $row Row index
  469. * @param mixed $attributes Associative array or string of table
  470. * row attributes. This can also be an
  471. * array of attributes, in which case the
  472. * attributes will be repeated in a loop.
  473. * @param bool $inTR false if attributes are to be applied
  474. * in TD tags; true if attributes are to
  475. * be applied in TR tag
  476. * @access public
  477. * @throws PEAR_Error
  478. */
  479. function setRowAttributes($row, $attributes, $inTR = false)
  480. {
  481. if (!$inTR) {
  482. $multiAttr = $this->_isAttributesArray($attributes);
  483. for ($i = 0; $i < $this->_cols; $i++) {
  484. if ($multiAttr) {
  485. $this->setCellAttributes($row, $i,
  486. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  487. } else {
  488. $this->setCellAttributes($row, $i, $attributes);
  489. }
  490. }
  491. } else {
  492. $attributes = $this->_parseAttributes($attributes);
  493. $err = $this->_adjustEnds($row, 0, 'setRowAttributes', $attributes);
  494. if (PEAR::isError($err)) {
  495. return $err;
  496. }
  497. $this->_structure[$row]['attr'] = $attributes;
  498. }
  499. }
  500. /**
  501. * Updates the row attributes for an existing row
  502. * @param int $row Row index
  503. * @param mixed $attributes Associative array or string of table
  504. * row attributes
  505. * @param bool $inTR false if attributes are to be applied
  506. * in TD tags; true if attributes are to
  507. * be applied in TR tag
  508. * @access public
  509. * @throws PEAR_Error
  510. */
  511. function updateRowAttributes($row, $attributes = null, $inTR = false)
  512. {
  513. if (!$inTR) {
  514. $multiAttr = $this->_isAttributesArray($attributes);
  515. for ($i = 0; $i < $this->_cols; $i++) {
  516. if ($multiAttr) {
  517. $this->updateCellAttributes($row, $i,
  518. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  519. } else {
  520. $this->updateCellAttributes($row, $i, $attributes);
  521. }
  522. }
  523. } else {
  524. $attributes = $this->_parseAttributes($attributes);
  525. $err = $this->_adjustEnds($row, 0, 'updateRowAttributes', $attributes);
  526. if (PEAR::isError($err)) {
  527. return $err;
  528. }
  529. $this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
  530. }
  531. }
  532. /**
  533. * Returns the attributes for a given row as contained in the TR tag
  534. * @param int $row Row index
  535. * @return array
  536. * @access public
  537. */
  538. function getRowAttributes($row)
  539. {
  540. if (isset($this->_structure[$row]['attr'])) {
  541. return $this->_structure[$row]['attr'];
  542. }
  543. return;
  544. }
  545. /**
  546. * Alternates the row attributes starting at $start
  547. * @param int $start Row index of row in which alternating
  548. * begins
  549. * @param mixed $attributes1 Associative array or string of table
  550. * row attributes
  551. * @param mixed $attributes2 Associative array or string of table
  552. * row attributes
  553. * @param bool $inTR false if attributes are to be applied
  554. * in TD tags; true if attributes are to
  555. * be applied in TR tag
  556. * @param int $firstAttributes (optional) Which attributes should be
  557. * applied to the first row, 1 or 2.
  558. * @access public
  559. */
  560. function altRowAttributes($start, $attributes1, $attributes2, $inTR = false,
  561. $firstAttributes = 1)
  562. {
  563. for ($row = $start; $row < $this->_rows; $row++) {
  564. if (($row + $start + ($firstAttributes - 1)) % 2 == 0) {
  565. $attributes = $attributes1;
  566. } else {
  567. $attributes = $attributes2;
  568. }
  569. $this->updateRowAttributes($row, $attributes, $inTR);
  570. }
  571. }
  572. /**
  573. * Adds a table column and returns the column identifier
  574. * @param array $contents (optional) Must be a indexed array of valid
  575. * cell contents
  576. * @param mixed $attributes (optional) Associative array or string of
  577. * table row attributes
  578. * @param string $type (optional) Cell type either 'th' or 'td'
  579. * @return int
  580. * @access public
  581. */
  582. function addCol($contents = null, $attributes = null, $type = 'td')
  583. {
  584. if (isset($contents) && !is_array($contents)) {
  585. return PEAR::raiseError('First parameter to HTML_Table::addCol ' .
  586. 'must be an array');
  587. }
  588. if (is_null($contents)) {
  589. $contents = array();
  590. }
  591. $type = strtolower($type);
  592. $col = $this->_cols++;
  593. foreach ($contents as $row => $content) {
  594. if ($type == 'td') {
  595. $this->setCellContents($row, $col, $content);
  596. } elseif ($type == 'th') {
  597. $this->setHeaderContents($row, $col, $content);
  598. }
  599. }
  600. $this->setColAttributes($col, $attributes);
  601. return $col;
  602. }
  603. /**
  604. * Sets the column attributes for an existing column
  605. * @param int $col Column index
  606. * @param mixed $attributes (optional) Associative array or string
  607. * of table row attributes
  608. * @access public
  609. */
  610. function setColAttributes($col, $attributes = null)
  611. {
  612. $multiAttr = $this->_isAttributesArray($attributes);
  613. for ($i = 0; $i < $this->_rows; $i++) {
  614. if ($multiAttr) {
  615. $this->setCellAttributes($i, $col,
  616. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  617. } else {
  618. $this->setCellAttributes($i, $col, $attributes);
  619. }
  620. }
  621. }
  622. /**
  623. * Updates the column attributes for an existing column
  624. * @param int $col Column index
  625. * @param mixed $attributes (optional) Associative array or string
  626. * of table row attributes
  627. * @access public
  628. */
  629. function updateColAttributes($col, $attributes = null)
  630. {
  631. $multiAttr = $this->_isAttributesArray($attributes);
  632. for ($i = 0; $i < $this->_rows; $i++) {
  633. if ($multiAttr) {
  634. $this->updateCellAttributes($i, $col,
  635. $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
  636. } else {
  637. $this->updateCellAttributes($i, $col, $attributes);
  638. }
  639. }
  640. }
  641. /**
  642. * Sets the attributes for all cells
  643. * @param mixed $attributes (optional) Associative array or
  644. * string of table row attributes
  645. * @access public
  646. */
  647. function setAllAttributes($attributes = null)
  648. {
  649. for ($i = 0; $i < $this->_rows; $i++) {
  650. $this->setRowAttributes($i, $attributes);
  651. }
  652. }
  653. /**
  654. * Updates the attributes for all cells
  655. * @param mixed $attributes (optional) Associative array or
  656. * string of table row attributes
  657. * @access public
  658. */
  659. function updateAllAttributes($attributes = null)
  660. {
  661. for ($i = 0; $i < $this->_rows; $i++) {
  662. $this->updateRowAttributes($i, $attributes);
  663. }
  664. }
  665. /**
  666. * Returns the table rows as HTML
  667. * @access public
  668. * @return string
  669. */
  670. function toHtml($tabs = null, $tab = null)
  671. {
  672. $strHtml = '';
  673. if (is_null($tabs)) {
  674. $tabs = $this->_getTabs();
  675. }
  676. if (is_null($tab)) {
  677. $tab = $this->_getTab();
  678. }
  679. $lnEnd = $this->_getLineEnd();
  680. if ($this->_useTGroups) {
  681. $extraTab = $tab;
  682. } else {
  683. $extraTab = '';
  684. }
  685. if ($this->_cols > 0) {
  686. for ($i = 0 ; $i < $this->_rows ; $i++) {
  687. $attr = '';
  688. if (isset($this->_structure[$i]['attr'])) {
  689. $attr = $this->_getAttrString($this->_structure[$i]['attr']);
  690. }
  691. $strHtml .= $tabs .$tab . $extraTab . '<tr'.$attr.'>' . $lnEnd;
  692. for ($j = 0 ; $j < $this->_cols ; $j++) {
  693. $attr = '';
  694. $contents = '';
  695. $type = 'td';
  696. if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
  697. continue;
  698. }
  699. if (isset($this->_structure[$i][$j]['type'])) {
  700. $type = (strtolower($this->_structure[$i][$j]['type']) == 'th' ? 'th' : 'td');
  701. }
  702. if (isset($this->_structure[$i][$j]['attr'])) {
  703. $attr = $this->_structure[$i][$j]['attr'];
  704. }
  705. if (isset($this->_structure[$i][$j]['contents'])) {
  706. $contents = $this->_structure[$i][$j]['contents'];
  707. }
  708. $strHtml .= $tabs . $tab . $tab . $extraTab . "<$type" . $this->_getAttrString($attr) . '>';
  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. if (isset($this->_autoFill) && $contents === '') {
  727. $contents = $this->_autoFill;
  728. }
  729. $strHtml .= $contents;
  730. $strHtml .= "</$type>" . $lnEnd;
  731. }
  732. $strHtml .= $tabs . $tab . $extraTab . '</tr>' . $lnEnd;
  733. }
  734. }
  735. return $strHtml;
  736. }
  737. /**
  738. * Checks if rows or columns are spanned
  739. * @param int $row Row index
  740. * @param int $col Column index
  741. * @access private
  742. */
  743. function _updateSpanGrid($row, $col)
  744. {
  745. if (isset($this->_structure[$row][$col]['attr']['colspan'])) {
  746. $colspan = $this->_structure[$row][$col]['attr']['colspan'];
  747. }
  748. if (isset($this->_structure[$row][$col]['attr']['rowspan'])) {
  749. $rowspan = $this->_structure[$row][$col]['attr']['rowspan'];
  750. }
  751. if (isset($colspan)) {
  752. for ($j = $col + 1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  753. $this->_structure[$row][$j] = '__SPANNED__';
  754. }
  755. }
  756. if (isset($rowspan)) {
  757. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  758. $this->_structure[$i][$col] = '__SPANNED__';
  759. }
  760. }
  761. if (isset($colspan) && isset($rowspan)) {
  762. for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  763. for ($j = $col + 1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  764. $this->_structure[$i][$j] = '__SPANNED__';
  765. }
  766. }
  767. }
  768. }
  769. /**
  770. * Adjusts ends (total number of rows and columns)
  771. * @param int $row Row index
  772. * @param int $col Column index
  773. * @param string $method Method name of caller
  774. * Used to populate PEAR_Error if thrown.
  775. * @param array $attributes Assoc array of attributes
  776. * Default is an empty array.
  777. * @access private
  778. * @throws PEAR_Error
  779. */
  780. function _adjustEnds($row, $col, $method, $attributes = array())
  781. {
  782. $colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
  783. $rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
  784. if (($row + $rowspan - 1) >= $this->_rows) {
  785. if ($this->_autoGrow) {
  786. $this->_rows = $row + $rowspan;
  787. } else {
  788. return PEAR::raiseError('Invalid table row reference[' .
  789. $row . '] in HTML_Table::' . $method);
  790. }
  791. }
  792. if (($col + $colspan - 1) >= $this->_cols) {
  793. if ($this->_autoGrow) {
  794. $this->_cols = $col + $colspan;
  795. } else {
  796. return PEAR::raiseError('Invalid table column reference[' .
  797. $col . '] in HTML_Table::' . $method);
  798. }
  799. }
  800. }
  801. /**
  802. * Tells if the parameter is an array of attribute arrays/strings
  803. * @param mixed $attributes Variable to test
  804. * @access private
  805. * @return bool
  806. */
  807. function _isAttributesArray($attributes)
  808. {
  809. if (is_array($attributes) && isset($attributes[0])) {
  810. if (is_array($attributes[0]) || (is_string($attributes[0]) && count($attributes) > 1)) {
  811. return true;
  812. }
  813. }
  814. return false;
  815. }
  816. }
  817. ?>