Apache Zeta Components Manual :: File Source for progressbar.php

Source for file progressbar.php

Documentation is available at progressbar.php

  1. <?php
  2. /**
  3.  * File containing the ezcConsoleProgressbar class.
  4.  *
  5.  * Licensed to the Apache Software Foundation (ASF) under one
  6.  * or more contributor license agreements.  See the NOTICE file
  7.  * distributed with this work for additional information
  8.  * regarding copyright ownership.  The ASF licenses this file
  9.  * to you under the Apache License, Version 2.0 (the
  10.  * "License"); you may not use this file except in compliance
  11.  * with the License.  You may obtain a copy of the License at
  12.  * 
  13.  *   http://www.apache.org/licenses/LICENSE-2.0
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing,
  16.  * software distributed under the License is distributed on an
  17.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18.  * KIND, either express or implied.  See the License for the
  19.  * specific language governing permissions and limitations
  20.  * under the License.
  21.  *
  22.  * @package ConsoleTools
  23.  * @version //autogentag//
  24.  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25.  * @filesource
  26.  */
  27.  
  28. /**
  29.  * Creating and maintaining progress-bars to be printed to the console.
  30.  *
  31.  * <code>
  32.  * $out = new ezcConsoleOutput();
  33.  * 
  34.  * // Create progress bar itself
  35.  * $progress = new ezcConsoleProgressbar( $out, 100, array( 'step' => 5 ) );
  36.  * 
  37.  * $progress->options->emptyChar = '-';
  38.  * $progress->options->progressChar = '#';
  39.  * $progress->options->formatString = "Uploading file </tmp/foobar.tar.bz2>: %act%/%max% kb [%bar%]";
  40.  * 
  41.  * // Perform actions
  42.  * $i = 0;
  43.  * while ( $i++ < 20 )
  44.  * {
  45.  *     // Do whatever you want to indicate progress for
  46.  *     usleep( mt_rand( 20000, 2000000 ) );
  47.  *     // Advance the progressbar by one step ( uploading 5k per run )
  48.  *     $progress->advance();
  49.  * }
  50.  * 
  51.  * // Finish progress bar and jump to next line.
  52.  * $progress->finish();
  53.  * 
  54.  * $out->outputText( "Successfully uploaded </tmp/foobar.tar.bz2>.\n", 'success' );
  55.  * </code>
  56.  * 
  57.  * @property ezcConsoleProgressbarOptions $options 
  58.  *            Contains the options for this class.
  59.  * @property int $max 
  60.  *            The maximum progress value to reach.
  61.  *
  62.  * @package ConsoleTools
  63.  * @version //autogen//
  64.  * @mainclass
  65.  */
  66. {
  67.     /**
  68.      * Container to hold the properties
  69.      *
  70.      * @var array(string=>mixed) 
  71.      */
  72.     protected $properties;
  73.  
  74.     /**
  75.      * Storage for actual values to be replaced in the format string.
  76.      * Actual values are stored here and will be inserted into the bar
  77.      * before printing it.
  78.      * 
  79.      * @var array(string=>string) 
  80.      */
  81.     protected $valueMap = array
  82.         'bar'       => '',
  83.         'fraction'  => '',
  84.         'act'       => '',
  85.         'max'       => '',
  86.     );
  87.  
  88.     /**
  89.      * Stores the bar utilization.
  90.      *
  91.      * This array saves how much space a specific part of the bar utilizes to not
  92.      * recalculate those on every step.
  93.      * 
  94.      * @var array(string=>int) 
  95.      */
  96.     protected $measures = array
  97.         'barSpace'          => 0,
  98.         'fractionSpace'     => 0,
  99.         'actSpace'          => 0,
  100.         'maxSpace'          => 0,
  101.         'fixedCharSpace'    => 0,
  102.     );
  103.  
  104.     /**
  105.      * The current step the progress bar should show.
  106.      * 
  107.      * @var int 
  108.      */
  109.     protected $currentStep = 0;
  110.  
  111.     /**
  112.      * The maximum number of steps to go.
  113.      * Calculated once from the settings.
  114.      *
  115.      * @var int 
  116.      */
  117.     protected $numSteps = 0;
  118.  
  119.     /**
  120.      * The ezcConsoleOutput object to use.
  121.      *
  122.      * @var ezcConsoleOutput 
  123.      */
  124.     protected $output;
  125.  
  126.     /**
  127.      * Indicates if the starting point for the bar has been stored.
  128.      * Per default this is false to indicate that no start position has been
  129.      * stored, yet.
  130.      * 
  131.      * @var bool 
  132.      */
  133.     protected $started = false;
  134.  
  135.     /**
  136.      * Tool object to perform multi-byte encoding safe string operations.
  137.      * 
  138.      * @var ezcConsoleStringTool 
  139.      */
  140.     private $stringTool;
  141.  
  142.     /**
  143.      * Creates a new progress bar.
  144.      *
  145.      * @param ezcConsoleOutput $outHandler   Handler to utilize for output
  146.      * @param int $max                       Maximum value, where progressbar
  147.      *                                        reaches 100%.
  148.      * @param array(string=>string) $options Options
  149.      *
  150.      * @see ezcConsoleProgressbar::$options
  151.      */
  152.     public function __constructezcConsoleOutput $outHandler$maxarray $options array() )
  153.     {
  154.         $this->output     = $outHandler;
  155.         $this->stringTool new ezcConsoleStringTool();
  156.         $this->__set'max'$max );
  157.         $this->properties['options'new ezcConsoleProgressbarOptions$options );
  158.     }
  159.     
  160.     /**
  161.      * Set new options.
  162.      * This method allows you to change the options of progressbar.
  163.      *  
  164.      * @param ezcConsoleProgresbarOptions $options The options to set.
  165.      *
  166.      * @throws ezcBaseSettingNotFoundException
  167.      *          If you tried to set a non-existent option value.
  168.      * @throws ezcBaseSettingValueException
  169.      *          If the value is not valid for the desired option.
  170.      * @throws ezcBaseValueException
  171.      *          If you submit neither an array nor an instance of
  172.      *          ezcConsoleProgresbarOptions.
  173.      */
  174.     public function setOptions$options 
  175.     {
  176.         if is_array$options ) ) 
  177.         {
  178.             $this->properties['options']->merge$options );
  179.         
  180.         else if $options instanceof ezcConsoleProgressbarOptions 
  181.         {
  182.             $this->properties['options'$options;
  183.         }
  184.         else
  185.         {
  186.             throw new ezcBaseValueException"options"$options"instance of ezcConsoleProgressbarOptions" );
  187.         }
  188.     }
  189.  
  190.     /**
  191.      * Returns the current options.
  192.      * Returns the options currently set for this progressbar.
  193.      * 
  194.      * @return ezcConsoleProgressbarOptions The current options.
  195.      */
  196.     public function getOptions()
  197.     {
  198.         return $this->properties['options'];
  199.     }
  200.  
  201.     /**
  202.      * Property read access.
  203.      * 
  204.      * @param string $key Name of the property.
  205.      * @return mixed Value of the property or null.
  206.      *
  207.      * @throws ezcBasePropertyNotFoundException
  208.      *          If the the desired property is not found.
  209.      * @ignore
  210.      */
  211.     public function __get$key )
  212.     {
  213.         switch $key )
  214.         {
  215.             case 'options':
  216.                 return $this->properties['options'];
  217.             case 'step':
  218.                 // Step is now an option
  219.                 return $this->properties['options']->step;
  220.             case 'max':
  221.                 return $this->properties[$key];
  222.             default:
  223.                 break;
  224.         }
  225.         throw new ezcBasePropertyNotFoundException$key );
  226.     }
  227.  
  228.     /**
  229.      * Property write access.
  230.      * 
  231.      * @param string $key Name of the property.
  232.      * @param mixed $val  The value for the property.
  233.      *
  234.      * @throws ezcBasePropertyNotFoundException
  235.      *          If a desired property could not be found.
  236.      * @throws ezcBaseValueException
  237.      *          If a desired property value is out of range.
  238.      * @ignore
  239.      */
  240.     public function __set$key$val )
  241.     {
  242.         switch $key )
  243.         {
  244.             case 'options':
  245.                 if !$val instanceof ezcConsoleProgressbarOptions ) )
  246.                 {
  247.                     throw new ezcBaseValueException'options',  $val'instance of ezcConsoleProgressbarOptions' );
  248.                 };
  249.                 break;
  250.             case 'max':
  251.                 if ( ( !is_int$val && !is_float$val ) ) || $val )
  252.                 {
  253.                     throw new ezcBaseValueException$key$val'number >= 0' );
  254.                 }
  255.                 break;
  256.             case 'step':
  257.                 if ( ( !is_int$val && !is_float$val ) ) || $val )
  258.                 {
  259.                     throw new ezcBaseValueException$key$val'number >= 0' );
  260.                 }
  261.                 // Step is now an option.
  262.                 $this->properties['options']->step $val;
  263.                 return;
  264.             default:
  265.                 throw new ezcBasePropertyNotFoundException$key );
  266.                 break;
  267.         }
  268.         // Changes settings or options, need for recalculating measures
  269.         $this->started = false;
  270.         $this->properties[$key$val;
  271.     }
  272.  
  273.     /**
  274.      * Property isset access.
  275.      * 
  276.      * @param string $key Name of the property.
  277.      * @return bool True is the property is set, otherwise false.
  278.      * @ignore
  279.      */
  280.     public function __isset$key )
  281.     {
  282.         switch $key )
  283.         {
  284.             case 'options':
  285.             case 'max':
  286.             case 'step':
  287.                 return true;
  288.         }
  289.         return false;
  290.     }
  291.  
  292.     /**
  293.      * Start the progress bar
  294.      * Starts the progress bar and sticks it to the current line.
  295.      * No output will be done yet. Call {@link ezcConsoleProgressbar::output()}
  296.      * to print the bar.
  297.      * 
  298.      * @return void 
  299.      */
  300.     public function start(
  301.     {
  302.         $this->calculateMeasures();
  303.         $this->output->storePos();
  304.         $this->started = true;
  305.     }
  306.  
  307.     /**
  308.      * Draw the progress bar.
  309.      * Prints the progress-bar to the screen. If start() has not been called
  310.      * yet, the current line is used for {@link ezcConsolProgressbar::start()}.
  311.      *
  312.      * @return void 
  313.      */
  314.     public function output()
  315.     {
  316.         if $this->options->minVerbosity $this->output->options->verbosityLevel
  317.              || $this->options->maxVerbosity !== false 
  318.                   && $this->options->maxVerbosity $this->output->options->verbosityLevel
  319.                 )
  320.            )
  321.         {
  322.             // Do not print progress bar if verbosity level is lower than it's
  323.             // output objects value.
  324.             return;
  325.         }
  326.  
  327.         if $this->started === false )
  328.         {
  329.             $this->start();
  330.         }
  331.  
  332.         $this->output->restorePos();
  333.         if ezcBaseFeatures::os(=== "Windows" )
  334.         {
  335.             echo str_repeat"\x8"$this->options->width );
  336.         }
  337.  
  338.         $this->generateValues();
  339.         echo $this->insertValues();
  340.     }
  341.  
  342.     /**
  343.      * Advance the progress bar.
  344.      * Advances the progress bar by $step steps. Redraws the bar by default,
  345.      * using the {@link ezcConsoleProgressbar::output()} method.
  346.      *
  347.      * @param bool  $redraw Whether to redraw the bar immediately.
  348.      * @param int $step     How many steps to advance.
  349.      * @return void 
  350.      */
  351.     public function advance$redraw true$step 
  352.     {
  353.         $this->currentStep += $step;
  354.         if $redraw === true && $this->currentStep % $this->properties['options']->redrawFrequency === )
  355.         {
  356.             $this->output();
  357.         }
  358.     }
  359.  
  360.     /**
  361.      * Finish the progress bar.
  362.      * Finishes the bar (jump to 100% if not happened yet,...) and jumps
  363.      * to the next line to allow new output. Also resets the values of the
  364.      * output handler used, if changed.
  365.      *
  366.      * @return void 
  367.      */
  368.     public function finish()
  369.     {
  370.         $this->currentStep = $this->numSteps;
  371.         $this->output();
  372.     }
  373.  
  374.     /**
  375.      * Generate all values to be replaced in the format string.
  376.      * 
  377.      * @return void 
  378.      */
  379.     protected function generateValues()
  380.     {
  381.         // Bar
  382.         $barFilledSpace ceil$this->measures['barSpace'$this->numSteps * $this->currentStep );
  383.         // Sanitize value if it gets to large by rounding
  384.         $barFilledSpace $barFilledSpace $this->measures['barSpace'$this->measures['barSpace'$barFilledSpace;
  385.         $bar $this->stringTool->strPad
  386.             $this->stringTool->strPad
  387.                 $this->properties['options']->progressChar
  388.                 $barFilledSpace
  389.                 $this->properties['options']->barChar
  390.                 STR_PAD_LEFT
  391.             )
  392.             $this->measures['barSpace']
  393.             $this->properties['options']->emptyChar
  394.             STR_PAD_RIGHT 
  395.         );
  396.         $this->valueMap['bar'$bar;
  397.  
  398.         // Fraction
  399.         $fractionVal sprintf
  400.             $this->properties['options']->fractionFormat,
  401.             $fractionVal $this->properties['options']->step $this->currentStep $this->max 100 100 100 $fractionVal
  402.         );
  403.         $this->valueMap['fraction'$this->stringTool->strPad
  404.             $fractionVal
  405.             iconv_strlensprintf$this->properties['options']->fractionFormat100 )'UTF-8' ),
  406.             ' ',
  407.             STR_PAD_LEFT
  408.         );
  409.  
  410.         // Act / max
  411.         $actVal sprintf(
  412.             $this->properties['options']->actFormat,
  413.             $actVal $this->currentStep * $this->properties['options']->step $this->max $this->max $actVal
  414.         );
  415.         $this->valueMap['act'$this->stringTool->strPad
  416.             $actVal
  417.             iconv_strlensprintf$this->properties['options']->actFormat$this->max )'UTF-8' ),
  418.             ' ',
  419.             STR_PAD_LEFT
  420.         );
  421.         $this->valueMap['max'sprintf$this->properties['options']->maxFormat$this->max );
  422.     }
  423.  
  424.     /**
  425.      * Insert values into bar format string.
  426.      * 
  427.      * @return void 
  428.      */
  429.     protected function insertValues()
  430.     {
  431.         $bar $this->properties['options']->formatString;
  432.         foreach $this->valueMap as $name => $val )
  433.         {
  434.             $bar str_replace"%{$name}%"$val$bar );
  435.         }
  436.         return $bar;
  437.     }
  438.  
  439.     /**
  440.      * Calculate several measures necessary to generate a bar.
  441.      * 
  442.      * @return void 
  443.      */
  444.     protected function calculateMeasures()
  445.     {
  446.         // Calc number of steps bar goes through
  447.         $this->numSteps = ( int ) round$this->max $this->properties['options']->step );
  448.         // Calculate measures
  449.         $this->measures['fixedCharSpace'iconv_strlen$this->stripEscapeSequences$this->insertValues() )'UTF-8' );
  450.         if iconv_strpos$this->properties['options']->formatString'%max%'0'UTF-8' !== false )
  451.         {
  452.             $this->measures['maxSpace'iconv_strlensprintf$this->properties['options']->maxFormat$this->max )'UTF-8' );
  453.  
  454.         }
  455.         if iconv_strpos$this->properties['options']->formatString'%act%'0'UTF-8' !== false )
  456.         {
  457.             $this->measures['actSpace'iconv_strlensprintf$this->properties['options']->actFormat$this->max )'UTF-8' );
  458.         }
  459.         if iconv_strpos$this->properties['options']->formatString'%fraction%'0'UTF-8' !== false )
  460.         {
  461.             $this->measures['fractionSpace'iconv_strlensprintf$this->properties['options']->fractionFormat100 )'UTF-8' );
  462.         }
  463.         $this->measures['barSpace'$this->properties['options']->width array_sum$this->measures );
  464.     }
  465.  
  466.     /**
  467.      * Strip all escape sequences from a string to measure it's size correctly.
  468.      * 
  469.      * @param mixed $str 
  470.      * @return void 
  471.      */
  472.     protected function stripEscapeSequences$str )
  473.     {
  474.         return preg_replace'/\033\[[0-9a-f;]*m/i'''$str  );
  475.     }
  476. }
  477. ?>
Documentation generated by phpDocumentor 1.4.3