home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / HTML / Table / Storage.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  30.3 KB  |  870 lines

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