Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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 234674 2007-04-29 16:31:06Z wiesemann $
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 = '&nbsp;';
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
?>