~chroot64bit/zivios/gentoo-experimental

« back to all changes in this revision

Viewing changes to application/library/Zend/ProgressBar/Adapter/Console.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
 * LICENSE
 
4
 *
 
5
 * This source file is subject to the new BSD license that is bundled
 
6
 * with this package in the file LICENSE.txt.
 
7
 * It is also available through the world-wide-web at this URL:
 
8
 * http://framework.zend.com/license/new-bsd
 
9
 * If you did not receive a copy of the license and are unable to
 
10
 * obtain it through the world-wide-web, please send an email
 
11
 * to license@zend.com so we can send you a copy immediately.
 
12
 *
 
13
 * @category   Zend
 
14
 * @package    Zend_ProgressBar
 
15
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
16
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 
17
 * @version    $Id: Console.php 12233 2008-11-01 00:11:01Z dasprid $
 
18
 */
 
19
 
 
20
/**
 
21
 * @see Zend_ProgressBar_Adapter
 
22
 */
 
23
require_once 'Zend/ProgressBar/Adapter.php';
 
24
 
 
25
/**
 
26
 * Zend_ProgressBar_Adapter_Console offers a text-based progressbar for console
 
27
 * applications
 
28
 *
 
29
 * @category  Zend
 
30
 * @package   Zend_ProgressBar
 
31
 * @uses      Zend_ProgressBar_Adapter_Interface
 
32
 * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
33
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 
34
 */
 
35
class Zend_ProgressBar_Adapter_Console extends Zend_ProgressBar_Adapter
 
36
{
 
37
    /**
 
38
     * Percentage value of the progress
 
39
     */
 
40
    const ELEMENT_PERCENT = 'ELEMENT_PERCENT';
 
41
    
 
42
    /**
 
43
     * Visual value of the progress
 
44
     */
 
45
    const ELEMENT_BAR = 'ELEMENT_BAR';
 
46
 
 
47
    /**
 
48
     * ETA of the progress
 
49
     */
 
50
    const ELEMENT_ETA = 'ELEMENT_ETA';
 
51
    
 
52
    /**
 
53
     * Text part of the progress
 
54
     */
 
55
    const ELEMENT_TEXT = 'ELEMENT_TEXT';
 
56
    
 
57
    /**
 
58
     * Finish action: End of Line
 
59
     */
 
60
    const FINISH_ACTION_EOL = 'FINISH_ACTION_EOL';
 
61
    
 
62
    /**
 
63
     * Finish action: Clear Line
 
64
     */
 
65
    const FINISH_ACTION_CLEAR_LINE = 'FINISH_ACTION_CLEAR_LINE';
 
66
    
 
67
    /**
 
68
     * Finish action: None
 
69
     */
 
70
    const FINISH_ACTION_NONE = 'FINISH_ACTION_NONE';
 
71
    
 
72
    /**
 
73
     * Width of the progressbar
 
74
     *
 
75
     * @var integer
 
76
     */
 
77
    protected $_width = null;
 
78
    
 
79
    /**
 
80
     * Elements to display
 
81
     *
 
82
     * @var array
 
83
     */
 
84
    protected $_elements = array(self::ELEMENT_PERCENT,
 
85
                                 self::ELEMENT_BAR,
 
86
                                 self::ELEMENT_ETA);
 
87
    
 
88
    /**
 
89
     * Which action to do at finish call
 
90
     *
 
91
     * @var string
 
92
     */
 
93
    protected $_finishAction = self::FINISH_ACTION_EOL;
 
94
    
 
95
    /**
 
96
     * Width of the bar element
 
97
     *
 
98
     * @var integer
 
99
     */
 
100
    protected $_barWidth;
 
101
    
 
102
    /**
 
103
     * Left character(s) within the bar
 
104
     *
 
105
     * @var string
 
106
     */
 
107
    protected $_barLeftChar = '#';
 
108
 
 
109
    /**
 
110
     * Indicator character(s) within the bar
 
111
     *
 
112
     * @var string
 
113
     */
 
114
    protected $_barIndicatorChar = '';
 
115
    
 
116
    /**
 
117
     * Right character(s) within the bar
 
118
     *
 
119
     * @var string
 
120
     */
 
121
    protected $_barRightChar = '-';
 
122
       
 
123
    /**
 
124
     * Stdout stream, when STDOUT is not defined (e.g. in CGI)
 
125
     * 
 
126
     * @var resource
 
127
     */
 
128
    protected $_stdout = null;
 
129
       
 
130
    /**
 
131
     * Width of the text element
 
132
     *
 
133
     * @var string
 
134
     */
 
135
    protected $_textWidth = 20;
 
136
    
 
137
    /**
 
138
     * Wether the output started yet or not
 
139
     *
 
140
     * @var boolean
 
141
     */
 
142
    protected $_outputStarted = false;
 
143
    
 
144
    /**
 
145
     * Defined by Zend_ProgressBar_Adapter
 
146
     *
 
147
     * @param null|array|Zend_Config $options
 
148
     */
 
149
    public function __construct($options = null)
 
150
    {       
 
151
        // If STDOUT isn't defined, open a local resource
 
152
        if (!defined('STDOUT')) {
 
153
            $this->_stdout = fopen('php://stdout', 'w');
 
154
        }
 
155
        
 
156
        // Call parent constructor with options
 
157
        parent::__construct($options);
 
158
        
 
159
        // Check if a width was set, else use auto width
 
160
        if ($this->_width === null) {
 
161
            $this->setWidth();
 
162
        }
 
163
    }
 
164
       
 
165
    /**
 
166
     * Close local stdout, when open
 
167
     */
 
168
    public function __destruct()
 
169
    {
 
170
        if ($this->_stdout !== null) {
 
171
            fclose($this->_stdout);
 
172
        }
 
173
    }
 
174
    
 
175
    /**
 
176
     * Set the width of the progressbar
 
177
     *
 
178
     * @param  integer $width
 
179
     * @return Zend_ProgressBar_Adapter_Console
 
180
     */
 
181
    public function setWidth($width = null)
 
182
    {
 
183
        if ($width === null || !is_integer($width)) {
 
184
            if (substr(PHP_OS, 0, 3) === 'WIN') {
 
185
                // We have to default to 79 on windows, because the windows
 
186
                // terminal always has a fixed width of 80 characters and the
 
187
                // cursor is counted to the line, else windows would line break
 
188
                // after every update.
 
189
                $this->_width = 79; 
 
190
            } else {
 
191
                // Set the default width of 80
 
192
                $this->_width = 80;
 
193
                
 
194
                // Try to determine the width through stty
 
195
                if (preg_match('#\d+ (\d+)#', @shell_exec('stty size'), $match) === 1) {
 
196
                    $this->_width = (int) $match[1];
 
197
                } else if (preg_match('#columns = (\d+);#', @shell_exec('stty'), $match) === 1) {                       
 
198
                    $this->_width = (int) $match[1];
 
199
                }
 
200
            }
 
201
        } else {
 
202
            $this->_width = (int) $width;
 
203
        }
 
204
        
 
205
        $this->_calculateBarWidth();
 
206
        
 
207
        return $this;
 
208
    }
 
209
    
 
210
    /**
 
211
     * Set the elements to display with the progressbar
 
212
     *
 
213
     * @param  array $elements
 
214
     * @throws Zend_ProgressBar_Adapter_Exception When an invalid element is foudn in the array
 
215
     * @return Zend_ProgressBar_Adapter_Console
 
216
     */
 
217
    public function setElements(array $elements)
 
218
    {
 
219
        $allowedElements = array(self::ELEMENT_PERCENT,
 
220
                                 self::ELEMENT_BAR,
 
221
                                 self::ELEMENT_ETA,
 
222
                                 self::ELEMENT_TEXT);
 
223
                                 
 
224
        if (count(array_diff($elements, $allowedElements)) > 0) {
 
225
            require_once 'Zend/ProgressBar/Adapter/Exception.php';
 
226
            throw new Zend_ProgressBar_Adapter_Exception('Invalid element found in $elements array');                
 
227
        }
 
228
        
 
229
        $this->_elements = $elements;
 
230
        
 
231
        $this->_calculateBarWidth();
 
232
        
 
233
        return $this;
 
234
    }
 
235
    
 
236
    /**
 
237
     * Set the left-hand character for the bar
 
238
     *
 
239
     * @param  string $char
 
240
     * @throws Zend_ProgressBar_Adapter_Exception When character is empty
 
241
     * @return Zend_ProgressBar_Adapter_Console
 
242
     */
 
243
    public function setBarLeftChar($char)
 
244
    {
 
245
        if (empty($char)) {
 
246
            require_once 'Zend/ProgressBar/Adapter/Exception.php';
 
247
            throw new Zend_ProgressBar_Adapter_Exception('Character may not be empty');                
 
248
        }
 
249
        
 
250
        $this->_barLeftChar = (string) $char;
 
251
        
 
252
        return $this;
 
253
    }
 
254
    
 
255
    /**
 
256
     * Set the right-hand character for the bar
 
257
     *
 
258
     * @param  string $char
 
259
     * @throws Zend_ProgressBar_Adapter_Exception When character is empty
 
260
     * @return Zend_ProgressBar_Adapter_Console
 
261
     */
 
262
    public function setBarRightChar($char)
 
263
    {
 
264
        if (empty($char)) {
 
265
            require_once 'Zend/ProgressBar/Adapter/Exception.php';
 
266
            throw new Zend_ProgressBar_Adapter_Exception('Character may not be empty');                
 
267
        }
 
268
        
 
269
        $this->_barRightChar = (string) $char;
 
270
        
 
271
        return $this;
 
272
    }
 
273
    
 
274
    /**
 
275
     * Set the indicator character for the bar
 
276
     *
 
277
     * @param  string $char
 
278
     * @return Zend_ProgressBar_Adapter_Console
 
279
     */
 
280
    public function setBarIndicatorChar($char)
 
281
    {
 
282
        $this->_barIndicatorChar = (string) $char;
 
283
        
 
284
        return $this;
 
285
    }
 
286
 
 
287
    /**
 
288
     * Set the width of the text element
 
289
     *
 
290
     * @param  integer $width
 
291
     * @return Zend_ProgressBar_Adapter_Console
 
292
     */
 
293
    public function setTextWidth($width)
 
294
    {
 
295
        $this->_textWidth = (int) $width;
 
296
        
 
297
        $this->_calculateBarWidth();
 
298
        
 
299
        return $this;
 
300
    }
 
301
    
 
302
    /**
 
303
     * Set the finish action
 
304
     *
 
305
     * @param  string $action
 
306
     * @throws Zend_ProgressBar_Adapter_Exception When an invalid action is specified
 
307
     * @return Zend_ProgressBar_Adapter_Console
 
308
     */
 
309
    public function setFinishAction($action)
 
310
    {
 
311
        $allowedActions = array(self::FINISH_ACTION_CLEAR_LINE,
 
312
                                self::FINISH_ACTION_EOL,
 
313
                                self::FINISH_ACTION_NONE);
 
314
                     
 
315
        if (!in_array($action, $allowedActions)) {
 
316
            require_once 'Zend/ProgressBar/Adapter/Exception.php';
 
317
            throw new Zend_ProgressBar_Adapter_Exception('Invalid finish action specified');                
 
318
        }
 
319
        
 
320
        $this->_finishAction = $action;
 
321
        
 
322
        return $this;
 
323
    }
 
324
    
 
325
    /**
 
326
     * Defined by Zend_ProgressBar_Adapter_Interface
 
327
     *
 
328
     * @param  float   $current       Current progress value
 
329
     * @param  float   $max           Max progress value
 
330
     * @param  flaot   $percent       Current percent value
 
331
     * @param  integer $timeTaken     Taken time in seconds
 
332
     * @param  integer $timeRemaining Remaining time in seconds
 
333
     * @param  string  $text          Status text
 
334
     * @return void
 
335
     */
 
336
    public function notify($current, $max, $percent, $timeTaken, $timeRemaining, $text)
 
337
    {
 
338
        // See if we must clear the line
 
339
        if ($this->_outputStarted) {
 
340
            $data = str_repeat("\x08", $this->_width);
 
341
        } else {
 
342
            $data = '';
 
343
            $this->_outputStarted = true;
 
344
        }
 
345
               
 
346
        // Build all elements
 
347
        $renderedElements = array();
 
348
        
 
349
        foreach ($this->_elements as $element) {
 
350
            switch ($element) {
 
351
                case self::ELEMENT_BAR:
 
352
                    $visualWidth = $this->_barWidth - 2;                    
 
353
                    $bar         = '[';
 
354
                    
 
355
                    $indicatorWidth = strlen($this->_barIndicatorChar);
 
356
                    
 
357
                    $doneWidth = min($visualWidth - $indicatorWidth, round($visualWidth * $percent));
 
358
                    if ($doneWidth > 0) {
 
359
                        $bar .= substr(str_repeat($this->_barLeftChar, ceil($doneWidth / strlen($this->_barLeftChar))), 0, $doneWidth);
 
360
                    }
 
361
                    
 
362
                    $bar .= $this->_barIndicatorChar;
 
363
                    
 
364
                    $leftWidth = $visualWidth - $doneWidth - $indicatorWidth;
 
365
                    if ($leftWidth > 0) {
 
366
                        $bar .= substr(str_repeat($this->_barRightChar, ceil($leftWidth / strlen($this->_barRightChar))), 0, $leftWidth); 
 
367
                    }
 
368
                    
 
369
                    $bar .= ']';
 
370
                    
 
371
                    $renderedElements[] = $bar;
 
372
                    break;
 
373
                    
 
374
                case self::ELEMENT_PERCENT:
 
375
                    $renderedElements[] = str_pad(round($percent * 100), 3, ' ', STR_PAD_LEFT) . '%';
 
376
                    break;
 
377
                    
 
378
                case self::ELEMENT_ETA:
 
379
                    // In the first 5 seconds we don't get accurate results,
 
380
                    // this skipping technique is found in many progressbar
 
381
                    // implementations.
 
382
                    if ($timeTaken < 5) {
 
383
                        $renderedElements[] = str_repeat(' ', 12);
 
384
                        break;
 
385
                    }
 
386
                                        
 
387
                    if ($timeRemaining === null || $timeRemaining > 86400) {
 
388
                        $etaFormatted = '??:??:??';
 
389
                    } else {
 
390
                        $hours   = floor($timeRemaining / 3600);
 
391
                        $minutes = floor(($timeRemaining % 3600) / 60);
 
392
                        $seconds = ($timeRemaining % 3600 % 60);
 
393
                                           
 
394
                        $etaFormatted = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
 
395
                    }
 
396
                    
 
397
                    $renderedElements[] = 'ETA ' . $etaFormatted;
 
398
                    break;  
 
399
 
 
400
                case self::ELEMENT_TEXT:
 
401
                    $renderedElements[] = str_pad(substr($text, 0, $this->_textWidth), $this->_textWidth, ' ');
 
402
                    break;
 
403
            }
 
404
        }
 
405
 
 
406
        $data .= implode(' ', $renderedElements);
 
407
        
 
408
        // Output line data
 
409
        $this->_outputData($data);
 
410
    }
 
411
    
 
412
    /**
 
413
     * Defined by Zend_ProgressBar_Adapter_Interface
 
414
     *
 
415
     * @return void
 
416
     */
 
417
    public function finish()
 
418
    {
 
419
        switch ($this->_finishAction) {
 
420
            case self::FINISH_ACTION_EOL:
 
421
                $this->_outputData(PHP_EOL);
 
422
                break;
 
423
                
 
424
            case self::FINISH_ACTION_CLEAR_LINE:
 
425
                if ($this->_outputStarted) {
 
426
                    $data = str_repeat("\x08", $this->_width)
 
427
                          . str_repeat(' ', $this->_width)
 
428
                          . str_repeat("\x08", $this->_width);
 
429
                          
 
430
                    $this->_outputData($data);
 
431
                }
 
432
                break;
 
433
                
 
434
            case self::FINISH_ACTION_NONE:
 
435
                break;
 
436
        }
 
437
    }
 
438
    
 
439
    /**
 
440
     * Calculate the bar width when other elements changed
 
441
     *
 
442
     * @return void
 
443
     */
 
444
    protected function _calculateBarWidth()
 
445
    {
 
446
        if (in_array(self::ELEMENT_BAR, $this->_elements)) {
 
447
            $barWidth = $this->_width;
 
448
            
 
449
            if (in_array(self::ELEMENT_PERCENT, $this->_elements)) {
 
450
                $barWidth -= 4;
 
451
            }
 
452
            
 
453
            if (in_array(self::ELEMENT_ETA, $this->_elements)) {
 
454
                $barWidth -= 12;
 
455
            }
 
456
            
 
457
            if (in_array(self::ELEMENT_TEXT, $this->_elements)) {
 
458
                $barWidth -= $this->_textWidth;
 
459
            }
 
460
            
 
461
            $this->_barWidth = $barWidth - (count($this->_elements) - 1);
 
462
        }
 
463
    }
 
464
    
 
465
    /**
 
466
     * Outputs given data to STDOUT.
 
467
     * 
 
468
     * This split-off is required for unit-testing.
 
469
     *
 
470
     * @param  string $data
 
471
     * @return void
 
472
     */
 
473
    protected function _outputData($data)
 
474
    {
 
475
        if ($this->_stdout !== null) {
 
476
            fwrite($this->_stdout, $data);
 
477
        } else {
 
478
            fwrite(STDOUT, $data);
 
479
        }            
 
480
    }
 
481
}
 
 
b'\\ No newline at end of file'