~chroot64bit/zivios/gentoo-experimental

« back to all changes in this revision

Viewing changes to application/library/Zend/Text/Table.php

  • Committer: Mustafa A. Hashmi
  • Date: 2008-12-04 13:32:21 UTC
  • Revision ID: mhashmi@zivios.org-20081204133221-0nd1trunwevijj38
Inclusion of new installation framework with ties to zend layout and dojo layout

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Zend Framework
 
4
 *
 
5
 * LICENSE
 
6
 *
 
7
 * This source file is subject to the new BSD license that is bundled
 
8
 * with this package in the file LICENSE.txt.
 
9
 * It is also available through the world-wide-web at this URL:
 
10
 * http://framework.zend.com/license/new-bsd
 
11
 * If you did not receive a copy of the license and are unable to
 
12
 * obtain it through the world-wide-web, please send an email
 
13
 * to license@zend.com so we can send you a copy immediately.
 
14
 *
 
15
 * @category  Zend
 
16
 * @package   Zend_Text_Table
 
17
 * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
18
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 
19
 * @version   $Id: Table.php 12550 2008-11-11 15:26:47Z dasprid $
 
20
 */
 
21
 
 
22
/**
 
23
 * Zend_Text_Table enables developers to create tables out of characters
 
24
 *
 
25
 * @category  Zend
 
26
 * @package   Zend_Text_Table
 
27
 * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
28
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 
29
 */
 
30
class Zend_Text_Table
 
31
{
 
32
    /**
 
33
     * Auto seperator settings
 
34
     */
 
35
    const AUTO_SEPARATE_NONE   = 0x0;
 
36
    const AUTO_SEPARATE_HEADER = 0x1;
 
37
    const AUTO_SEPARATE_FOOTER = 0x2;
 
38
    const AUTO_SEPARATE_ALL    = 0x4;
 
39
    
 
40
    /**
 
41
     * Decorator used for the table borders
 
42
     *
 
43
     * @var Zend_Text_Table_Decorator_Interface
 
44
     */
 
45
    protected $_decorator = null;
 
46
 
 
47
    /**
 
48
     * List of all column widths
 
49
     *
 
50
     * @var array
 
51
     */
 
52
    protected $_columnWidths = null;
 
53
 
 
54
    /**
 
55
     * Rows of the table
 
56
     *
 
57
     * @var array
 
58
     */
 
59
    protected $_rows = array();
 
60
    
 
61
    /**
 
62
     * Auto separation mode
 
63
     *
 
64
     * @var integer
 
65
     */
 
66
    protected $_autoSeparate = self::AUTO_SEPARATE_ALL;
 
67
    
 
68
    /**
 
69
     * Padding for columns
 
70
     *
 
71
     * @var integer
 
72
     */
 
73
    protected $_padding = 0;
 
74
    
 
75
    /**
 
76
     * Default column aligns for rows created by appendRow(array $data)
 
77
     *
 
78
     * @var array
 
79
     */
 
80
    protected $_defaultColumnAligns = array();
 
81
 
 
82
    /**
 
83
     * Plugin loader for decorators
 
84
     *
 
85
     * @var string
 
86
     */
 
87
    protected $_pluginLoader = null;
 
88
    
 
89
    /**
 
90
     * Charset which is used for input by default
 
91
     *
 
92
     * @var string
 
93
     */
 
94
    protected static $_inputCharset = 'utf-8';
 
95
    
 
96
    /**
 
97
     * Charset which is used internally
 
98
     *
 
99
     * @var string
 
100
     */
 
101
    protected static $_outputCharset = 'utf-8';
 
102
    
 
103
    /**
 
104
     * Option keys to skip when calling setOptions()
 
105
     * 
 
106
     * @var array
 
107
     */
 
108
    protected $_skipOptions = array(
 
109
        'options',
 
110
        'config',
 
111
        'defaultColumnAlign',
 
112
    );
 
113
        
 
114
    /**
 
115
     * Create a basic table object
 
116
     *
 
117
     * @param  array             $columnsWidths List of all column widths
 
118
     * @param  Zend_Config|array $options       Configuration options
 
119
     * @throws Zend_Text_Table_Exception When no columns widths were set
 
120
     */
 
121
    public function __construct($options = null)
 
122
    {       
 
123
        // Set options
 
124
        if (is_array($options)) {
 
125
            $this->setOptions($options);
 
126
        } else if ($options instanceof Zend_Config) {
 
127
            $this->setConfig($options);
 
128
        }
 
129
 
 
130
        // Check if column widths were set
 
131
        // @todo When column widths were not set, assume auto-sizing
 
132
        if ($this->_columnWidths === null) {
 
133
            require_once 'Zend/Text/Table/Exception.php';
 
134
            throw new Zend_Text_Table_Exception('You must define the column widths');
 
135
        }
 
136
        
 
137
        // If no decorator was given, use default unicode decorator
 
138
        if ($this->_decorator === null) {
 
139
            if (self::getOutputCharset() === 'utf-8') {
 
140
                $this->setDecorator('unicode');
 
141
            } else {
 
142
                $this->setDecorator('ascii');
 
143
            }
 
144
        }
 
145
    }
 
146
    
 
147
    /**
 
148
     * Set options from array
 
149
     *
 
150
     * @param  array $options Configuration for Zend_Text_Table
 
151
     * @return Zend_Text_Table
 
152
     */
 
153
    public function setOptions(array $options)
 
154
    {
 
155
        foreach ($options as $key => $value) {
 
156
            if (in_array(strtolower($key), $this->_skipOptions)) {
 
157
                continue;
 
158
            }
 
159
 
 
160
            $method = 'set' . ucfirst($key);
 
161
            if (method_exists($this, $method)) {
 
162
                $this->$method($value);
 
163
            }
 
164
        }
 
165
        
 
166
        return $this;
 
167
    }
 
168
 
 
169
    /**
 
170
     * Set options from config object
 
171
     *
 
172
     * @param  Zend_Config $config Configuration for Zend_Text_Table
 
173
     * @return Zend_Text_Table
 
174
     */
 
175
    public function setConfig(Zend_Config $config)
 
176
    {
 
177
        return $this->setOptions($config->toArray());
 
178
    }
 
179
    
 
180
    /**
 
181
     * Set column widths
 
182
     *
 
183
     * @param  array $columnWidths Widths of all columns
 
184
     * @throws Zend_Text_Table_Exception When no columns were supplied
 
185
     * @throws Zend_Text_Table_Exception When a column has an invalid width
 
186
     * @return Zend_Text_Table
 
187
     */
 
188
    public function setColumnWidths(array $columnWidths)
 
189
    {
 
190
        if (count($columnWidths) === 0) {
 
191
            require_once 'Zend/Text/Table/Exception.php';
 
192
            throw new Zend_Text_Table_Exception('You must supply at least one column');
 
193
        }
 
194
        
 
195
        foreach ($columnWidths as $columnNum => $columnWidth) {
 
196
            if (is_int($columnWidth) === false or $columnWidth < 1) {
 
197
                require_once 'Zend/Text/Table/Exception.php';
 
198
                throw new Zend_Text_Table_Exception('Column ' . $columnNum . ' has an invalid'
 
199
                                                    . ' column width');
 
200
            }
 
201
        }
 
202
 
 
203
        $this->_columnWidths = $columnWidths;
 
204
        
 
205
        return $this;
 
206
    }
 
207
 
 
208
    /**
 
209
     * Set auto separation mode
 
210
     *
 
211
     * @param  integer $autoSeparate Auto separation mode
 
212
     * @return Zend_Text_Table
 
213
     */
 
214
    public function setAutoSeparate($autoSeparate)
 
215
    {
 
216
        $this->_autoSeparate = (int) $autoSeparate;
 
217
        return $this;
 
218
    }
 
219
       
 
220
    /**
 
221
     * Set decorator
 
222
     *
 
223
     * @param  Zend_Text_Table_Decorator_Interface|string $decorator Decorator to use
 
224
     * @return Zend_Text_Table
 
225
     */
 
226
    public function setDecorator($decorator)
 
227
    {
 
228
        if ($decorator instanceof Zend_Text_Table_Decorator_Interface) {
 
229
            $this->_decorator = $decorator;
 
230
        } else {
 
231
            $classname        = $this->getPluginLoader()->load($decorator);
 
232
            $this->_decorator = new $classname;
 
233
        }
 
234
        
 
235
        return $this;
 
236
    }
 
237
    
 
238
    /**
 
239
     * Set the column padding
 
240
     *
 
241
     * @param  integer $padding The padding for the columns
 
242
     * @return Zend_Text_Table
 
243
     */
 
244
    public function setPadding($padding)
 
245
    {
 
246
        $this->_padding = max(0, (int) $padding);
 
247
        return $this;
 
248
    }
 
249
    
 
250
    /**
 
251
     * Get the plugin loader for decorators
 
252
     *
 
253
     * @return Zend_Loader_PluginLoader
 
254
     */
 
255
    public function getPluginLoader()
 
256
    {
 
257
        if ($this->_pluginLoader === null) {
 
258
            $prefix     = 'Zend_Text_Table_Decorator_';
 
259
            $pathPrefix = 'Zend/Text/Table/Decorator/';
 
260
    
 
261
            require_once 'Zend/Loader/PluginLoader.php';
 
262
            $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix));
 
263
        }
 
264
        
 
265
        return $this->_pluginLoader;
 
266
    }
 
267
    
 
268
    /**
 
269
     * Set default column align for rows created by appendRow(array $data) 
 
270
     *
 
271
     * @param  integer $columnNum
 
272
     * @param  string  $align
 
273
     * @return Zend_Text_Table
 
274
     */
 
275
    public function setDefaultColumnAlign($columnNum, $align) 
 
276
    {
 
277
        $this->_defaultColumnAligns[$columnNum] = $align;
 
278
        
 
279
        return $this;
 
280
    }
 
281
 
 
282
    /**
 
283
     * Set the input charset for column contents
 
284
     *
 
285
     * @param string $charset
 
286
     */
 
287
    public static function setInputCharset($charset)
 
288
    {
 
289
        self::$_inputCharset = strtolower($charset);
 
290
    }
 
291
    
 
292
    /**
 
293
     * Get the input charset for column contents
 
294
     *
 
295
     * @param string $charset
 
296
     */
 
297
    public static function getInputCharset()
 
298
    {
 
299
        return self::$_inputCharset;
 
300
    }
 
301
    
 
302
    /**
 
303
     * Set the output charset for column contents
 
304
     *
 
305
     * @param string $charset
 
306
     */
 
307
    public static function setOutputCharset($charset)
 
308
    {
 
309
        self::$_outputCharset = strtolower($charset);
 
310
    }
 
311
    
 
312
    /**
 
313
     * Get the output charset for column contents
 
314
     *
 
315
     * @param string $charset
 
316
     */
 
317
    public static function getOutputCharset()
 
318
    {
 
319
        return self::$_outputCharset;
 
320
    }
 
321
    
 
322
    /**
 
323
     * Append a row to the table
 
324
     *
 
325
     * @param  array|Zend_Text_Table_Row $row The row to append to the table
 
326
     * @throws Zend_Text_Table_Exception When $row is neither an array nor Zend_Zext_Table_Row
 
327
     * @throws Zend_Text_Table_Exception When a row contains too many columns
 
328
     * @return Zend_Text_Table
 
329
     */
 
330
    public function appendRow($row)
 
331
    {
 
332
        if (!is_array($row) && !($row instanceof Zend_Text_Table_Row)) {
 
333
            require_once 'Zend/Text/Table/Exception.php';
 
334
            throw new Zend_Text_Table_Exception('$row must be an array or instance of Zend_Text_Table_Row');
 
335
        }
 
336
        
 
337
        if (is_array($row)) {
 
338
            if (count($row) > count($this->_columnWidths)) {
 
339
                require_once 'Zend/Text/Table/Exception.php';
 
340
                throw new Zend_Text_Table_Exception('Row contains too many columns');
 
341
            }
 
342
                        
 
343
            require_once 'Zend/Text/Table/Row.php';
 
344
            
 
345
            $data   = $row;
 
346
            $row    = new Zend_Text_Table_Row();
 
347
            $colNum = 0;
 
348
            foreach ($data as $columnData) {
 
349
                if (isset($this->_defaultColumnAligns[$colNum])) {
 
350
                    $align = $this->_defaultColumnAligns[$colNum];
 
351
                } else {
 
352
                    $align = null;
 
353
                }
 
354
                
 
355
                $row->appendColumn(new Zend_Text_Table_Column($columnData, $align));
 
356
                $colNum++;    
 
357
            }
 
358
        }
 
359
        
 
360
        $this->_rows[] = $row;
 
361
        
 
362
        return $this;
 
363
    }
 
364
 
 
365
    /**
 
366
     * Render the table
 
367
     *
 
368
     * @throws Zend_Text_Table_Exception When no rows were added to the table
 
369
     * @return string
 
370
     */
 
371
    public function render()
 
372
    {
 
373
        // There should be at least one row
 
374
        if (count($this->_rows) === 0) {
 
375
            require_once 'Zend/Text/Table/Exception.php';
 
376
            throw new Zend_Text_Table_Exception('No rows were added to the table yet');
 
377
        }
 
378
 
 
379
        // Initiate the result variable
 
380
        $result = '';
 
381
 
 
382
        // Count total columns
 
383
        $totalNumColumns = count($this->_columnWidths);
 
384
 
 
385
        // Now render all rows, starting from the first one
 
386
        $numRows = count($this->_rows);
 
387
        foreach ($this->_rows as $rowNum => $row) {
 
388
            // Get all column widths
 
389
            if (isset($columnWidths) === true) {
 
390
                $lastColumnWidths = $columnWidths;
 
391
            }
 
392
 
 
393
            $renderedRow  = $row->render($this->_columnWidths, $this->_decorator, $this->_padding);
 
394
            $columnWidths = $row->getColumnWidths();
 
395
            $numColumns   = count($columnWidths);
 
396
 
 
397
            // Check what we have to draw
 
398
            if ($rowNum === 0) {
 
399
                // If this is the first row, draw the table top
 
400
                $result .= $this->_decorator->getTopLeft();
 
401
 
 
402
                foreach ($columnWidths as $columnNum => $columnWidth) {
 
403
                    $result .= str_repeat($this->_decorator->getHorizontal(),
 
404
                                          $columnWidth);
 
405
 
 
406
                    if (($columnNum + 1) === $numColumns) {
 
407
                        $result .= $this->_decorator->getTopRight();
 
408
                    } else {
 
409
                        $result .= $this->_decorator->getHorizontalDown();
 
410
                    }
 
411
                }
 
412
 
 
413
                $result .= "\n";
 
414
            } else {
 
415
                // Else check if we have to draw the row separator
 
416
                if ($this->_autoSeparate & self::AUTO_SEPARATE_ALL) {
 
417
                    $drawSeparator = true;
 
418
                } else if ($rowNum === 1 && $this->_autoSeparate & self::AUTO_SEPARATE_HEADER) {
 
419
                    $drawSeparator = true;
 
420
                } else if ($rowNum === ($numRows - 1) && $this->_autoSeparate & self::AUTO_SEPARATE_FOOTER) {
 
421
                    $drawSeparator = true;
 
422
                } else {
 
423
                    $drawSeparator = false;
 
424
                }
 
425
                
 
426
                if ($drawSeparator) {             
 
427
                    $result .= $this->_decorator->getVerticalRight();
 
428
    
 
429
                    $currentUpperColumn = 0;
 
430
                    $currentLowerColumn = 0;
 
431
                    $currentUpperWidth  = 0;
 
432
                    $currentLowerWidth  = 0;
 
433
    
 
434
                    // Loop through all column widths
 
435
                    foreach ($this->_columnWidths as $columnNum => $columnWidth) {
 
436
                        // Add the horizontal line
 
437
                        $result .= str_repeat($this->_decorator->getHorizontal(),
 
438
                                              $columnWidth);
 
439
    
 
440
                        // If this is the last line, break out
 
441
                        if (($columnNum + 1) === $totalNumColumns) {
 
442
                            break;
 
443
                        }
 
444
    
 
445
                        // Else check, which connector style has to be used
 
446
                        $connector          = 0x0;
 
447
                        $currentUpperWidth += $columnWidth;
 
448
                        $currentLowerWidth += $columnWidth;
 
449
    
 
450
                        if ($lastColumnWidths[$currentUpperColumn] === $currentUpperWidth) {
 
451
                            $connector          |= 0x1;
 
452
                            $currentUpperColumn += 1;
 
453
                            $currentUpperWidth   = 0;
 
454
                        } else {
 
455
                            $currentUpperWidth += 1;
 
456
                        }
 
457
    
 
458
                        if ($columnWidths[$currentLowerColumn] === $currentLowerWidth) {
 
459
                            $connector          |= 0x2;
 
460
                            $currentLowerColumn += 1;
 
461
                            $currentLowerWidth   = 0;
 
462
                        } else {
 
463
                            $currentLowerWidth += 1;
 
464
                        }
 
465
    
 
466
                        switch ($connector) {
 
467
                            case 0x0:
 
468
                                $result .= $this->_decorator->getHorizontal();
 
469
                                break;
 
470
    
 
471
                            case 0x1:
 
472
                                $result .= $this->_decorator->getHorizontalUp();
 
473
                                break;
 
474
    
 
475
                            case 0x2:
 
476
                                $result .= $this->_decorator->getHorizontalDown();
 
477
                                break;
 
478
    
 
479
                            case 0x3:
 
480
                                $result .= $this->_decorator->getCross();
 
481
                                break;
 
482
    
 
483
                            default:
 
484
                                // This can never happen, but the CS tells I have to have it ...
 
485
                                break;
 
486
                        }
 
487
                    }
 
488
    
 
489
                    $result .= $this->_decorator->getVerticalLeft() . "\n";
 
490
                }
 
491
            }
 
492
 
 
493
            // Add the rendered row to the result
 
494
            $result .= $renderedRow;
 
495
 
 
496
            // If this is the last row, draw the table bottom
 
497
            if (($rowNum + 1) === $numRows) {
 
498
                $result .= $this->_decorator->getBottomLeft();
 
499
 
 
500
                foreach ($columnWidths as $columnNum => $columnWidth) {
 
501
                    $result .= str_repeat($this->_decorator->getHorizontal(),
 
502
                                          $columnWidth);
 
503
 
 
504
                    if (($columnNum + 1) === $numColumns) {
 
505
                        $result .= $this->_decorator->getBottomRight();
 
506
                    } else {
 
507
                        $result .= $this->_decorator->getHorizontalUp();
 
508
                    }
 
509
                }
 
510
 
 
511
                $result .= "\n";
 
512
            }
 
513
        }
 
514
 
 
515
        return $result;
 
516
    }
 
517
 
 
518
    /**
 
519
     * Magic method which returns the rendered table
 
520
     *
 
521
     * @return string
 
522
     */
 
523
    public function __toString()
 
524
    {
 
525
        try {
 
526
            return $this->render();
 
527
        } catch (Exception $e) {
 
528
            trigger_error($e->getMessage(), E_USER_ERROR);
 
529
        }
 
530
 
 
531
    }
 
532
}