Viewing file: Progress2.php (134.05 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
* HTML loading bar with only PHP and JS interface.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTML
* @package HTML_Progress2
* @author Laurent Laville <pear@laurent-laville.org>
* @copyright 2005-2007 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Progress2.php,v 1.33 2007/01/03 16:44:05 farell Exp $
* @link http://pear.php.net/package/HTML_Progress2
* @since File available since Release 2.0.0RC1
*/
require_once 'HTML/Common.php';
require_once 'HTML/CSS.php';
require_once 'Event/Dispatcher.php';
if (version_compare(phpversion(), '5.0.0', '<')) {
include_once 'PHP/Compat.php';
PHP_Compat::loadFunction('ob_get_clean');
PHP_Compat::loadConstant('PHP_EOL');
}
/**#@+
* Progress Bar shape types
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_BAR_HORIZONTAL', 1);
define ('HTML_PROGRESS2_BAR_VERTICAL', 2);
define ('HTML_PROGRESS2_POLYGONAL', 3);
define ('HTML_PROGRESS2_CIRCLE', 4);
/**#@-*/
/**#@+
* Progress Bar label types
*
* @var string
* @since 2.0.0
*/
define ('HTML_PROGRESS2_LABEL_TEXT', 'text');
define ('HTML_PROGRESS2_LABEL_BUTTON', 'button');
define ('HTML_PROGRESS2_LABEL_STEP', 'step');
define ('HTML_PROGRESS2_LABEL_PERCENT', 'percent');
define ('HTML_PROGRESS2_LABEL_CROSSBAR', 'crossbar');
/**#@-*/
/**
* Basic error code that indicate an unknown message
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_ERROR_UNKNOWN', -1);
/**
* Basic error code that indicate a wrong input
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_ERROR_INVALID_INPUT', -100);
/**
* Basic error code that indicate a wrong callback definition.
* Allows only function or class-method structure.
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_ERROR_INVALID_CALLBACK', -101);
/**
* Basic error code that indicate a deprecated method
* that may be removed at any time from a future version
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_ERROR_DEPRECATED', -102);
/**
* Basic error code that indicate an invalid option.
*
* @var integer
* @since 2.0.0
*/
define ('HTML_PROGRESS2_ERROR_INVALID_OPTION', -103);
/**
* HTML loading bar with only PHP and JS interface.
*
* The HTML_Progress2 class allow you to add a loading bar
* to any of your xhtml document.
* You should have a browser that accept DHTML feature.
*
* Here is a basic example:
* <code>
* <?php
* require_once 'HTML/Progress2.php';
*
* $pb = new HTML_Progress2();
* $pb->setAnimSpeed(50);
* ?>
* <html>
* <head>
* <?php
* echo $pb->getStyle(false);
* echo $pb->getScript(false);
* ?>
* </head>
* <body>
* <?php
* $pb->display();
* $pb->run();
* ?>
* </body>
* </html>
* </code>
*
* @category HTML
* @package HTML_Progress2
* @author Laurent Laville <pear@laurent-laville.org>
* @copyright 2005-2007 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version Release: 2.2.0
* @link http://pear.php.net/package/HTML_Progress2
* @since Class available since Release 2.0.0RC1
*/
class HTML_Progress2 extends HTML_Common
{
/**
* Status of the progress bar (new, show, hide).
*
* @var string
* @since 2.0.0
* @access private
*/
var $_status = 'new';
/**
* Whether the progress bar is in determinate or indeterminate mode.
* The default is false.
* An indeterminate progress bar continuously displays animation indicating
* that an operation of unknown length is occuring.
*
* @var boolean
* @since 2.0.0
* @access public
* @see setIndeterminate(), isIndeterminate()
*/
var $indeterminate;
/**
* Whether to display a border around the progress bar.
* The default is false.
*
* @var boolean
* @since 2.0.0
* @access private
* @see setBorderPainted(), isBorderPainted()
*/
var $_paintBorder;
/**
* The label that uniquely identifies this progress object.
*
* @var string
* @since 2.0.0
* @access public
* @see getIdent(), setIdent()
*/
var $ident;
/**
* Stores the event dispatcher which handles notifications
*
* @var array
* @since 2.0.0RC2
* @access protected
*/
var $dispatcher;
/**
* Count the number of observer registered.
* The Event_Dispatcher will be add on first observer registration, and
* will be removed with the last observer.
*
* @var integer
* @since 2.0.0RC2
* @access private
*/
var $_observerCount;
/**
* Delay in milisecond before each progress cells display.
* 1000 ms === sleep(1)
* <strong>usleep()</strong> function does not run on Windows platform.
*
* @var integer
* @since 2.0.0
* @access public
* @see setAnimSpeed()
*/
var $animSpeed;
/**
* Callback, either function name or array(&$object, 'method')
*
* @var mixed
* @since 2.0.0
* @access private
* @see setProgressHandler()
*/
var $_callback = false;
/**
* The progress bar's minimum value.
* The default is 0.
*
* @var integer
* @since 2.0.0
* @access public
* @see getMinimum(), setMinimum()
*/
var $minimum;
/**
* The progress bar's maximum value.
* The default is 100.
*
* @var integer
* @since 2.0.0
* @access public
* @see getMaximum(), setMaximum()
*/
var $maximum;
/**
* The progress bar's increment value.
* The default is +1.
*
* @var integer
* @since 2.0.0
* @access public
* @see getIncrement(), setIncrement()
*/
var $increment;
/**
* The progress bar's current value.
*
* @var integer
* @since 2.0.0
* @access public
* @see getValue(), setvalue(), incValue()
*/
var $value;
/**
* Whether the progress bar is horizontal, vertical, polygonal or circle.
* The default is horizontal.
*
* @var integer
* @since 2.0.0
* @access public
* @see getOrientation(), setOrientation()
*/
var $orientation;
/**
* Whether the progress bar is filled in 'natural' or 'reverse' way.
* The default fill way is 'natural'.
*
* <ul>
* <li>'way' = bar fill way
* <ul>
* <li>with Progress Bar Horizontal,
* natural way is : left to right
* <br />reverse way is : right to left
* <li>with Progress Bar Vertical,
* natural way is : down to up
* <br />reverse way is : up to down
* <li>with Progress Circle or Polygonal,
* natural way is : clockwise
* <br />reverse way is : anticlockwise
* </ul>
* </ul>
*
* @var string
* @since 2.0.0
* @access public
* @see getFillWay(), setFillWay()
*/
var $fillWay;
/**
* The cell count of the progress bar. The default is 10.
*
* @var integer
* @since 2.0.0
* @access public
* @see getCellCount(), setCellCount()
*/
var $cellCount;
/**
* The cell coordinates for a progress polygonal shape.
*
* @var array
* @since 2.0.0
* @access private
* @see getCellCoordinates(), setCellCoordinates()
*/
var $_coordinates;
/**
* The width of grid in cell-size of the polygonal shape.
*
* @var integer
* @since 2.0.0
* @access private
* @see getCellCoordinates(), setCellCoordinates()
*/
var $_xgrid;
/**
* The height of grid in cell-size of the polygonal shape.
*
* @var integer
* @since 2.0.0
* @access private
* @see getCellCoordinates(), setCellCoordinates()
*/
var $_ygrid;
/**
* Progress bar core properties
*
* <code>
* $progress = array(
* 'background-color' => '#FFFFFF', # bar background color
* 'background-image' => 'none', # bar background image
* 'background-repeat' => 'no-repeat', # bar background image repeat option
* 'background-position' => 'top left', # bar background image start position
* 'width' => 0, # bar width
* 'height' => 0, # bar height
* 'left' => 10, # position from left
* 'top' => 25, # position from top
* 'position' => 'relative' # position absolute or relative
* );
* </code>
*
* @var array
* @since 2.0.0
* @access private
* @see getProgressAttributes(), setProgressAttributes()
*/
var $_progress = array();
/**
* Progress bar frame properties
*
* <code>
* $frame = array(
* 'show' => false, # frame show (true/false)
* 'left' => 200, # position from left
* 'top' => 100, # position from top
* 'width' => 320, # width
* 'height' => 90, # height
* 'color' => '#C0C0C0', # color
* 'border-width' => 2, # border width
* 'border-style' => 'solid', # border style
* # (solid, dashed, dotted ...)
* 'border-color' => '#DFDFDF #404040 #404040 #DFDFDF' # border color (3dfx)
* );
* </code>
*
* @var array
* @since 2.0.0
* @access public
* @see getFrameAttributes(), setFrameAttributes()
*/
var $frame = array();
/**
* Progress bar border properties
*
* <code>
* $border = array(
* 'class' => 'progressBorder%s', # css class selector
* 'width' => 0, # width size in pixel
* 'style' => 'solid', # style (solid, dashed, dotted ...)
* 'color' => '#000000' # color
* );
* </code>
*
* @var array
* @since 2.0.0
* @access public
* @see getBorderAttributes(), setBorderAttributes()
*/
var $border = array();
/**
* Progress bar cells properties
*
* <code>
* $cell = array(
* 'id' => 'pcel%01s', # cell identifier mask
* 'class' => 'cell%s', # css class selector
* 'active-color' => '#006600', # active color
* 'inactive-color' => '#CCCCCC', # inactive color
* 'font-family' => 'Courier, Verdana', # font family
* 'font-size' => 8, # font size
* 'color' => '#000000', # foreground color
* 'background-color' => '#FFFFFF', # background color
* 'background-image' => 'none', # cell background image
* 'background-repeat' => 'no-repeat', # cell background image repeat option
* 'background-position' => 'top left', # cell background image start position
* 'width' => 15, # cell width
* 'height' => 20, # cell height
* 'spacing' => 2 # cell spacing
* );
* </code>
*
* @var array
* @since 2.0.0
* @access public
* @see getCellAttributes(), setCellAttributes()
*/
var $cell = array();
/**
* Progress bar labels properties
*
* <code>
* $label = array(
* 'name' => array( # label name
* 'type' => 'text', # label type
* # (text,button,step,percent,crossbar)
* 'value' => ' ', # label value
* 'left' => ($left), # label position from left
* 'top' => ($top - 16), # label position from top
* 'width' => 0, # label width
* 'height' => 0, # label height
* 'align' => 'left', # label align
* 'background-color' => 'transparent', # label background color
* 'font-family' => 'Verdana, Tahoma, Arial', # label font family
* 'font-size' => 11, # label font size
* 'font-weight' => 'normal', # label font weight
* 'color' => '#000000', # label font color
* 'class' => 'progressPercentLabel%s' # css class selector
* );
* </code>
*
* @var array
* @since 2.0.0
* @access public
* @see getLabelAttributes(), setLabelAttributes()
*/
var $label = array();
/**
* External Javascript file to override internal default code
*
* @var string
* @since 2.0.0
* @access public
* @see getScript(), setScript()
*/
var $script;
/**
* Error message callback.
* This will be used to generate the error message
* from the error code.
*
* @var false|string|array
* @since 2.0.0
* @access private
* @see _initErrorHandler()
*/
var $_callback_message = false;
/**
* Error context callback.
* This will be used to generate the error context for an error.
*
* @var false|string|array
* @since 2.0.0
* @access private
* @see _initErrorHandler()
*/
var $_callback_context = false;
/**
* Error push callback.
* The return value will be used to determine whether to allow
* an error to be pushed or logged.
*
* @var false|string|array
* @since 2.0.0
* @access private
* @see _initErrorHandler()
*/
var $_callback_push = false;
/**
* Error handler callback.
* This will handle any errors raised by this package.
*
* @var false|string|array
* @since 2.0.0
* @access private
* @see _initErrorHandler()
*/
var $_callback_errorhandler = false;
/**
* Associative array of key-value pairs
* that are used to specify any handler-specific settings.
*
* @var array
* @since 2.0.0
* @access private
* @see _initErrorHandler()
*/
var $_errorhandler_options = array();
/**
* Error stack for this package.
*
* @var array
* @since 2.0.0
* @access private
* @see raiseError()
*/
var $_errorstack = array();
/**
* Constructor (ZE1)
*
* @since 2.0.0
* @access public
*/
function HTML_Progress2($errorPrefs = array(),
$orient = HTML_PROGRESS2_BAR_HORIZONTAL, $min = 0, $max = 100,
$percentLabel = 'pct1')
{
$this->__construct($errorPrefs, $orient, $min, $max, $percentLabel);
}
/**
* Constructor (ZE2) Summary
*
* Creates a natural horizontal progress bar that displays ten separated cells
* with no border and only percent label.
* The initial and minimum values are 0, and the maximum is 100.
*
* @param array $errorPrefs (optional) Hash of params to configure error handler
* @param int $orient (optional) Orientation of progress bar
* @param int $min (optional) Minimum value of progress bar
* @param int $max (optional) Maximum value of progress bar
* @param mixed $percentLabel (optional) Progress bar percent label id.
*
* @since 2.0.0
* @access protected
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setIndeterminate(), setIdent(), setAnimSpeed(),
* setOrientation(), setMinimum(), setMaximum(), addLabel()
*/
function __construct($errorPrefs = array(),
$orient = HTML_PROGRESS2_BAR_HORIZONTAL, $min = 0, $max = 100,
$percentLabel = 'pct1')
{
$this->_initErrorHandler($errorPrefs);
$this->_observerCount = 0;
$this->value = 0;
$this->minimum = 0;
$this->maximum = 100;
$this->increment = +1;
$this->cellCount = 10;
$this->orientation = HTML_PROGRESS2_BAR_HORIZONTAL;
$this->fillWay = 'natural'; // fill bar from left to right
$this->script = null; // uses internal javascript code
$this->frame = array('show' => false);
$this->_progress = array(
'background-color' => '#FFFFFF',
'background-image' => 'none',
'background-repeat' => 'no-repeat',
'background-position' => 'top left',
'width' => 0,
'height' => 0,
'left' => 10,
'top' => 25,
'position' => 'relative'
);
$this->border = array(
'class' => 'progressBorder%s',
'width' => 0,
'style' => 'solid',
'color' => '#000000'
);
$this->cell = array(
'id' => 'pcel%01s',
'class' => 'cell%s',
'active-color' => '#006600',
'inactive-color' => '#CCCCCC',
'font-family' => 'Courier, Verdana',
'font-size' => 8,
'color' => '#000000',
'background-color' => '#FFFFFF',
'background-image' => 'none',
'background-repeat' => 'no-repeat',
'background-position' => 'top left',
'width' => 15,
'height' => 20,
'spacing' => 2
);
$this->_updateProgressSize(); // updates the new size of progress bar
if (!is_int($orient)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$orient',
'was' => gettype($orient),
'expected' => 'integer',
'paramnum' => 2));
} elseif (!is_int($min)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$min',
'was' => gettype($min),
'expected' => 'integer',
'paramnum' => 3));
} elseif (!is_int($max)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$max',
'was' => gettype($max),
'expected' => 'integer',
'paramnum' => 4));
} elseif (!is_string($percentLabel) && !is_bool($percentLabel)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$percentLabel',
'was' => gettype($percentLabel),
'expected' => 'string | boolean',
'paramnum' => 5));
}
$this->setOrientation($orient);
$this->setMinimum($min);
$this->setMaximum($max);
if ($percentLabel) {
$this->addLabel(HTML_PROGRESS2_LABEL_PERCENT, $percentLabel);
}
$this->setBorderPainted(false);
$this->setIndeterminate(false);
$this->setIdent();
$this->setAnimSpeed(0);
// to fix a potential php config problem with PHP 4.2.0 : turn 'implicit_flush' ON
ob_implicit_flush(1);
}
/**
* Returns the current API version.
*
* This function return a "PHP-standardized" version number string.
* This is useful if you would like to write programs working only on some
* versions of HTML_Progress2. See also php version_compare() function.
*
* @link http://www.php.net/manual/en/function.version-compare.php
* @return string
* @since 2.0.0
* @access public
*/
function apiVersion()
{
return '2.2.0';
}
/**
* Returns mode of the progress meter.
*
* There are two types of progress meters: determinate and undeterminate.
*
* Determinate progress meters are used when you know the length of time
* that an operation will take. The progress meter will fill up and,
* once full, the operation should be finished.
*
* Undeterminate progress meters are used when you do not know the length
* of time of an operation. The progress meter will have an animation
* such a sliding box.
*
* @return boolean
* @since 2.0.0
* @access public
* @see setIndeterminate()
*/
function isIndeterminate()
{
return $this->indeterminate;
}
/**
* Sets the mode of progress meter.
*
* Default progress meters are in determinate mode ($continuous = TRUE), but
* can be switched anytime in indeterminate mode ($continuous = FALSE).
*
* @param boolean $continuous whether countinuously displays animation
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see isIndeterminate()
*/
function setIndeterminate($continuous)
{
if (!is_bool($continuous)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$continuous',
'was' => gettype($continuous),
'expected' => 'boolean',
'paramnum' => 1));
}
$this->indeterminate = $continuous;
}
/**
* Determines whether the progress bar border is painted or not.
*
* By default, each progress bar (horizontal, vertical) has no border.
* This function gave ability to know if you've already set a border
* (return TRUE), or not (return FALSE).
*
* @return boolean
* @since 2.0.0
* @access public
* @see setBorderPainted()
*/
function isBorderPainted()
{
return $this->_paintBorder;
}
/**
* Decides to paint or not a border to the progress bar.
*
* This function gave ability to set ($paint = TRUE) or remove ($paint = FALSE)
* a border to the current progress bar.
*
* @param boolean $paint whether the progress bar should paint its border
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see isBorderPainted()
*/
function setBorderPainted($paint)
{
if (!is_bool($paint)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$paint',
'was' => gettype($paint),
'expected' => 'boolean',
'paramnum' => 1));
}
$this->_paintBorder = $paint;
}
/**
* Returns the progress meter minimum value.
*
* Get the minimum value at which the progress meter will start.
* The default value is zero and can't be negative.
*
* @return integer
* @since 2.0.0
* @access public
* @see setMinimum()
*/
function getMinimum()
{
return $this->minimum;
}
/**
* Sets the progress meter minimum value.
*
* Set the minimum value at which the progress meter will start.
* The default value is zero and can't be negative.
* If the new minimum is different than previous value, all listeners
* are notified.
*
* @param integer $min progress meter's minimal value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getMinimum()
*/
function setMinimum($min)
{
if (!is_int($min)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$min',
'was' => gettype($min),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($min < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$min',
'was' => $min,
'expected' => 'positive',
'paramnum' => 1));
} elseif ($min > $this->maximum) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$min',
'was' => $min,
'expected' => 'less than $max = '.$this->maximum,
'paramnum' => 1));
}
$oldVal = $this->minimum;
$this->minimum = $min;
/* set current value to minimum if less than minimum */
if ($this->value < $min) {
$this->setValue($min);
}
if ($oldVal != $min) {
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $min));
}
}
/**
* Returns the progress meter maximum value.
*
* Get the maximum value at which the progress meter will stop.
* The default value is 100 and can't be less than minimum.
*
* @return integer
* @since 2.0.0
* @access public
* @see setMaximum()
*/
function getMaximum()
{
return $this->maximum;
}
/**
* Sets the progress meter maximum value.
*
* Set the maximum value at which the progress meter will stop.
* The default value is 100 and can't be less than minimum.
* If the new maximum is different than previous value, all listeners
* are notified.
*
* @param integer $max progress meter's maximal value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getMaximum()
*/
function setMaximum($max)
{
if (!is_int($max)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$max',
'was' => gettype($max),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($max < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$max',
'was' => $max,
'expected' => 'positive',
'paramnum' => 1));
} elseif ($max < $this->minimum) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$max',
'was' => $max,
'expected' => 'greater than $min = '.$this->minimum,
'paramnum' => 1));
}
$oldVal = $this->maximum;
$this->maximum = $max;
/* set current value to maximum if greater to maximum */
if ($this->value > $max) {
$this->setValue($max);
}
if ($oldVal != $max) {
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $max));
}
}
/**
* Returns the progress meter increment value.
*
* Get step of progress property of a progress meter.
* The default value is +1.
*
* @return integer
* @since 2.0.0
* @access public
* @see setIncrement()
*/
function getIncrement()
{
return $this->increment;
}
/**
* Sets the progress meter increment value.
*
* Defines step of progress property of a progress meter.
* Allows to ajust default value (+1).
*
* @param integer $inc progress meter's increment value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getIncrement()
*/
function setIncrement($inc)
{
if (!is_int($inc)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$inc',
'was' => gettype($inc),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($inc == 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$inc',
'was' => $inc,
'expected' => 'not equal zero',
'paramnum' => 1));
}
$this->increment = $inc;
}
/**
* Returns the progress meter current value.
*
* Get the current value of the progress meter that is always between
* the minimum and maximum values, inclusive.
* The default value is equal to minimum.
*
* @return integer
* @since 2.0.0
* @access public
* @see setValue(), incValue()
*/
function getValue()
{
return $this->value;
}
/**
* Sets the progress meter current value.
*
* Set the current value of the progress meter that is always between
* the minimum and maximum values, inclusive. If the new value is different
* from previous, then all listeners are notified.
*
* @param integer $val progress meter's current value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getValue(), incValue()
*/
function setValue($val)
{
if (!is_int($val)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$val',
'was' => gettype($val),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($val < $this->minimum) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$val',
'was' => $val,
'expected' => 'greater than $min = '.$this->minimum,
'paramnum' => 1));
} elseif ($val > $this->maximum) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$val',
'was' => $val,
'expected' => 'less than $max = '.$this->maximum,
'paramnum' => 1));
}
$oldVal = $this->value;
$this->value = $val;
if ($oldVal != $val) {
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $val));
}
}
/**
* Updates the internal progress meter current value.
*
* The new current value is equal to previous value increase by
* increment value. All listeners are notified.
* See also moveNext() method if you want a refresh display too.
*
* @return void
* @since 2.0.0
* @access public
* @see getValue(), setValue(), moveNext()
*/
function incValue()
{
$newVal = $this->value + $this->increment;
$newVal = min($this->maximum, $newVal);
$this->value = $newVal;
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $newVal));
}
/**
* Changes new value of the progress meter by step increase.
*
* Move current value to the next step of the progress meter
* defined by its increment. If result value is different than previous,
* then all listeners are notified.
* Caution: a step is always between 1 and (maximum / taskcount) rounded fractions up.
*
* @param integer $step new step value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see moveNext()
*/
function moveStep($step)
{
if (!is_int($step)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$step',
'was' => gettype($step),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($step < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$step',
'was' => $step,
'expected' => 'greater than zero',
'paramnum' => 1));
} elseif ($step > intval(ceil($this->maximum / $this->increment))) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$step',
'was' => $step,
'expected' => 'less than '. intval(ceil($this->maximum / $this->increment)),
'paramnum' => 1));
}
$oldVal = $this->value;
$this->value = $step * $this->increment;
$this->value = min($this->maximum, $this->value);
if ($oldVal != $this->value) {
$this->_refreshDisplay($this->value);
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $step));
}
}
/**
* Changes new value of the progress meter by increment increase.
*
* Move current value to the next value of the progress meter
* defined by its increment. If result value is different than previous,
* then all listeners are notified.
*
* @return void
* @since 2.0.0
* @access public
* @see moveStep()
*/
function moveNext()
{
$oldVal = $this->value;
$this->value = $oldVal + $this->increment;
$this->value = min($this->maximum, $this->value);
if ($oldVal != $this->value) {
$this->_refreshDisplay($this->value);
$this->_postNotification('onChange', array('handler' => __FUNCTION__, 'value' => $this->value));
}
}
/**
* Returns the percent complete of the progress meter.
*
* Note that this number is between 0.00 and 1.00 when $float = true.
* And this number is between 0 and 100 when $float = false.
*
* @param boolean $float (optional) float or integer format
*
* @return float
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getValue(), getMaximum()
*/
function getPercentComplete($float = true)
{
if (!is_bool($float)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$float',
'was' => gettype($float),
'expected' => 'boolean',
'paramnum' => 1));
}
$min = $this->minimum;
$max = $this->maximum;
$val = $this->value;
$percent = round((($val - $min) / ($max - $min)), 4);
if ($float) {
return $percent;
} else {
return intval($percent * 100);
}
}
/**
* Returns orientation of the progress bar.
*
* There are only two distinct orientations for a progress bar:
* horizontal and vertical, identified by two constants:
* HTML_PROGRESS2_BAR_HORIZONTAL and HTML_PROGRESS2_BAR_VERTICAL.
* While circle and other polygonal progress meter are identified by
* two other constants: HTML_PROGRESS2_CIRCLE and HTML_PROGRESS2_POLYGONAL.
* The default orientation is horizontal.
*
* @return integer
* @since 2.0.0
* @access public
* @see setOrientation()
*/
function getOrientation()
{
return $this->orientation;
}
/**
* Sets orientation of the progress bar.
*
* There are only two distinct orientations for a progress bar:
* horizontal and vertical, identified by two constants:
* HTML_PROGRESS2_BAR_HORIZONTAL and HTML_PROGRESS2_BAR_VERTICAL.
* While circle and other polygonal progress meter are identified by
* two other constants: HTML_PROGRESS2_CIRCLE and HTML_PROGRESS2_POLYGONAL.
* The default orientation is horizontal.
*
* @param integer $orient Orientation (horizontal or vertical)
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getOrientation()
*/
function setOrientation($orient)
{
if (!is_int($orient)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$orient',
'was' => gettype($orient),
'expected' => 'integer',
'paramnum' => 1));
} elseif (($orient != HTML_PROGRESS2_BAR_HORIZONTAL) &&
($orient != HTML_PROGRESS2_BAR_VERTICAL) &&
($orient != HTML_PROGRESS2_POLYGONAL) &&
($orient != HTML_PROGRESS2_CIRCLE)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$orient',
'was' => $orient,
'expected' => HTML_PROGRESS2_BAR_HORIZONTAL.' | '.
HTML_PROGRESS2_BAR_VERTICAL.' | '.
HTML_PROGRESS2_POLYGONAL.' | '.
HTML_PROGRESS2_CIRCLE,
'paramnum' => 1));
}
$previous = $this->orientation; // gets previous orientation
$this->orientation = $orient; // sets the new orientation
if ($previous != $orient) {
// if orientation has changed, we need to swap cell width and height
$w = $this->cell['width'];
$h = $this->cell['height'];
$this->cell['width'] = $h;
$this->cell['height'] = $w;
$this->_updateProgressSize(); // updates the new size of progress bar
}
}
/**
* Returns fill option of the progress meter.
*
* Get 'natural' or 'reverse', depending of the fill way of progress meter.
* For horizontal progress bar, natural way is from left to right, and reverse
* way is from right to left.
* For vertical progress bar, natural way is from down to up, and reverse
* way is from up to down.
* The default fill way is 'natural'.
*
* @return string
* @since 2.0.0
* @access public
* @see setFillWay()
*/
function getFillWay()
{
return $this->fillWay;
}
/**
* Sets fill option of the progress meter.
*
* Sets the progress meter fill option: must be 'natural' or 'reverse'.
* The default fill way is 'natural'.
*
* @param string $way fill direction (natural or reverse)
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getFillWay()
*/
function setFillWay($way)
{
if (!is_string($way)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$way',
'was' => gettype($way),
'expected' => 'string',
'paramnum' => 1));
} elseif (($way != 'natural') && ($way != 'reverse')) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$way',
'was' => $way,
'expected' => 'natural | reverse',
'paramnum' => 1));
}
$this->fillWay = $way;
}
/**
* Returns count of cell in the progress meter.
*
* Get the number of cell defined to a progress meter. It must be positive.
* The default value is 10.
*
* @return integer
* @since 2.0.0
* @access public
* @see setCellCount()
*/
function getCellCount()
{
return $this->cellCount;
}
/**
* Sets count of cell in the progress meter.
*
* Defines the number of cell to a progress meter. It must be positive.
* The default value is 10.
*
* @param integer $cells Cell count on progress meter
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getCellCount()
*/
function setCellCount($cells)
{
if (!is_int($cells)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$cells',
'was' => gettype($cells),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($cells < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$cells',
'was' => $cells,
'expected' => 'greater or equal zero',
'paramnum' => 1));
}
$this->cellCount = $cells;
$this->_updateProgressSize(); // updates the new size of progress bar
}
/**
* Returns cell attributes values.
*
* Get all cell attributes in a associative array with key-value couple
* (by default). Get the attributes as string is also possible.
*
* @param bool $asString (optional) whether to return the attributes as string
*
* @return mixed
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setCellAttributes()
*/
function getCellAttributes($asString = false)
{
if (!is_bool($asString)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$asString',
'was' => gettype($asString),
'expected' => 'boolean',
'paramnum' => 1));
}
$attr = $this->cell;
if ($asString) {
return $this->_getAttrString($attr);
} else {
return $attr;
}
}
/**
* Sets cell attributes values.
*
* Sets cell attributes for all cells (default) or a specific an existing cell.
*
* Defaults are:
* <ul>
* <li>id = pcel%01s
* <li>class = cell
* <li>spacing = 2
* <li>active-color = #006600
* <li>inactive-color = #CCCCCC
* <li>font-family = Courier, Verdana
* <li>font-size = lowest value from cell width, cell height, and font size
* <li>color = #000000
* <li>background-color = #FFFFFF
* <li>background-image = none
* <li>background-repeat = no-repeat
* <li>background-position = top left
* <li>Horizontal Bar :
* <ul>
* <li>width = 15
* <li>height = 20
* </ul>
* <li>Vertical Bar :
* <ul>
* <li>width = 20
* <li>height = 15
* </ul>
* </ul>
*
* @param mixed $attributes Associative array or string of HTML tag attributes
* @param int $cell (optional) Cell index
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getCellAttributes()
*/
function setCellAttributes($attributes, $cell = null)
{
if (!is_null($cell)) {
if (!is_int($cell)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$cell',
'was' => gettype($cell),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($cell < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$cell',
'was' => $cell,
'expected' => 'positive',
'paramnum' => 1));
} elseif ($cell > $this->cellCount) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$cell',
'was' => $cell,
'expected' => 'less or equal '.$this->cellCount,
'paramnum' => 1));
}
$this->_updateAttrArray($this->cell[$cell], $this->_parseAttributes($attributes));
} else {
$this->_updateAttrArray($this->cell, $this->_parseAttributes($attributes));
}
$font_size = $this->cell['font-size'];
$cell_width = $this->cell['width'];
$cell_height = $this->cell['height'];
$margin = ($this->orientation == HTML_PROGRESS2_BAR_HORIZONTAL) ? 0 : 3;
$font_size = min(min($cell_width, $cell_height) - $margin, $font_size);
$this->cell['font-size'] = $font_size;
$this->_updateProgressSize(); // updates the new size of progress bar
}
/**
* Returns coordinates of each cell for a polygonal progress meter.
*
* Get array of all cell coordinates (x,y) that define a polygonal
* progress meter.
* For example, a 3x3 square as: (0,0) for top left corner,
* (2,0) for top right corner, (2,2) for bottom right corner, and
* (0,2) for bottom left corner.
*
* @return array
* @since 2.0.0
* @access public
* @see setCellCoordinates()
*/
function getCellCoordinates()
{
return isset($this->_coordinates) ? $this->_coordinates : array();
}
/**
* Sets coordinates of each cell for a polygonal progress meter.
*
* A polygonal progress meter is defined by its size (width, height) and its
* cells coordinates (array of couple x,y screen coordinates).
*
* @param integer $xgrid The grid width in cell size
* @param integer $ygrid The grid height in cell size
* @param array $coord (optional) Coordinates (x,y) in the grid, of each cell
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getCellCoordinates()
*/
function setCellCoordinates($xgrid, $ygrid, $coord = array())
{
if (!is_int($xgrid)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$xgrid',
'was' => gettype($xgrid),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($xgrid < 3) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$xgrid',
'was' => $xgrid,
'expected' => 'greater than 2',
'paramnum' => 1));
} elseif (!is_int($ygrid)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$ygrid',
'was' => gettype($ygrid),
'expected' => 'integer',
'paramnum' => 2));
} elseif ($ygrid < 3) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$ygrid',
'was' => $ygrid,
'expected' => 'greater than 2',
'paramnum' => 2));
} elseif (!is_array($coord)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$coord',
'was' => gettype($coord),
'expected' => 'array',
'paramnum' => 3));
}
if (count($coord) == 0) {
// Computes all coordinates of a standard polygon (square or rectangle)
$coord = $this->_computeCoordinates($xgrid, $ygrid);
} else {
foreach ($coord as $id => $pos) {
if (!is_array($pos)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$coord[,$pos]',
'was' => gettype($pos),
'expected' => 'array',
'paramnum' => 3));
}
if ($pos[0] >= $ygrid) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$pos[0]',
'was' => $pos[0],
'expected' => 'coordinate less than grid height',
'paramnum' => 2));
}
if ($pos[1] >= $xgrid) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$pos[1]',
'was' => $pos[1],
'expected' => 'coordinate less than grid width',
'paramnum' => 1));
}
}
}
$this->_coordinates = $coord;
$this->_xgrid = $xgrid;
$this->_ygrid = $ygrid;
// auto-compute cell count
$this->cellCount = count($coord);
$this->_updateProgressSize(); // updates the new size of progress bar
}
/**
* Returns progress bar's border attributes values.
*
* Get all border attributes in a associative array with key-value couple
* (by default). Get the attributes as string is also possible.
*
* @param bool $asString (optional) whether to return the attributes as string
*
* @return mixed
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setBorderAttributes()
*/
function getBorderAttributes($asString = false)
{
if (!is_bool($asString)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$asString',
'was' => gettype($asString),
'expected' => 'boolean',
'paramnum' => 1));
}
$attr = $this->border;
if ($asString) {
return $this->_getAttrString($attr);
} else {
return $attr;
}
}
/**
* Sets the progress bar's border attributes.
*
* Defines all border attributes (color, size, ...) a progress bar
* (only horizontal or vertical) can handle.
*
* Defaults are:
* <ul>
* <li>class = progressBorder%s
* <li>width = 0
* <li>style = solid
* <li>color = #000000
* </ul>
*
* @param mixed $attributes Associative array or string of HTML tag attributes
*
* @return void
* @since 2.0.0
* @access public
* @see getBorderAttributes()
*/
function setBorderAttributes($attributes)
{
$this->_updateAttrArray($this->border, $this->_parseAttributes($attributes));
$this->_updateProgressSize(); // updates the new size of progress bar
}
/**
* Returns frame attributes values.
*
* Get all frame attributes in a associative array with key-value couple
* (by default). Get the attributes as string is also possible.
*
* @param bool $asString (optional) whether to return the attributes as string
*
* @return mixed
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setFrameAttributes()
*/
function getFrameAttributes($asString = false)
{
if (!is_bool($asString)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$asString',
'was' => gettype($asString),
'expected' => 'boolean',
'paramnum' => 1));
}
$attr = $this->frame;
if ($asString) {
return $this->_getAttrString($attr);
} else {
return $attr;
}
}
/**
* Sets the progress meter frame attributes.
*
* Allows to build a customisable frame (color, size) around the progress meter.
*
* Defaults are:
* <ul>
* <li>show = true
* <li>left = 200
* <li>top = 100
* <li>width = 320
* <li>height = 90
* <li>color = #C0C0C0
* <li>border-width = 2
* <li>border-style = solid
* <li>border-color = #DFDFDF #404040 #404040 #DFDFDF
* </ul>
*
* @param null|array $attributes (optional) hash of style parameters
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT,
* HTML_PROGRESS2_ERROR_INVALID_OPTION
*/
function setFrameAttributes($attributes = array())
{
if (!is_null($attributes) && !is_array($attributes)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$attributes',
'was' => gettype($attributes),
'expected' => 'array',
'paramnum' => 1));
}
$default = array(
'show' => true,
'left' => 200,
'top' => 100,
'width' => 320,
'height' => 90,
'color' => '#C0C0C0',
'border-width' => 2,
'border-style' => 'solid',
'border-color' => '#DFDFDF #404040 #404040 #DFDFDF'
);
$allowed_options = array_keys($default);
$options = array_merge($default, $attributes);
foreach ($options as $prop => $val) {
if (in_array($prop, $allowed_options)) {
$this->frame[$prop] = $val;
} else {
$this->raiseError(HTML_PROGRESS2_ERROR_INVALID_OPTION, 'warning',
array('element' => 'frame', 'prop' => $prop)
);
}
}
}
/**
* Returns attributes values of an existing label.
*
* Get all attributes of an existing label identified by $name argument.
* This identifier must be the same as the one given to addLabel() method.
* Return attributes values in a associative array with key-value couple
* (by default). Get the attributes as string is also possible.
*
* @param string $name progress label id.
* @param bool $asString (optional) whether to return the attributes as string
*
* @return mixed
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setLabelAttributes()
*/
function getLabelAttributes($name, $asString = false)
{
if (!isset($this->label[$name])) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$name',
'was' => 'undefined',
'expected' => "label '$name' exists",
'paramnum' => 1));
} elseif (!is_bool($asString)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$asString',
'was' => gettype($asString),
'expected' => 'boolean',
'paramnum' => 2));
}
$attr = $this->label[$name];
if ($asString) {
return $this->_getAttrString($attr);
} else {
return $attr;
}
}
/**
* Sets attributes values of an existing label.
*
* Defines attributes (font, color, size, alignement ...) of an existing label.
* Whether an attribute is not specified, previous or default value
* is used instead.
*
* Defaults are:
* <ul>
* <li>class = progressPercentLabel%s
* <li>width = 50
* <li>height = 0
* <li>font-size = 11
* <li>font-family = Verdana, Tahoma, Arial
* <li>font-weight = normal
* <li>color = #000000
* <li>background-color = transparent
* <li>align = right
* <li>valign = right
* </ul>
*
* @param string $name progress label id.
* @param mixed $attributes Associative array or string of HTML tag attributes
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getLabelAttributes(), addLabel()
*/
function setLabelAttributes($name, $attributes)
{
if (!isset($this->label[$name])) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$name',
'was' => "label '$name' undefined",
'expected' => 'label already exists',
'paramnum' => 1));
}
$this->_updateAttrArray($this->label[$name], $this->_parseAttributes($attributes));
if ($this->label[$name]['type'] == HTML_PROGRESS2_LABEL_TEXT) {
if ($this->_status != 'new') {
$this->_changeLabelText($name, $this->label[$name]['value']);
}
}
}
/**
* Add a new label to the progress meter.
*
* Defines a new label identifier choosen between five categories:
* <ul>
* <li>HTML_PROGRESS2_LABEL_TEXT constant if you want a simple text zone
* <li>HTML_PROGRESS2_LABEL_BUTTON constant if you want a form button
* <li>HTML_PROGRESS2_LABEL_STEP constant if you want a step resume progress
* <li>HTML_PROGRESS2_LABEL_PERCENT constant if you want current progress value
* <li>HTML_PROGRESS2_LABEL_CROSSBAR constant if you want a little javascript animation
* </ul>
*
* @param string $type Label type (text,button,step,percent,crossbar)
* @param string $name Label name
* @param string $value (optional) default label value
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setLabelAttributes(), removeLabel()
*/
function addLabel($type, $name, $value = ' ')
{
if (($type != HTML_PROGRESS2_LABEL_TEXT) &&
($type != HTML_PROGRESS2_LABEL_BUTTON) &&
($type != HTML_PROGRESS2_LABEL_STEP) &&
($type != HTML_PROGRESS2_LABEL_PERCENT) &&
($type != HTML_PROGRESS2_LABEL_CROSSBAR)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$type',
'was' => $type,
'expected' => 'HTML_PROGRESS2_LABEL_* constant value',
'paramnum' => 1));
} elseif (!is_string($name)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$name',
'was' => gettype($name),
'expected' => 'string',
'paramnum' => 2));
} elseif (isset($this->label[$name])) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$name',
'was' => 'label already exists',
'expected' => "label '$name' undefined",
'paramnum' => 2));
} elseif (!is_string($value)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$value',
'was' => gettype($value),
'expected' => 'string',
'paramnum' => 3));
}
switch($type) {
case HTML_PROGRESS2_LABEL_TEXT:
$this->label[$name] = array(
'type' => $type,
'value' => $value,
'left' => 5,
'top' => 5,
'width' => 0,
'height' => 0,
'align' => 'left',
'valign' => 'top',
'background-color' => 'transparent',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'class' => 'progressTextLabel%s'
);
break;
case HTML_PROGRESS2_LABEL_BUTTON:
$this->label[$name] = array(
'type' => $type,
'value' => $value,
'action' => '',
'target' => 'self',
'left' => 0,
'top' => 5,
'width' => 0,
'height' => 0,
'align' => 'center',
'valign' => 'bottom',
'background-color' => 'transparent',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'class' => 'progressButtonLabel%s'
);
break;
case HTML_PROGRESS2_LABEL_STEP:
$this->label[$name] = array(
'type' => $type,
'value' => $value,
'left' => 5,
'top' => 5,
'width' => 165,
'height' => 0,
'align' => 'right',
'valign' => 'top',
'background-color' => 'transparent',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'class' => 'progressStepLabel%s'
);
break;
case HTML_PROGRESS2_LABEL_PERCENT:
$this->label[$name] = array(
'type' => $type,
'value' => $value,
'left' => 5,
'top' => 5,
'width' => 50,
'height' => 0,
'align' => 'right',
'valign' => 'right',
'background-color' => 'transparent',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'class' => 'progressPercentLabel%s'
);
break;
case HTML_PROGRESS2_LABEL_CROSSBAR:
$this->label[$name] = array(
'type' => $type,
'value' => $value,
'left' => 5,
'top' => 5,
'width' => 20,
'height' => 0,
'align' => 'center',
'valign' => 'top',
'background-color' => 'transparent',
'font-size' => 11,
'font-family' => 'Verdana, Tahoma, Arial',
'font-weight' => 'normal',
'color' => '#000000',
'class' => 'progressCrossbarLabel%s'
);
break;
}
}
/**
* Removes a label to the progress meter.
*
* The label identifier must exists or it cannot be remove. This is the same
* identifier as the one given to addLabel() method.
*
* @param string $name Label name
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see addLabel()
*/
function removeLabel($name)
{
if (!is_string($name)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$name',
'was' => gettype($name),
'expected' => 'string',
'paramnum' => 1));
} elseif (!isset($this->label[$name])) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'notice',
array('var' => '$name',
'was' => 'label does not exists',
'expected' => "label '$name' defined",
'paramnum' => 1));
}
unset($this->label[$name]);
}
/**
* Returns the progress background attributes values.
*
* Get all background attributes in a associative array with key-value couple
* (by default). Get the attributes as string is also possible.
*
* @param bool $asString (optional) whether to return the attributes as string
*
* @return mixed
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setProgressAttributes()
*/
function getProgressAttributes($asString = false)
{
if (!is_bool($asString)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$asString',
'was' => gettype($asString),
'expected' => 'boolean',
'paramnum' => 1));
}
$attr = $this->_progress;
if ($asString) {
return $this->_getAttrString($attr);
} else {
return $attr;
}
}
/**
* Sets the progress background attributes values.
*
* Background attributes are color and size, with default values:
* <ul>
* <li>background-color = #FFFFFF
* <li>background-image = none
* <li>background-repeat = no-repeat
* <li>background-position = top left
* <li>Horizontal Bar :
* <ul>
* <li>width = (cell_count * (cell_width + cell_spacing)) + cell_spacing
* <li>height = cell_height + (2 * cell_spacing)
* </ul>
* <li>Vertical Bar :
* <ul>
* <li>width = cell_width + (2 * cell_spacing)
* <li>height = (cell_count * (cell_height + cell_spacing)) + cell_spacing
* </ul>
* </ul>
*
* @param mixed $attributes Associative array or string of HTML tag attributes
*
* @return void
* @since 2.0.0
* @access public
* @see getProgressAttributes()
*/
function setProgressAttributes($attributes)
{
$this->_updateAttrArray($this->_progress, $this->_parseAttributes($attributes));
}
/**
* Returns javascript progress meter handler.
*
* Get the javascript URL or inline code that will handle the progress meter
* refresh.
*
* @param boolean $raw (optional) html output with script tags or just raw data
*
* @return string
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setScript()
*/
function getScript($raw = true)
{
if (!is_bool($raw)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$raw',
'was' => gettype($raw),
'expected' => 'boolean',
'paramnum' => 1));
}
if (!is_null($this->script)) {
if ($raw) {
$js = $this->script; // URL to the linked Progress JavaScript
} else {
$js = '<script type="text/javascript" src="' . $this->script
. '"></script>' . PHP_EOL;
}
return $js;
}
$js = <<< JS
function setProgress(pIdent, pValue, pDeterminate, pCellCount)
{
if (pValue == pDeterminate) {
for (var i = 0; i < pCellCount; i++) {
showCell(i, pIdent, 'I');
}
}
if ((pDeterminate > 0) && (pValue > 0)) {
var i = (pValue - 1) % pCellCount;
showCell(i, pIdent, 'A');
} else {
for (var i = pValue - 1; i >= 0; i--) {
showCell(i, pIdent, 'A');
}
}
}
function showCell(pCell, pIdent, pVisibility)
{
var name = '%progressCell%' + pCell + pIdent;
var cellElement = document.getElementById(name);
cellElement.className = '%cellCN%' + pIdent + pVisibility;
}
function hideProgress(pIdent)
{
var name = 'tfrm' + pIdent;
var tfrm = document.getElementById(name);
tfrm.style.visibility = "hidden";
}
function setLabelText(pIdent, pName, pText)
{
var name = 'plbl' + pName + pIdent;
document.getElementById(name).firstChild.nodeValue = pText;
}
function setElementStyle(pPrefix, pName, pIdent, pStyles)
{
var name = pPrefix + pName + pIdent;
var styles = pStyles.split(';');
styles.pop();
for (var i = 0; i < styles.length; i++) {
var s = styles[i].split(':');
var c = 'document.getElementById(name).style.' + s[0] + '="' + s[1] + '"';
eval(c);
}
}
function setRotaryCross(pIdent, pName)
{
var name = 'plbl' + pName + pIdent;
var cross = document.getElementById(name).firstChild.nodeValue;
switch(cross) {
case "--": cross = "\\\\"; break;
case "\\\\": cross = "|"; break;
case "|": cross = "/"; break;
default: cross = "--"; break;
}
document.getElementById(name).firstChild.nodeValue = cross;
}
JS;
$cellAttr = $this->getCellAttributes();
$attr = array(
trim(sprintf($cellAttr['id'], ' ')),
trim(sprintf($cellAttr['class'], ' '))
);
$js = str_replace(array('%progressCell%', '%cellCN%'), $attr, $js);
if ($raw !== true) {
$js = '<script type="text/javascript">' . PHP_EOL
. '//<![CDATA[' . $js . '//]]>' . PHP_EOL
. '</script>' . PHP_EOL;
}
return $js;
}
/**
* Sets the javascript progress meter handler.
*
* Defines the javascript source (URL or inline code) that will handle
* the progress meter refresh.
*
* @param string $url URL to the linked Progress JavaScript
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getScript()
*/
function setScript($url)
{
if (!is_null($url)) {
if (!is_string($url)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$url',
'was' => gettype($url),
'expected' => 'string',
'paramnum' => 1));
} elseif (!is_file($url) || $url == '.' || $url == '..') {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$url',
'was' => $url.' file does not exists',
'expected' => 'javascript file exists',
'paramnum' => 1));
}
}
/*
- since version 0.5.0,
- default javascript code comes from getScript() method
- but may be overrided by external file.
*/
$this->script = $url;
}
/**
* Draw all circle segment pictures.
*
* This function build/prepare all circle segment PNG pictures that will be
* send to browser output. Requires PEAR::Image_Color and PHP:gd extension.
*
* @param string $dir (optional) Directory where pictures should be created
* @param string $fileMask (optional) sprintf format for pictures filename
*
* @return array
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see setCellAttributes()
*/
function drawCircleSegments($dir = '.', $fileMask = 'c%s.png')
{
if (!is_dir($dir)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$dir',
'was' => $dir,
'expected' => 'directory exists',
'paramnum' => 1));
}
require_once 'Image/Color.php';
$cellAttr = $this->getCellAttributes();
$w = $cellAttr['width'];
$h = $cellAttr['height'];
$s = $cellAttr['spacing'];
$c = intval(360 / $this->cellCount);
if (fmod($w,2) == 0) {
$cx = floor($w / 2) - 0.5;
} else {
$cx = floor($w / 2);
}
if (fmod($h,2) == 0) {
$cy = floor($h / 2) - 0.5;
} else {
$cy = floor($h / 2);
}
$image = imagecreate($w, $h);
$bg = Image_Color::allocateColor($image, $cellAttr['background-color']);
$colorA = Image_Color::allocateColor($image, $cellAttr['active-color']);
$colorI = Image_Color::allocateColor($image, $cellAttr['inactive-color']);
imagefilledarc($image, $cx, $cy, $w, $h, 0, 360, $colorI, IMG_ARC_EDGED);
$filename = $dir . DIRECTORY_SEPARATOR . sprintf($fileMask,0);
imagepng($image, $filename);
$this->setCellAttributes(array('background-image' => $filename),0);
for ($i = 0; $i < $this->cellCount; $i++) {
if ($this->fillWay == 'natural') {
$sA = $i*$c;
$eA = ($i+1)*$c;
$sI = ($i+1)*$c;
$eI = 360;
} else {
$sA = 360-(($i+1)*$c);
$eA = 360-($i*$c);
$sI = 0;
$eI = 360-(($i+1)*$c);
}
if ($s > 0) {
imagefilledarc($image, $cx, $cy, $w, $h, 0, $sA, $colorI, IMG_ARC_EDGED);
}
imagefilledarc($image, $cx, $cy, $w, $h, $sA, $eA, $colorA, IMG_ARC_EDGED);
imagefilledarc($image, $cx, $cy, $w, $h, $sI, $eI, $colorI, IMG_ARC_EDGED);
$filename = $dir . DIRECTORY_SEPARATOR . sprintf($fileMask,$i+1);
imagepng($image, $filename);
$this->setCellAttributes(array('background-image' => $filename),$i+1);
}
imagedestroy($image);
}
/**
* Returns delay execution of the progress meter.
*
* Given a delay in process of the progress meter is only necessary
* if you need demonstration or also smooth animation.
* The default value is zero (no delay).
*
* @return integer
* @since 2.0.0
* @access public
* @see setAnimSpeed()
*/
function getAnimSpeed()
{
return $this->animSpeed;
}
/**
* Sets delay execution of the progress meter.
*
* The delay (in milisecond) cannot exceed 1000 (1 second), that is enough
* to smooth an animation. User process should slow down animation and in most
* case the default value (zero) will be efficient.
*
* @param integer $delay Delay in milisecond.
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see getAnimSpeed()
*/
function setAnimSpeed($delay)
{
if (!is_int($delay)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$delay',
'was' => gettype($delay),
'expected' => 'integer',
'paramnum' => 1));
} elseif ($delay < 0) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$delay',
'was' => $delay,
'expected' => 'greater than zero',
'paramnum' => 1));
} elseif ($delay > 1000) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$delay',
'was' => $delay,
'expected' => 'less or equal 1000',
'paramnum' => 1));
}
$this->animSpeed = $delay;
}
/**
* Returns the cascading style sheet (CSS).
*
* Get the CSS required to display the progress meter in a HTML document.
*
* @param boolean $raw (optional) html output with script tags or just raw data
*
* @return string
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
*/
function getStyle($raw = true)
{
if (!is_bool($raw)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$raw',
'was' => gettype($raw),
'expected' => 'boolean',
'paramnum' => 1));
}
$progressAttr = $this->getProgressAttributes();
$borderAttr = $this->getBorderAttributes();
$cellAttr = $this->getCellAttributes();
$css = new HTML_CSS();
$borderCls = '.' . sprintf($borderAttr['class'], $this->ident);
$css->setStyle($borderCls, 'width', $progressAttr['width'].'px');
$css->setStyle($borderCls, 'height', $progressAttr['height'].'px');
if ($this->isBorderPainted()) {
$css->setStyle($borderCls, 'border-width', $borderAttr['width'].'px');
$css->setStyle($borderCls, 'border-style', $borderAttr['style']);
$css->setStyle($borderCls, 'border-color', $borderAttr['color']);
}
if ($progressAttr['background-image'] !== 'none') {
$css->setStyle($borderCls, 'background-image', 'url("'. $progressAttr['background-image'] .'")');
$css->setStyle($borderCls, 'background-repeat', $progressAttr['background-repeat']);
$css->setStyle($borderCls, 'background-position', $progressAttr['background-position']);
}
if ($this->cellCount > 0) {
$css->setStyle($borderCls, 'background-color', $progressAttr['background-color']);
} else {
$css->setStyle($borderCls, 'background-color', $cellAttr['inactive-color']);
}
foreach($this->label as $name => $data) {
$style = '.' . sprintf($data['class'], $name . $this->ident);
if ($data['width'] > 0) {
$css->setStyle($style, 'width', $data['width'].'px');
}
if ($data['height'] > 0) {
$css->setStyle($style, 'height', $data['height'].'px');
}
$css->setStyle($style, 'text-align', $data['align']);
$css->setStyle($style, 'background-color', $data['background-color']);
$css->setStyle($style, 'font-size', $data['font-size'].'px');
$css->setStyle($style, 'font-family', $data['font-family']);
$css->setStyle($style, 'font-weight', $data['font-weight']);
$css->setStyle($style, 'color', $data['color']);
}
$cellClsI = '.' . sprintf($cellAttr['class'], $this->ident) . 'I';
$cellClsA = '.' . sprintf($cellAttr['class'], $this->ident) . 'A';
$css->setStyle($cellClsI, 'width', $cellAttr['width'].'px');
$css->setStyle($cellClsI, 'height', $cellAttr['height'].'px');
$css->setStyle($cellClsI, 'font-family', $cellAttr['font-family']);
$css->setStyle($cellClsI, 'font-size', $cellAttr['font-size'].'px');
if ($this->orientation == HTML_PROGRESS2_BAR_HORIZONTAL) {
$css->setStyle($cellClsI, 'float', 'left');
}
if ($this->orientation == HTML_PROGRESS2_BAR_VERTICAL) {
$css->setStyle($cellClsI, 'float', 'none');
}
$css->setSameStyle($cellClsA, $cellClsI);
if ($this->orientation !== HTML_PROGRESS2_CIRCLE) {
$css->setStyle($cellClsI, 'background-color', $cellAttr['inactive-color']);
}
$css->setStyle($cellClsA, 'background-color', $cellAttr['active-color']);
if ($cellAttr['background-image'] !== 'none') {
$css->setStyle($cellClsA, 'background-image', 'url("'. $cellAttr['background-image'] .'")');
if ($this->orientation == HTML_PROGRESS2_CIRCLE) {
$css->setStyle($cellClsA, 'background-repeat', 'no-repeat');
} else {
$css->setStyle($cellClsA, 'background-repeat', $cellAttr['background-repeat']);
$css->setStyle($cellClsA, 'background-position', $cellAttr['background-position']);
}
}
if ($this->orientation == HTML_PROGRESS2_CIRCLE) {
$css->setStyle($cellClsI, 'background-image', 'url("'.$cellAttr[0]['background-image'].'")');
$css->setStyle($cellClsI, 'background-repeat', 'no-repeat');
}
$styles = $css->toString();
if ($raw !== true) {
$styles = '<style type="text/css">' . PHP_EOL
. '<!--' . PHP_EOL
. $styles . PHP_EOL
. ' -->' . PHP_EOL
. '</style>'. PHP_EOL;
}
return $styles;
}
/**
* Import cascading style sheet (CSS) elements
*
* Set the CSS required to display the progress meter in a HTML document.
*
* @param mixed $styles CSS elements reference to import
*
* @return void|PEAR_Error
* @since 2.2.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_INPUT
*/
function importStyle($styles)
{
if (is_string($styles)) {
$styles = (array)$styles;
}
if (!is_array($styles)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$styles',
'was' => gettype($styles),
'expected' => 'array | string',
'paramnum' => 1));
}
$css = new HTML_CSS();
$res = $css->parseData($styles);
if ($css->isError()) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'error',
array('var' => '$styles',
'was' => 'unknown data source',
'expected' => 'valid CSS',
'paramnum' => 1));
}
if (strpos($this->border['class'], '%s') === false) {
$pattern = $this->ident . '\.' . $this->border['class'];
} else {
$pattern = '\.' . sprintf($this->border['class'], $this->ident);
}
$border = $css->grepStyle("/$pattern/");
foreach ($border as $b) {
foreach ($b as $p => $v) {
if (substr($p, 0, 6) == 'border') {
$n = str_replace('border-', '', $p);
if (isset($this->border[$n])) {
if (substr($v, -2) == 'px') {
$this->border[$n] = intval($v);
} else {
$this->border[$n] = $v;
}
}
} else {
if ($p == 'background-color' && $this->cellCount == 0) {
$this->cell['inactive-color'] = $v;
} elseif (isset($this->_progress[$p])) {
if (substr($v, -2) == 'px') {
$this->_progress[$p] = intval($v);
} else {
$this->_progress[$p] = $v;
}
}
}
}
if ($this->border['width'] > 0) {
$this->_paintBorder = true;
}
}
foreach ($this->label as $name => $data) {
if (strpos($data['class'], '%s') === false) {
$pattern = $name . $this->ident . '\.' . $data['class'];
} else {
$pattern = '\.' . sprintf($data['class'], $name . $this->ident);
}
$label = $css->grepStyle("/$pattern/");
foreach ($label as $l) {
foreach ($l as $p => $v) {
if (substr($p, 0, 4) == 'text') {
$n = str_replace('text-', '', $p);
if (isset($this->label[$name][$n])) {
$this->label[$name][$n] = $v;
}
} elseif (isset($this->label[$name][$p])) {
if (substr($v, -2) == 'px') {
$this->label[$name][$p] = intval($v);
} else {
$this->label[$name][$p] = $v;
}
}
}
}
}
$pcell = '.' . sprintf($this->cell['class'], $this->ident);
if (strpos($this->cell['class'], '%s') === false) {
$pattern = $this->ident . '\s*\.' . $this->cell['class'];
} else {
$pattern = '\.' . sprintf($this->cell['class'], $this->ident);
}
$cell = $css->grepStyle("/$pattern/");
foreach ($cell as $c => $data) {
foreach ($data as $p => $v) {
if ($p == 'background-color') {
if (strpos($c, $pcell.'A') !== false) {
$this->cell['active-color'] = $v;
} else {
$this->cell['inactive-color'] = $v;
}
} elseif ($p == 'background-image') {
$pattern = "\s*url\s*\([\s\"'`]*([\w:?=@&\/#._;-]+)[\s\"'`]*\)\s*";
$found = preg_match("/$pattern/", $v, $matches);
if ($found) {
$this->cell[$p] = $matches[1];
}
} else {
if (substr($v, -2) == 'px') {
$this->cell[$p] = intval($v);
} else {
$this->cell[$p] = $v;
}
}
}
}
}
/**
* Returns the progress meter structure into an array.
*
* Get all progress meter properties, couple key-value, into a php array.
* This structure is read-only, a dump-like information.
*
* @return array
* @since 2.0.0
* @access public
*/
function toArray()
{
$structure = array(
'id' => $this->ident,
'indeterminate' => $this->indeterminate,
'borderpainted' => $this->isBorderPainted(),
'label' => $this->label,
'animspeed' => $this->animSpeed,
'orientation' => $this->orientation,
'fillway' => $this->fillWay,
'cell' => $this->cell,
'cellcount' => $this->cellCount,
'cellcoord' => $this->getCellCoordinates(),
'border' => $this->border,
'progress' => $this->_progress,
'script' => $this->getScript(),
'minimum' => $this->minimum,
'maximum' => $this->maximum,
'increment' => $this->increment,
'value' => $this->value,
'percent' => $this->getPercentComplete()
);
return $structure;
}
/**
* Returns the progress meter structure as HTML.
*
* Get html code required to display the progress meter in any html document.
*
* @return string
* @since 2.0.0
* @access public
*/
function toHtml()
{
$strHtml = '';
$tabs = $this->_getTabs();
$tab = $this->_getTab();
$comment = $this->getComment();
$progressAttr = $this->getProgressAttributes();
$borderAttr = $this->getBorderAttributes();
$cellAttr = $this->getCellAttributes();
/**
* Adds a progress meter caption in html code is possible.
* See HTML_Common::setComment() method.
*/
if (strlen($comment) > 0) {
$strHtml .= $tabs . "<!-- $comment -->" . PHP_EOL;
}
// Start of Top progress meter frame
if ($this->frame['show']) {
$topshift = $progressAttr['top'];
$leftshift = $progressAttr['left'];
$border = '';
if ($this->frame['border-width'] > 0) {
$border = 'border-width:' . $this->frame['border-width'] . 'px;'
. 'border-style:' . $this->frame['border-style'] . ';'
. 'border-color:' . $this->frame['border-color'] . ';';
}
if ($progressAttr['position'] == 'relative') {
$_top = $_left = 0;
} else {
$_top = $this->frame['top'];
$_left = $this->frame['left'];
}
$strHtml .= $tabs
. '<div id="tfrm' . $this->ident . '" style="'
. 'position:' . $progressAttr['position'] . ';'
. 'top:' . $_top . 'px;'
. 'left:' . $_left . 'px;'
. 'width:' . $this->frame['width'] . 'px;'
. 'height:' . $this->frame['height'] . 'px;'
. $border
. 'background-color:' . $this->frame['color'] . ';">'
. PHP_EOL;
} else {
$topshift = $leftshift = 0;
$strHtml .= $tabs
. '<div id="tfrm' . $this->ident . '" style="'
. 'position:' . $progressAttr['position'] . ';'
. 'top:' . $progressAttr['top'] . 'px;'
. 'left:' . $progressAttr['left'] . 'px;'
. 'height:{_heightshift_}px;">'
. PHP_EOL;
}
// Start of progress meter border
$strHtml .= $tabs
. '<div id="pbrd' . $this->ident . '"'
. ' style="position:absolute;top:{_topshift_}px;left:{_leftshift_}px;"'
. ' class="' . sprintf($borderAttr['class'], $this->ident) . '">'
. PHP_EOL;
// Start of progress meter
if ($this->cellCount == 0) {
$strHtml .= $tabs
. '<div id="pbar' . $this->ident . '" style="'
. 'width:' . $progressAttr['width'] . 'px;'
. 'height:' . $progressAttr['height'] . 'px;'
. 'background-color:' . $cellAttr['active-color'] . ';">'
. PHP_EOL;
} else {
$strHtml .= $tabs
. '<div id="pbar' . $this->ident . '">'
. PHP_EOL;
}
if ($this->orientation == HTML_PROGRESS2_BAR_HORIZONTAL) {
$progressHtml = $this->_getProgressHbar_toHtml();
}
if ($this->orientation == HTML_PROGRESS2_BAR_VERTICAL) {
$progressHtml = $this->_getProgressVbar_toHtml();
}
if ($this->orientation == HTML_PROGRESS2_POLYGONAL) {
$progressHtml = $this->_getProgressPolygonal_toHtml();
}
if ($this->orientation == HTML_PROGRESS2_CIRCLE) {
$cellAttr = $this->getCellAttributes();
if (!isset($cellAttr[0]['background-image']) || !file_exists($cellAttr[0]['background-image'])) {
// creates default circle segments pictures :
// 'c0.png'->0% 'c1.png'->10%, 'c2.png'->20%, ... 'c10.png'->100%
$this->drawCircleSegments();
}
$progressHtml = $this->_getProgressCircle_toHtml();
}
$strHtml .= $tabs
. $progressHtml
. PHP_EOL;
// Enf of progress meter
$strHtml .= $tabs
. '</div>'
. PHP_EOL;
// Enf of progress meter border
$strHtml .= $tabs
. '</div>'
. PHP_EOL;
$cyshift = 0;
$heightshift = $progressAttr['height'];
// Start of progress meter labels
foreach ($this->label as $name => $data) {
$align = $data['align'];
$width = $data['width'];
$height = $data['height'];
if ($progressAttr['position'] == 'relative') {
switch ($data['valign']) {
case 'top':
$style_pos = 'top:0;left:{_leftshift_}px;';
if ($data['height'] > 0) {
$topshift = $data['height'];
} else {
$topshift = $progressAttr['height'];
}
$height = $topshift;
$heightshift += $height;
break;
case 'right':
$style_pos = 'top:{_topshift_}px;'
. 'left:{_rxshift_}px;';
break;
case 'bottom':
$style_pos = 'top:{_cyshift_}px;'
. 'left:{_leftshift_}px;';
$cyshift = $progressAttr['height'];
if ($data['height'] == 0) {
$height = $progressAttr['height'];
}
$heightshift += $height;
break;
case 'left':
$style_pos = 'top:{_topshift_}px;left:0;';
if ($data['width'] > 0) {
$leftshift = $data['width'];
} else {
$leftshift = $progressAttr['width'];
}
$leftshift += $data['left'];
break;
case 'center':
$style_pos = 'top:{_cyshift_}px;'
. 'left:{_leftshift_}px;';
$cyshift = intval($progressAttr['height']) / 2;
$width = $progressAttr['width'];
$align = 'center';
break;
}
if ($this->frame['show']) {
$style_pos .= 'margin-top:5px;'
. 'margin-left:5px;';
} else {
$style_pos .= 'margin-top:' . $data['top'] . 'px;'
. 'margin-left:' . $data['left'] . 'px;';
}
if ($width > 0) {
$style_pos .= 'width:' . $width . 'px;';
}
} else {
$style_pos = 'top:' . $data['top'] . 'px;'
. 'left:' . $data['left'] . 'px;';
}
$style_cls = sprintf($data['class'], $name . $this->ident);
switch ($data['type']) {
case HTML_PROGRESS2_LABEL_TEXT:
$strHtml .= $tabs
. '<div id="plbl' . $name . $this->ident . '"'
. ' style="position:absolute;' . $style_pos . '"'
. ' class="' . $style_cls . '">'
. $data['value']
. '</div>'
. PHP_EOL;
break;
case HTML_PROGRESS2_LABEL_BUTTON:
$strHtml .= $tabs
. '<div><input id="plbl' . $name . $this->ident
. '" type="button" value="' . $data['value']
. '" style="position:absolute;' . $style_pos
. '" class="' . $style_cls
. '" onclick="' . $data['target']
. '.location.href=\'' . $data['action'] . '\'" />'
. '</div>'
. PHP_EOL;
break;
case HTML_PROGRESS2_LABEL_STEP:
$strHtml .= $tabs
. '<div id="plbl' . $name . $this->ident
. '" style="position:absolute;' . $style_pos
. '" class="' . $style_cls . '"> '
. '</div>'
. PHP_EOL;
break;
case HTML_PROGRESS2_LABEL_PERCENT:
$strHtml .= $tabs
. '<div id="plbl' . $name . $this->ident . '"'
. ' style="position:absolute;' . $style_pos . '"'
. ' class="' . $style_cls . '"> '
. '</div>'
. PHP_EOL;
break;
case HTML_PROGRESS2_LABEL_CROSSBAR:
$strHtml .= $tabs
. '<div id="plbl' . $name . $this->ident . '"'
. ' style="position:absolute;' . $style_pos . '"'
. ' class="' . $style_cls . '">'
. $data['value']
. '</div>'
. PHP_EOL;
break;
}
}
// End of Top progress meter frame
$strHtml .= $tabs
. '</div>'
. PHP_EOL;
$placeHolders = array(
'{_leftshift_}', '{_topshift_}', '{_heightshift_}',
'{_cyshift_}', '{_rxshift_}'
);
$htmlElement = array(
$leftshift, $topshift, $heightshift,
($topshift + $cyshift), ($leftshift + $progressAttr['width'])
);
$strHtml = str_replace($placeHolders, $htmlElement, $strHtml);
return $strHtml;
}
/**
* Renders the new value of progress meter.
*
* This method should be used only to display initial state of the progress meter.
* Next steps to refresh display must use either moveStep() or moveNext() methods.
*
* @return void
* @since 2.0.0
* @access public
*/
function display()
{
$this->_status = 'show';
echo $this->toHtml();
}
/**
* Hides the progress meter.
*
* Once the process is over this method provides a solution
* to remove/hide the progress meter of the browser screen.
*
* @return void
* @since 2.0.0
* @access public
*/
function hide()
{
$bar = '<script type="text/javascript">'
. 'hideProgress("' . $this->ident . '");'
. '</script>';
echo $bar . PHP_EOL;
}
/**
* Delay execution.
*
* The HTML_Progress2::sleep() function delays program execution
* for the given number of milliseconds.
* This is the default user callback when none are defined.
*
* NOTE: The function {@link http://www.php.net/manual/en/function.usleep.php}
* did not work on Windows systems until PHP 5.0.0
*
* @return void
* @since 2.0.0
* @access public
* @see getAnimSpeed(), setAnimSpeed(), process()
*/
function sleep()
{
// convert delay from milliseconds to microseconds
$usecs = $this->animSpeed * 1000;
if ((substr(PHP_OS, 0, 3) == 'WIN') && (substr(PHP_VERSION,0,1) < '5')) {
for ($i = 0; $i < $usecs; $i++) {
}
} else {
usleep($usecs);
}
}
/**
* Sets the user progress callback function.
*
* The process() function will call the user-callback defined here by this
* setProgressHandler() method.
*
* The user-supplied progress function must return either positive
* for a step progression, using moveStep() method,
* or NULL for a standard progression, using moveNext() method.
*
* @param mixed $handler Name of function or a class-method.
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_CALLBACK
* @see process()
*/
function setProgressHandler($handler)
{
if (!is_callable($handler)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_CALLBACK, 'warning',
array('var' => '$handler',
'element' => 'valid Class-Method/Function',
'was' => 'callback',
'paramnum' => 1));
}
$this->_callback = $handler;
}
/**
* Performs the progress user process.
*
* This function call the user-specified progress function, defined by
* setProgressHandler() method. Default callback is the HTML_Progress2::sleep() method.
*
* @return mixed
* @since 2.0.0
* @access public
* @see sleep(), setProgressHandler()
*/
function process()
{
if ($this->_callback) {
return call_user_func_array($this->_callback, array($this->value, &$this));
} else {
// when there is no valid user callback then default is to sleep a bit ...
$this->sleep();
}
}
/**
* Runs the progress meter.
*
* This function accept both modes: indeterminate and determinate,
* and execute all actions defined in the user callback identified by
* setProgressHandler() method.
*
* All observers are also notified of main changes (start, stop meter).
*
* @return void
* @since 2.0.0
* @access public
* @see process(), setProgressHandler()
*/
function run()
{
$this->_postNotification('onSubmit', array('handler' => __FUNCTION__, 'value' => $this->getValue()));
do {
$ret = $this->process();
if ($this->getPercentComplete() == 1) {
if ($this->indeterminate) {
$this->setValue(0);
} else {
break;
}
}
if (is_null($ret)) {
$this->moveNext();
} else {
$this->moveStep($ret);
}
} while (1);
$this->_postNotification('onLoad', array('handler' => __FUNCTION__, 'value' => $this->getValue()));
}
/**
* Returns the progress meter identifier.
*
* Each progress meter has its own identifier. That allows to display more than
* only once meter at same time on same page.
*
* @return string
* @since 2.0.0
* @access public
* @see setIdent()
*/
function getIdent()
{
return $this->ident;
}
/**
* Sets the progress meter identifier.
*
* Each progress meter has its own identifier. That allows to display more than
* only once meter at same time on same page.
* If no identification string is given, then the default identifier will be
* six first characters of md5 hash value of the current unix timestamp.
*
* @param mixed $ident (optional) the new identification string.
*
* @since 2.0.0
* @access public
* @see getIdent()
*/
function setIdent($ident = null)
{
if (is_null($ident)) {
$this->ident = substr(md5(microtime()), 0, 6);
} else {
$this->ident = $ident;
}
}
/**
* Attachs a new observer.
*
* Adds a new observer to the Event Dispatcher that will listen
* for all messages emitted by this HTML_Progress2 instance.
*
* @param mixed $callback PHP callback that will act as listener
* @param string $nName Expected notification name, serves as a filter
*
* @return void
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_CALLBACK,
* HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see removeListener()
*/
function addListener($callback, $nName = EVENT_DISPATCHER_GLOBAL)
{
if (!is_callable($callback)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_CALLBACK, 'exception',
array('var' => '$callback',
'element' => 'valid Class-Method/Function',
'was' => 'callback',
'paramnum' => 1));
} elseif (!is_string($nName)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$nName',
'was' => gettype($nName),
'expected' => 'string',
'paramnum' => 2));
}
$this->dispatcher =& Event_Dispatcher::getInstance('ProgressMeter');
$this->dispatcher->addObserver($callback, $nName);
$this->_observerCount++;
}
/**
* Removes a registered observer.
*
* Detachs a previously registered observer and remove the Event Dispatcher
* if there is no more observer registered.
*
* @param mixed $callback PHP callback that act as listener
* @param string $nName Expected notification name, serves as a filter
*
* @return bool True if observer was removed, false otherwise
* @since 2.0.0
* @access public
* @throws HTML_PROGRESS2_ERROR_INVALID_CALLBACK,
* HTML_PROGRESS2_ERROR_INVALID_INPUT
* @see addListener()
*/
function removeListener($callback, $nName = EVENT_DISPATCHER_GLOBAL)
{
if (!is_callable($callback)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_CALLBACK, 'exception',
array('var' => '$callback',
'element' => 'valid Class-Method/Function',
'was' => 'callback',
'paramnum' => 1));
} elseif (!is_string($nName)) {
return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception',
array('var' => '$nName',
'was' => gettype($nName),
'expected' => 'string',
'paramnum' => 2));
}
$result = $this->dispatcher->removeObserver($callback, $nName);
if ($result) {
$this->_observerCount--;
if ($this->_observerCount == 0) {
unset($this->dispatcher);
}
}
return $result;
}
/**
* Refresh the progress meter display.
*
* @param integer $value new value of the progress meter
*
* @return void
* @since 2.0.0RC2
* @access private
* @see moveStep(), moveNext()
*/
function _refreshDisplay($value)
{
static $determinate;
foreach ($this->label as $name => $data) {
switch($data['type']) {
case HTML_PROGRESS2_LABEL_STEP:
if (!$this->indeterminate) {
$this->_changeLabelText($name, intval(ceil($value / $this->increment))
. '/'
. intval(ceil($this->maximum / $this->increment))
);
}
break;
case HTML_PROGRESS2_LABEL_PERCENT:
if (!$this->indeterminate) {
$this->_changeLabelText($name, $this->getPercentComplete(false) . '%');
}
break;
case HTML_PROGRESS2_LABEL_CROSSBAR:
$this->_changeCrossItem($name);
break;
}
}
$bar = ob_get_clean();
if ($this->cellCount > 0) {
$cellAmount = ($this->maximum - $this->minimum) / $this->cellCount;
if ($this->indeterminate) {
if (isset($determinate)) {
$determinate++;
$progress = $determinate;
} else {
$progress = $determinate = 1;
}
} else {
$progress = ($this->value - $this->minimum) / $cellAmount;
$determinate = 0;
}
$bar .= '<script type="text/javascript">'
. 'setProgress'
. '("' . $this->ident . '",'
. intval($progress) . ',' . $determinate . ',' . $this->cellCount
. ');'
. '</script>';
} else {
$position = $this->_computePosition();
$orient = $this->orientation;
$cssText = '';
if ($orient == HTML_PROGRESS2_BAR_HORIZONTAL) {
if ($this->fillWay == 'reverse') {
$cssText .= 'left:' . $position['left'] . 'px;';
}
$cssText .= 'width:' . $position['width'] . 'px;';
}
if ($orient == HTML_PROGRESS2_BAR_VERTICAL) {
if ($this->fillWay == 'natural') {
$cssText .= 'top:' . $position['top'] . 'px;';
}
$cssText .= 'height:' . $position['height'] . 'px;';
}
$bar .= $this->_changeElementStyle('pbar', '', $cssText);
}
echo $bar . PHP_EOL;
ob_start();
}
/**
* Returns a horizontal progress bar structure as HTML.
*
* @return string
* @since 2.0.0
* @access private
*/
function _getProgressHbar_toHtml()
{
$tabs = $this->_getTabs();
$tab = $this->_getTab();
$way_natural = ($this->fillWay == 'natural');
$cellAttr = $this->getCellAttributes();
$cellCls = sprintf($cellAttr['class'], $this->ident);
$html = '';
if ($way_natural) {
$pos = $cellAttr['spacing'];
for ($i = 0; $i < $this->cellCount; $i++) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $pos . 'px;'
. 'top:' . $cellAttr['spacing'] . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
$pos += ($cellAttr['width'] + $cellAttr['spacing']);
}
} else {
$pos = $cellAttr['spacing'];
for ($i = $this->cellCount - 1; $i >= 0; $i--) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $pos . 'px;'
. 'top:' . $cellAttr['spacing'] . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
$pos += ($cellAttr['width'] + $cellAttr['spacing']);
}
}
return $html;
}
/**
* Returns a vertical progress bar structure as HTML.
*
* @return string
* @since 2.0.0
* @access private
*/
function _getProgressVbar_toHtml()
{
$tabs = $this->_getTabs();
$tab = $this->_getTab();
$way_natural = ($this->fillWay == 'natural');
$cellAttr = $this->getCellAttributes();
$cellCls = sprintf($cellAttr['class'], $this->ident);
$html = '';
if ($way_natural) {
$pos = $cellAttr['spacing'];
for ($i = $this->cellCount - 1; $i >= 0; $i--) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $cellAttr['spacing'] . 'px;'
. 'top:' . $pos . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
$pos += ($cellAttr['height'] + $cellAttr['spacing']);
}
} else {
$pos = $cellAttr['spacing'];
for ($i = 0; $i < $this->cellCount; $i++) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $cellAttr['spacing'] . 'px;'
. 'top:' . $pos . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
$pos += ($cellAttr['height'] + $cellAttr['spacing']);
}
}
return $html;
}
/**
* Returns a polygonal progress structure as HTML.
*
* @return string
* @since 2.0.0
* @access private
*/
function _getProgressPolygonal_toHtml()
{
$tabs = $this->_getTabs();
$tab = $this->_getTab();
$way_natural = ($this->fillWay == 'natural');
$cellAttr = $this->getCellAttributes();
$cellCls = sprintf($cellAttr['class'], $this->ident);
$coord = $this->getCellCoordinates();
$html = '';
if ($way_natural) {
for ($i = 0; $i < $this->cellCount; $i++) {
$top = $coord[$i][0] * $cellAttr['width'];
$left = $coord[$i][1] * $cellAttr['height'];
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $left . 'px;'
. 'top:' . $top . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
}
} else {
$c = count($coord) - 1;
for ($i = 0; $i < $this->cellCount; $i++) {
$top = $coord[$c-$i][0] * $cellAttr['width'];
$left = $coord[$c-$i][1] * $cellAttr['height'];
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;'
. 'left:' . $left . 'px;'
. 'top:' . $top . 'px;';
if (isset($cellAttr[$i])) {
$html .= 'color:' . $cellAttr[$i]['color'] . ';';
}
$html .= '"></div>' . PHP_EOL;
}
}
return $html;
}
/**
* Returns a circle progress structure as HTML.
*
* @return string
* @since 2.0.0
* @access private
*/
function _getProgressCircle_toHtml()
{
$tabs = $this->_getTabs();
$tab = $this->_getTab();
$way_natural = ($this->fillWay == 'natural');
$cellAttr = $this->getCellAttributes();
$cellCls = sprintf($cellAttr['class'], $this->ident);
$html = '';
if ($way_natural) {
for ($i = 0; $i < $this->cellCount; $i++) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;left:0;top:0;'
. '"><img src="' . $cellAttr[$i+1]['background-image']
. '" border="0" alt="" />'
. '</div>'
. PHP_EOL;
}
} else {
for ($i = 0; $i < $this->cellCount; $i++) {
$html .= $tabs . $tab
. '<div id="' . sprintf($cellAttr['id'], $i) . $this->ident . '"'
. ' class="' . $cellCls . 'I"'
. ' style="position:absolute;left:0;top:0;'
. '"><img src="' . $cellAttr[$i+1]['background-image']
. '" border="0" alt="" />'
. '</div>'
. PHP_EOL;
}
}
return $html;
}
/**
* Computes all coordinates of a standard polygon (square or rectangle).
*
* @param integer $w Polygon width
* @param integer $h Polygon height
*
* @return array
* @since 2.0.0
* @access private
* @see setCellCoordinates()
*/
function _computeCoordinates($w, $h)
{
$coord = array();
for ($y=0; $y<$h; $y++) {
if ($y == 0) {
// creates top side line
for ($x=0; $x<$w; $x++) {
$coord[] = array($y, $x);
}
} elseif ($y == ($h-1)) {
// creates bottom side line
for ($x=($w-1); $x>0; $x--) {
$coord[] = array($y, $x);
}
// creates left side line
for ($i=($h-1); $i>0; $i--) {
$coord[] = array($i, 0);
}
} else {
// creates right side line
$coord[] = array($y, $w - 1);
}
}
return $coord;
}
/**
* Updates the new size of progress bar, depending of cell size, cell count
* and border width.
*
* @since 2.0.0
* @access private
* @see setOrientation(), setCellCount(), setCellAttributes(),
* setBorderAttributes()
*/
function _updateProgressSize()
{
if ($this->cellCount == 0) {
return;
}
$cell_width = $this->cell['width'];
$cell_height = $this->cell['height'];
$cell_spacing = $this->cell['spacing'];
$border_width = $this->border['width'];
$cell_count = $this->cellCount;
if ($this->orientation == HTML_PROGRESS2_BAR_HORIZONTAL) {
$w = ($cell_count * ($cell_width + $cell_spacing)) + $cell_spacing;
$h = $cell_height + (2 * $cell_spacing);
}
if ($this->orientation == HTML_PROGRESS2_BAR_VERTICAL) {
$w = $cell_width + (2 * $cell_spacing);
$h = ($cell_count * ($cell_height + $cell_spacing)) + $cell_spacing;
}
if ($this->orientation == HTML_PROGRESS2_POLYGONAL) {
$w = $cell_width * $this->_xgrid;
$h = $cell_height * $this->_ygrid;
}
if ($this->orientation == HTML_PROGRESS2_CIRCLE) {
$w = $cell_width;
$h = $cell_height;
}
$attr = array ('width' => $w, 'height' => $h);
$this->_updateAttrArray($this->_progress, $attr);
}
/**
* Calculate the new position in pixel of the progress bar value.
*
* @return void
* @since 2.0.0
* @access private
*/
function _computePosition()
{
$orient = $this->orientation;
$progressAttr = $this->getProgressAttributes();
$min = $this->minimum;
$max = $this->maximum;
$step = $this->value;
$padding = 0;
if ($orient == HTML_PROGRESS2_BAR_HORIZONTAL) {
if ($this->fillWay == 'natural') {
$direction = 'right';
} else {
$direction = 'left';
}
} else {
if ($this->fillWay == 'natural') {
$direction = 'up';
} else {
$direction = 'down';
}
}
switch ($direction) {
case 'right':
case 'left':
$bar = $progressAttr['width'];
break;
case 'down':
case 'up':
$bar = $progressAttr['height'];
break;
}
$pixel = round(($step - $min) * ($bar - ($padding * 2)) / ($max - $min));
if ($step <= $min) {
$pixel = 0;
}
if ($step >= $max) {
$pixel = $bar - ($padding * 2);
}
switch ($direction) {
case 'right':
$position['left'] = $padding;
$position['top'] = $padding;
$position['width'] = $pixel;
$position['height'] = $progressAttr['height'] - ($padding * 2);
break;
case 'left':
$position['left'] = $progressAttr['width'] - $padding - $pixel;
$position['top'] = $padding;
$position['width'] = $pixel;
$position['height'] = $progressAttr['height'] - ($padding * 2);
break;
case 'down':
$position['left'] = $padding;
$position['top'] = $padding;
$position['width'] = $progressAttr['width'] - ($padding * 2);
$position['height'] = $pixel;
break;
case 'up':
$position['left'] = $padding;
$position['top'] = $progressAttr['height'] - $padding - $pixel;
$position['width'] = $progressAttr['width'] - ($padding * 2);
$position['height'] = $pixel;
break;
}
return $position;
}
/**
* Sends a DOM command (emulate firstChild.nodeValue) through a javascript function
* to change label value of a progress bar's element.
*
* @param string $element element name (label id.)
* @param string $text element value (label content)
*
* @return void
* @since 2.0.0
* @access private
*/
function _changeLabelText($element, $text)
{
$cmd = '<script type="text/javascript">'
. 'setLabelText'
. '("' . $this->ident . '","' . $element . '","' . $text . '");'
. '</script>';
echo $cmd;
}
/**
* Sends a DOM command through a javascript function
* to change the next frame animation of a cross bar's element.
*
* @param string $element element name (cross id.)
*
* @return string
* @since 2.0.0
* @access private
*/
function _changeCrossItem($element)
{
$cmd = '<script type="text/javascript">'
. 'setRotaryCross'
. '("' . $this->ident . '","' . $element . '");'
. '</script>';
echo $cmd;
}
/**
* Sends a DOM command (emulate cssText attribute) through a javascript function
* to change styles of a progress bar's element.
*
* @param string $prefix prefix identifier of the element
* @param string $element element name (label id.)
* @param string $styles styles of a DOM element
*
* @return string
* @since 2.0.0
* @access private
*/
function _changeElementStyle($prefix, $element, $styles)
{
$cmd = '<script type="text/javascript">'
. 'setElementStyle'
. '("' . $prefix . '","' . $element . '","' . $this->ident . '","' . $styles . '");'
. '</script>';
return $cmd;
}
/**
* Post a new notification to all observers registered.
* This notification occured only if a dispatcher exists. That means if
* at least one observer was registered.
*
* @param string $event Name of the notification handler
* @param array $info (optional) Additional information about the notification
*
* @return void
* @since 2.0.0RC2
* @access private
*/
function _postNotification($event, $info = array())
{
if (isset($this->dispatcher)) {
$info['sender'] = get_class($this);
$info['time'] = microtime();
$this->dispatcher->post($this, $event, $info);
}
}
/**
* Initialize Error Handler
*
* Parameter '$prefs' contains a hash of options to define the error handler.
* You may find :
* 'message_callback' A callback to generate message body.
* Default is: HTML_Progress2_Error::_msgCallback()
* 'context_callback' A callback to generate context of error.
* Default is: HTML_Progress2_Error::getBacktrace()
* 'push_callback' A callback to determine whether to allow an error
* to be pushed or logged.
* Default is: HTML_Progress2_Error::_handleError()
* 'error_handler' A callback to manage all error raised.
* Default is: HTML_Progress2::_errorHandler()
* 'handler' Hash of params to configure all handlers (display, file, mail ...)
* There are only a display handler by default with options below:
*
* @param array $prefs hash of params to configure error handler
*
* @return void
* @since 2.0.0
* @access private
*/
function _initErrorHandler($prefs = array())
{
// error message mapping callback
if (isset($prefs['message_callback']) && is_callable($prefs['message_callback'])) {
$this->_callback_message = $prefs['message_callback'];
} else {
$this->_callback_message = array('HTML_Progress2_Error', '_msgCallback');
}
// error context mapping callback
if (isset($prefs['context_callback']) && is_callable($prefs['context_callback'])) {
$this->_callback_context = $prefs['context_callback'];
} else {
$this->_callback_context = array('HTML_Progress2_Error', 'getBacktrace');
}
// determine whether to allow an error to be pushed or logged
if (isset($prefs['push_callback']) && is_callable($prefs['push_callback'])) {
$this->_callback_push = $prefs['push_callback'];
} else {
$this->_callback_push = array('HTML_Progress2_Error', '_handleError');
}
// default error handler will use PEAR_Error
if (isset($prefs['error_handler']) && is_callable($prefs['error_handler'])) {
$this->_callback_errorhandler = $prefs['error_handler'];
} else {
$this->_callback_errorhandler = array(&$this, '_errorHandler');
}
// any handler-specific settings
if (isset($prefs['handler'])) {
$this->_errorhandler_options = $prefs['handler'];
}
}
/**
* Standard error handler that will use PEAR_Error object
*
* To improve performances, the PEAR.php file is included dynamically.
* The file is so included only when an error is triggered. So, in most
* cases, the file isn't included and perfs are much better.
*
* @param integer $code Error code
* @param string $level Error level
* @param array $params Associative array of error parameters
*
* @return PEAR_Error
* @since 2.0.0
* @access private
*/
function _errorHandler($code, $level, $params)
{
require_once 'HTML/Progress2/Error.php';
$mode = call_user_func($this->_callback_push, $code, $level);
$message = call_user_func($this->_callback_message, $code, $params);
$userinfo['level'] = $level;
if (isset($this->_errorhandler_options['display'])) {
$userinfo['display'] = $this->_errorhandler_options['display'];
} else {
$userinfo['display'] = array();
}
if (isset($this->_errorhandler_options['log'])) {
$userinfo['log'] = $this->_errorhandler_options['log'];
} else {
$userinfo['log'] = array();
}
return PEAR::raiseError($message, $code, $mode, null, $userinfo, 'HTML_Progress2_Error');
}
/**
* A basic wrapper around the default PEAR_Error object.
*
* This method throws any internal API error that could be raised
* due to a wrong programming. It will use your error handler system defined
* at class construction (by first argument).
*
* @return mixed
* @since 2.0.0
* @access public
* @see _errorHandler()
*/
function raiseError()
{
$args = func_get_args();
$err = call_user_func_array($this->_callback_errorhandler, $args);
if (is_null($err)) {
$err = array('code' => $args[0], 'level' => $args[1], 'params' => $args[2]);
}
array_push($this->_errorstack, $err);
return $err;
}
/**
* Determine whether there are errors into the HTML_Progress2 stack.
*
* This function gave you ability to be aware of API errors presence
* in user scripts.
*
* @return integer
* @since 2.0.0
* @access public
* @see getError(), raiseError()
*/
function hasErrors()
{
return count($this->_errorstack);
}
/**
* Pop an error off of the HTML_Progress2 stack.
*
* Get all error data (code, message, level, context) from an object (PEAR_Error, ...)
* or a simple php array.
*
* @return false|array|PEAR_Error
* @since 2.0.0
* @access public
* @see hasErrors(), raiseError()
*/
function getError()
{
return @array_shift($this->_errorstack);
}
}
?>
|