Completed
Push — master ( dca322...47e653 )
by Julito
08:54
created

HTML_Table_Storage   F

Complexity

Total Complexity 140

Size/Duplication

Total Lines 809
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 241
dl 0
loc 809
rs 2
c 0
b 0
f 0
wmc 140

How to fix   Complexity   

Complex Class

Complex classes like HTML_Table_Storage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use HTML_Table_Storage, and based on these observations, apply Extract Interface, too.

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 <[email protected]>,
16
 *                          Bertrand Mansion <[email protected]>,
17
 *                          Mark Wiesemann <[email protected]>
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 <[email protected]>
47
 * @author     Bertrand Mansion <[email protected]>
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 <[email protected]>
63
 * @author     Bertrand Mansion <[email protected]>
64
 * @author     Mark Wiesemann <[email protected]>
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
    public function __construct($tabOffset = 0, $useTGroups = false)
130
    {
131
        parent::__construct(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
    public function setUseTGroups($useTGroups)
141
    {
142
        $this->_useTGroups = $useTGroups;
143
    }
144
145
    /**
146
     * Returns the useTGroups value
147
     * @access   public
148
     * @return   boolean
149
     */
150
    public function getUseTGroups()
151
    {
152
        return $this->_useTGroups;
153
    }
154
155
    /**
156
     * Sets the autoFill value
157
     * @param   mixed   $fill
158
     * @access  public
159
     */
160
    public function setAutoFill($fill)
161
    {
162
        $this->_autoFill = $fill;
163
    }
164
165
    /**
166
     * Returns the autoFill value
167
     * @access   public
168
     * @return   mixed
169
     */
170
    public function getAutoFill()
171
    {
172
        return $this->_autoFill;
173
    }
174
175
    /**
176
     * Sets the autoGrow value
177
     * @param    bool   $fill
178
     * @access   public
179
     */
180
    public function setAutoGrow($grow)
181
    {
182
        $this->_autoGrow = $grow;
183
    }
184
185
    /**
186
     * Returns the autoGrow value
187
     * @access   public
188
     * @return   mixed
189
     */
190
    public 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
        // Fix use of rowspan/colspan
303
        //$this->_updateSpanGrid($row, $col);
304
    }
305
306
    /**
307
     * Updates the cell attributes passed but leaves other existing attributes
308
     * intact
309
     * @param    int     $row         Row index
310
     * @param    int     $col         Column index
311
     * @param    mixed   $attributes  Associative array or string of table row
312
     *                                attributes
313
     * @access   public
314
     */
315
    function updateCellAttributes($row, $col, $attributes)
316
    {
317
        if (   isset($this->_structure[$row][$col])
318
            && $this->_structure[$row][$col] == '__SPANNED__'
319
        ) {
320
            return;
321
        }
322
        $attributes = $this->_parseAttributes($attributes);
323
        $err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
324
        if (PEAR::isError($err)) {
325
            return $err;
326
        }
327
        $this->_updateAttrArray($this->_structure[$row][$col]['attr'], $attributes);
328
        //$this->_updateSpanGrid($row, $col);
329
    }
330
331
    /**
332
     * Returns the attributes for a given cell
333
     * @param    int     $row         Row index
334
     * @param    int     $col         Column index
335
     * @return   array
336
     * @access   public
337
     */
338
    function getCellAttributes($row, $col)
339
    {
340
        if (   isset($this->_structure[$row][$col])
341
            && $this->_structure[$row][$col] != '__SPANNED__'
342
        ) {
343
            return $this->_structure[$row][$col]['attr'];
344
        } elseif (!isset($this->_structure[$row][$col])) {
345
            throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellAttributes');
346
        }
347
    }
348
349
    /**
350
     * Sets the cell contents for an existing cell
351
     *
352
     * If the given indices do not exist and autoGrow is true then the given
353
     * row and/or col is automatically added.  If autoGrow is false then an
354
     * error is returned.
355
     * @param    int      $row        Row index
356
     * @param    int      $col        Column index
357
     * @param    mixed    $contents   May contain html or any object with a
358
     *                                toHTML() method; if it is an array (with
359
     *                                strings and/or objects), $col will be used
360
     *                                as start offset and the array elements will
361
     *                                be set to this and the following columns
362
     *                                in $row
363
     * @param    string   $type       (optional) Cell type either 'TH' or 'TD'
364
     * @access   public
365
     * @throws   PEAR_Error
366
     */
367
    function setCellContents($row, $col, $contents, $type = 'TD')
368
    {
369
        if (is_array($contents)) {
370
            foreach ($contents as $singleContent) {
371
                $ret = $this->_setSingleCellContents($row, $col, $singleContent,
372
                    $type);
373
                if (PEAR::isError($ret)) {
374
                    return $ret;
375
                }
376
                $col++;
377
            }
378
        } else {
379
            $ret = $this->_setSingleCellContents($row, $col, $contents, $type);
380
            if (PEAR::isError($ret)) {
381
                return $ret;
382
            }
383
        }
384
    }
385
386
    /**
387
     * Sets the cell contents for a single existing cell
388
     *
389
     * If the given indices do not exist and autoGrow is true then the given
390
     * row and/or col is automatically added.  If autoGrow is false then an
391
     * error is returned.
392
     * @param    int      $row        Row index
393
     * @param    int      $col        Column index
394
     * @param    mixed    $contents   May contain html or any object with a
395
     *                                toHTML() method; if it is an array (with
396
     *                                strings and/or objects), $col will be used
397
     *                                as start offset and the array elements will
398
     *                                be set to this and the following columns
399
     *                                in $row
400
     * @param    string   $type       (optional) Cell type either 'TH' or 'TD'
401
     * @access   private
402
     * @throws   PEAR_Error
403
     */
404
    function _setSingleCellContents($row, $col, $contents, $type = 'TD')
405
    {
406
        if (   isset($this->_structure[$row][$col])
407
            && $this->_structure[$row][$col] == '__SPANNED__'
408
        ) {
409
            return;
410
        }
411
        $err = $this->_adjustEnds($row, $col, 'setCellContents');
412
        if (PEAR::isError($err)) {
413
            return $err;
414
        }
415
        $this->_structure[$row][$col]['contents'] = $contents;
416
        $this->_structure[$row][$col]['type'] = $type;
417
    }
418
419
    /**
420
     * Returns the cell contents for an existing cell
421
     * @param    int        $row    Row index
422
     * @param    int        $col    Column index
423
     * @access   public
424
     * @return   mixed
425
     */
426
    function getCellContents($row, $col)
427
    {
428
        if (   isset($this->_structure[$row][$col])
429
            && $this->_structure[$row][$col] == '__SPANNED__'
430
        ) {
431
            return;
432
        }
433
        if (!isset($this->_structure[$row][$col])) {
434
            throw new \Exception('Invalid table cell reference[' .$row . '][' . $col . '] in HTML_Table::getCellContents');
435
        }
436
        return $this->_structure[$row][$col]['contents'];
437
    }
438
439
    /**
440
     * Sets the contents of a header cell
441
     * @param    int     $row
442
     * @param    int     $col
443
     * @param    mixed   $contents
444
     * @param    mixed   $attributes  Associative array or string of table row
445
     *                                attributes
446
     * @access   public
447
     */
448
    function setHeaderContents($row, $col, $contents, $attributes = null)
449
    {
450
        $this->setCellContents($row, $col, $contents, 'TH');
451
        if (!is_null($attributes)) {
452
            $this->updateCellAttributes($row, $col, $attributes);
453
        }
454
    }
455
456
    /**
457
     * Adds a table row and returns the row identifier
458
     * @param    array    $contents   (optional) Must be a indexed array of valid
459
     *                                           cell contents
460
     * @param    mixed    $attributes (optional) Associative array or string of
461
     *                                           table row attributes. This can
462
     *                                           also be an array of attributes,
463
     *                                           in which case the attributes
464
     *                                           will be repeated in a loop.
465
     * @param    string   $type       (optional) Cell type either 'th' or 'td'
466
     * @param    bool     $inTR                  false if attributes are to be
467
     *                                           applied in TD tags; true if
468
     *                                           attributes are to be applied in
469
     *                                            TR tag
470
     * @return   int
471
     * @access   public
472
     */
473
    function addRow($contents = [], $attributes = null, $type = 'td',
474
        $inTR = false)
475
    {
476
        if (isset($contents) && !is_array($contents)) {
477
            throw new \Exception('First parameter to HTML_Table::addRow must be an array');
478
        }
479
        if (is_null($contents)) {
480
            $contents = array();
481
        }
482
483
        $type = strtolower($type);
484
        $row = $this->_rows++;
485
        foreach ($contents as $col => $content) {
486
            if ($type == 'td') {
487
                $this->setCellContents($row, $col, $content);
488
            } elseif ($type == 'th') {
489
                $this->setHeaderContents($row, $col, $content);
490
            }
491
        }
492
        $this->setRowAttributes($row, $attributes, $inTR);
493
        return $row;
494
    }
495
496
    /**
497
     * Sets the row attributes for an existing row
498
     * @param    int      $row            Row index
499
     * @param    mixed    $attributes     Associative array or string of table
500
     *                                    row attributes. This can also be an
501
     *                                    array of attributes, in which case the
502
     *                                    attributes will be repeated in a loop.
503
     * @param    bool     $inTR           false if attributes are to be applied
504
     *                                    in TD tags; true if attributes are to
505
     *                                    be applied in TR tag
506
     * @access   public
507
     * @throws   PEAR_Error
508
     */
509
    function setRowAttributes($row, $attributes, $inTR = false)
510
    {
511
        if (!$inTR) {
512
            $multiAttr = $this->_isAttributesArray($attributes);
513
            for ($i = 0; $i < $this->_cols; $i++) {
514
                if ($multiAttr) {
515
                    $this->setCellAttributes($row, $i,
516
                        $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
517
                } else {
518
                    $this->setCellAttributes($row, $i, $attributes);
519
                }
520
            }
521
        } else {
522
            $attributes = $this->_parseAttributes($attributes);
523
            $err = $this->_adjustEnds($row, 0, 'setRowAttributes', $attributes);
524
            if (PEAR::isError($err)) {
525
                return $err;
526
            }
527
            $this->_structure[$row]['attr'] = $attributes;
528
        }
529
    }
530
531
    /**
532
     * Updates the row attributes for an existing row
533
     * @param    int      $row            Row index
534
     * @param    mixed    $attributes     Associative array or string of table
535
     *                                    row attributes
536
     * @param    bool     $inTR           false if attributes are to be applied
537
     *                                    in TD tags; true if attributes are to
538
     *                                    be applied in TR tag
539
     * @access   public
540
     * @throws   PEAR_Error
541
     */
542
    function updateRowAttributes($row, $attributes = null, $inTR = false)
543
    {
544
        if (!$inTR) {
545
            $multiAttr = $this->_isAttributesArray($attributes);
546
            for ($i = 0; $i < $this->_cols; $i++) {
547
                if ($multiAttr) {
548
                    $this->updateCellAttributes($row, $i,
549
                        $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
550
                } else {
551
                    $this->updateCellAttributes($row, $i, $attributes);
552
                }
553
            }
554
        } else {
555
            $attributes = $this->_parseAttributes($attributes);
556
            $err = $this->_adjustEnds($row, 0, 'updateRowAttributes', $attributes);
557
            if (PEAR::isError($err)) {
558
                return $err;
559
            }
560
            $this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
561
        }
562
    }
563
564
    /**
565
     * Returns the attributes for a given row as contained in the TR tag
566
     * @param    int     $row         Row index
567
     * @return   array
568
     * @access   public
569
     */
570
    function getRowAttributes($row)
571
    {
572
        if (isset($this->_structure[$row]['attr'])) {
573
            return $this->_structure[$row]['attr'];
574
        }
575
        return;
576
    }
577
578
    /**
579
     * Alternates the row attributes starting at $start
580
     * @param    int      $start            Row index of row in which alternating
581
     *                                      begins
582
     * @param    mixed    $attributes1      Associative array or string of table
583
     *                                      row attributes
584
     * @param    mixed    $attributes2      Associative array or string of table
585
     *                                      row attributes
586
     * @param    bool     $inTR             false if attributes are to be applied
587
     *                                      in TD tags; true if attributes are to
588
     *                                      be applied in TR tag
589
     * @param    int      $firstAttributes  (optional) Which attributes should be
590
     *                                      applied to the first row, 1 or 2.
591
     * @access   public
592
     */
593
    function altRowAttributes($start, $attributes1, $attributes2, $inTR = false,
594
        $firstAttributes = 1)
595
    {
596
        for ($row = $start; $row < $this->_rows; $row++) {
597
            if (($row + $start + ($firstAttributes - 1)) % 2 == 0) {
598
                $attributes = $attributes1;
599
            } else {
600
                $attributes = $attributes2;
601
            }
602
            $this->updateRowAttributes($row, $attributes, $inTR);
603
        }
604
    }
605
606
    /**
607
     * Adds a table column and returns the column identifier
608
     * @param    array    $contents   (optional) Must be a indexed array of valid
609
     *                                cell contents
610
     * @param    mixed    $attributes (optional) Associative array or string of
611
     *                                table row attributes
612
     * @param    string   $type       (optional) Cell type either 'th' or 'td'
613
     * @return   int
614
     * @access   public
615
     */
616
    function addCol($contents = null, $attributes = null, $type = 'td')
617
    {
618
        if (isset($contents) && !is_array($contents)) {
619
            throw new \Exception('First parameter to HTML_Table::addCol must be an array');
620
        }
621
        if (is_null($contents)) {
622
            $contents = array();
623
        }
624
625
        $type = strtolower($type);
626
        $col = $this->_cols++;
627
        foreach ($contents as $row => $content) {
628
            if ($type == 'td') {
629
                $this->setCellContents($row, $col, $content);
630
            } elseif ($type == 'th') {
631
                $this->setHeaderContents($row, $col, $content);
632
            }
633
        }
634
        $this->setColAttributes($col, $attributes);
635
        return $col;
636
    }
637
638
    /**
639
     * Sets the column attributes for an existing column
640
     * @param    int      $col            Column index
641
     * @param    mixed    $attributes     (optional) Associative array or string
642
     *                                    of table row attributes
643
     * @access   public
644
     */
645
    function setColAttributes($col, $attributes = null)
646
    {
647
        $multiAttr = $this->_isAttributesArray($attributes);
648
        for ($i = 0; $i < $this->_rows; $i++) {
649
            if ($multiAttr) {
650
                $this->setCellAttributes($i, $col,
651
                    $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
652
            } else {
653
                $this->setCellAttributes($i, $col, $attributes);
654
            }
655
        }
656
    }
657
658
    /**
659
     * Updates the column attributes for an existing column
660
     * @param    int      $col            Column index
661
     * @param    mixed    $attributes     (optional) Associative array or string
662
     *                                    of table row attributes
663
     * @access   public
664
     */
665
    function updateColAttributes($col, $attributes = null)
666
    {
667
        $multiAttr = $this->_isAttributesArray($attributes);
668
        for ($i = 0; $i < $this->_rows; $i++) {
669
            if ($multiAttr) {
670
                $this->updateCellAttributes($i, $col,
671
                    $attributes[$i - ((ceil(($i + 1) / count($attributes))) - 1) * count($attributes)]);
672
            } else {
673
                $this->updateCellAttributes($i, $col, $attributes);
674
            }
675
        }
676
    }
677
678
    /**
679
     * Sets the attributes for all cells
680
     * @param    mixed    $attributes        (optional) Associative array or
681
     *                                       string of table row attributes
682
     * @access   public
683
     */
684
    function setAllAttributes($attributes = null)
685
    {
686
        for ($i = 0; $i < $this->_rows; $i++) {
687
            $this->setRowAttributes($i, $attributes);
688
        }
689
    }
690
691
    /**
692
     * Updates the attributes for all cells
693
     * @param    mixed    $attributes        (optional) Associative array or
694
     *                                       string of table row attributes
695
     * @access   public
696
     */
697
    function updateAllAttributes($attributes = null)
698
    {
699
        for ($i = 0; $i < $this->_rows; $i++) {
700
            $this->updateRowAttributes($i, $attributes);
701
        }
702
    }
703
704
    /**
705
     * Returns the table rows as HTML
706
     * @access   public
707
     * @return   string
708
     */
709
    function toHtml($tabs = null, $tab = null)
710
    {
711
        $strHtml = '';
712
        if (is_null($tabs)) {
713
            $tabs = $this->_getTabs();
714
        }
715
        if (is_null($tab)) {
716
            $tab = $this->_getTab();
717
        }
718
        $lnEnd = $this->_getLineEnd();
719
        if ($this->_useTGroups) {
720
            $extraTab = $tab;
721
        } else {
722
            $extraTab = '';
723
        }
724
        if ($this->_cols > 0) {
725
            for ($i = 0 ; $i < $this->_rows ; $i++) {
726
                $attr = '';
727
                if (isset($this->_structure[$i]['attr'])) {
728
                    $attr = $this->_getAttrString($this->_structure[$i]['attr']);
729
                }
730
                $strHtml .= $tabs .$tab . $extraTab . '<tr'.$attr.'>' . $lnEnd;
731
                for ($j = 0 ; $j < $this->_cols ; $j++) {
732
                    $attr     = '';
733
                    $contents = '';
734
                    $type     = 'td';
735
                    if (isset($this->_structure[$i][$j]) && $this->_structure[$i][$j] == '__SPANNED__') {
736
                        continue;
737
                    }
738
                    if (isset($this->_structure[$i][$j]['type'])) {
739
                        $type = (strtolower($this->_structure[$i][$j]['type']) == 'th' ? 'th' : 'td');
740
                    }
741
                    if (isset($this->_structure[$i][$j]['attr'])) {
742
                        $attr = $this->_structure[$i][$j]['attr'];
743
                    }
744
                    if (isset($this->_structure[$i][$j]['contents'])) {
745
                        $contents = $this->_structure[$i][$j]['contents'];
746
                    }
747
748
                    if (is_object($contents)) {
749
                        // changes indent and line end settings on nested tables
750
                        if (is_subclass_of($contents, 'html_common')) {
751
                            $contents->setTab($tab . $extraTab);
752
                            $contents->setTabOffset($this->_tabOffset + 3);
753
                            $contents->_nestLevel = $this->_nestLevel + 1;
754
                            $contents->setLineEnd($this->_getLineEnd());
755
                        }
756
                        if (method_exists($contents, 'toHtml')) {
757
                            $contents = $contents->toHtml();
758
                        } elseif (method_exists($contents, 'toString')) {
759
                            $contents = $contents->toString();
760
                        }
761
                    }
762
                    if (is_array($contents)) {
763
                        $contents = implode(', ', $contents);
764
                    }
765
766
                    $typeContent = $tabs . $tab . $tab . $extraTab . "<$type" . $this->_getAttrString($attr) . '>';
767
768
                    if ($contents || is_numeric($contents)) {
769
                        $typeContent .= $contents;
770
                    } elseif (empty($contents)) {
771
                        if (isset($this->_autoFill) && $this->_autoFill) {
772
                            $contents = $this->_autoFill;
773
                        }
774
                    }
775
776
                    $typeContent .= "</$type>" . $lnEnd;
777
778
                    if (!empty($contents) || is_numeric($contents)) {
779
                        $strHtml .= $typeContent;
780
                    }
781
782
                }
783
                $strHtml .= $tabs . $tab . $extraTab . '</tr>' . $lnEnd;
784
            }
785
        }
786
        return $strHtml;
787
    }
788
789
    /**
790
     * Checks if rows or columns are spanned
791
     * @param    int        $row            Row index
792
     * @param    int        $col            Column index
793
     * @access   private
794
     */
795
    function _updateSpanGrid($row, $col)
796
    {
797
        if (isset($this->_structure[$row][$col]['attr']['colspan'])) {
798
            $colspan = $this->_structure[$row][$col]['attr']['colspan'];
799
        }
800
801
        if (isset($this->_structure[$row][$col]['attr']['rowspan'])) {
802
            $rowspan = $this->_structure[$row][$col]['attr']['rowspan'];
803
        }
804
805
        if (isset($colspan)) {
806
            for ($j = $col + 1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
807
                $this->_structure[$row][$j] = '__SPANNED__';
808
            }
809
        }
810
811
        if (isset($rowspan)) {
812
            for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
813
                $this->_structure[$i][$col] = '__SPANNED__';
814
            }
815
        }
816
817
        if (isset($colspan) && isset($rowspan)) {
818
            for ($i = $row + 1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
819
                for ($j = $col + 1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
820
                    $this->_structure[$i][$j] = '__SPANNED__';
821
                }
822
            }
823
        }
824
    }
825
826
    /**
827
     * Adjusts ends (total number of rows and columns)
828
     * @param    int     $row        Row index
829
     * @param    int     $col        Column index
830
     * @param    string  $method     Method name of caller
831
     *                               Used to populate PEAR_Error if thrown.
832
     * @param    array   $attributes Assoc array of attributes
833
     *                               Default is an empty array.
834
     * @access   private
835
     * @throws   PEAR_Error
836
     */
837
    function _adjustEnds($row, $col, $method, $attributes = array())
838
    {
839
        $colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
840
        $rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
841
        if (!is_numeric($row) or !is_numeric($col)) {
842
            //throw new Exception('Row or column index is not numerical');
843
            return;
844
        }
845
        if (($row + $rowspan - 1) >= $this->_rows) {
846
            if ($this->_autoGrow) {
847
                $this->_rows = $row + $rowspan;
848
849
            } else {
850
                /*return PEAR::raiseError('Invalid table row reference[' .
851
                    $row . '] in HTML_Table::' . $method);*/
852
            }
853
        }
854
855
        if (($col + $colspan - 1) >= $this->_cols) {
856
            if ($this->_autoGrow) {
857
                $this->_cols = $col + $colspan;
858
            } else {
859
                /*return PEAR::raiseError('Invalid table column reference[' .
860
                    $col . '] in HTML_Table::' . $method);*/
861
            }
862
        }
863
    }
864
865
    /**
866
     * Tells if the parameter is an array of attribute arrays/strings
867
     * @param    mixed   $attributes Variable to test
868
     * @access   private
869
     * @return   bool
870
     */
871
    function _isAttributesArray($attributes)
872
    {
873
        if (is_array($attributes) && isset($attributes[0])) {
874
            if (is_array($attributes[0]) || (is_string($attributes[0]) && count($attributes) > 1)) {
875
                return true;
876
            }
877
        }
878
        return false;
879
    }
880
881
}
882
?>
883