1<?php 2/** 3 * PHP Command Line Tools 4 * 5 * This source file is subject to the MIT license that is bundled 6 * with this package in the file LICENSE. 7 * 8 * @author James Logsdon <dwarf@girsbrain.org> 9 * @copyright 2010 James Logsdom (http://girsbrain.org) 10 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 11 */ 12 13namespace cli; 14 15/** 16 * A more complex type of Notifier, `Progress` Notifiers always have a maxim 17 * value and generally show some form of percent complete or estimated time 18 * to completion along with the standard Notifier displays. 19 * 20 * @see cli\Notify 21 */ 22abstract class Progress extends \cli\Notify { 23 protected $_total = 0; 24 25 /** 26 * Instantiates a Progress Notifier. 27 * 28 * @param string $msg The text to display next to the Notifier. 29 * @param int $total The total number of ticks we will be performing. 30 * @param int $interval The interval in milliseconds between updates. 31 * @see cli\Progress::setTotal() 32 */ 33 public function __construct($msg, $total, $interval = 100) { 34 parent::__construct($msg, $interval); 35 $this->setTotal($total); 36 } 37 38 /** 39 * Set the max increments for this progress notifier. 40 * 41 * @param int $total The total number of times this indicator should be `tick`ed. 42 * @throws \InvalidArgumentException Thrown if the `$total` is less than 0. 43 */ 44 public function setTotal($total) { 45 $this->_total = (int)$total; 46 47 if ($this->_total < 0) { 48 throw new \InvalidArgumentException('Maximum value out of range, must be positive.'); 49 } 50 } 51 52 /** 53 * Reset the progress state so the same instance can be used in multiple loops. 54 */ 55 public function reset($total = null) { 56 parent::reset(); 57 58 if ($total) { 59 $this->setTotal($total); 60 } 61 } 62 63 /** 64 * Behaves in a similar manner to `cli\Notify::current()`, but the output 65 * is padded to match the length of `cli\Progress::total()`. 66 * 67 * @return string The formatted and padded tick count. 68 * @see cli\Progress::total() 69 */ 70 public function current() { 71 $size = strlen($this->total()); 72 return str_pad(parent::current(), $size); 73 } 74 75 /** 76 * Returns the formatted total expected ticks. 77 * 78 * @return string The formatted total ticks. 79 */ 80 public function total() { 81 return number_format($this->_total); 82 } 83 84 /** 85 * Calculates the estimated total time for the tick count to reach the 86 * total ticks given. 87 * 88 * @return int The estimated total number of seconds for all ticks to be 89 * completed. This is not the estimated time left, but total. 90 * @see cli\Notify::speed() 91 * @see cli\Notify::elapsed() 92 */ 93 public function estimated() { 94 $speed = $this->speed(); 95 if (!$speed || !$this->elapsed()) { 96 return 0; 97 } 98 99 $estimated = round($this->_total / $speed); 100 return $estimated; 101 } 102 103 /** 104 * Forces the current tick count to the total ticks given at instatiation 105 * time before passing on to `cli\Notify::finish()`. 106 */ 107 public function finish() { 108 $this->_current = $this->_total; 109 parent::finish(); 110 } 111 112 /** 113 * Increments are tick counter by the given amount. If no amount is provided, 114 * the ticker is incremented by 1. 115 * 116 * @param int $increment The amount to increment by. 117 */ 118 public function increment($increment = 1) { 119 $this->_current = min($this->_total, $this->_current + $increment); 120 } 121 122 /** 123 * Calculate the percentage completed. 124 * 125 * @return float The percent completed. 126 */ 127 public function percent() { 128 if ($this->_total == 0) { 129 return 1; 130 } 131 132 return ($this->_current / $this->_total); 133 } 134} 135