web/lib/Zend/TimeSync.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * Zend Framework
       
     5  *
       
     6  * LICENSE
       
     7  *
       
     8  * This source file is subject to the new BSD license that is bundled
       
     9  * with this package in the file LICENSE.txt.
       
    10  * It is also available through the world-wide-web at this URL:
       
    11  * http://framework.zend.com/license/new-bsd
       
    12  * If you did not receive a copy of the license and are unable to
       
    13  * obtain it through the world-wide-web, please send an email
       
    14  * to license@zend.com so we can send you a copy immediately.
       
    15  *
       
    16  * @category   Zend
       
    17  * @package    Zend_TimeSync
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @version    $Id: TimeSync.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    20  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    21  */
       
    22 
       
    23 /**
       
    24  * Zend_Date
       
    25  */
       
    26 require_once 'Zend/Date.php';
       
    27 
       
    28 /**
       
    29  * @category   Zend
       
    30  * @package    Zend_TimeSync
       
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    33  */
       
    34 class Zend_TimeSync implements IteratorAggregate
       
    35 {
       
    36     /**
       
    37      * Set the default timeserver protocol to "Ntp". This will be called
       
    38      * when no protocol is specified
       
    39      */
       
    40     const DEFAULT_PROTOCOL = 'Ntp';
       
    41 
       
    42     /**
       
    43      * Contains array of timeserver objects
       
    44      *
       
    45      * @var array
       
    46      */
       
    47     protected $_timeservers = array();
       
    48 
       
    49     /**
       
    50      * Holds a reference to the timeserver that is currently being used
       
    51      *
       
    52      * @var object
       
    53      */
       
    54     protected $_current;
       
    55 
       
    56     /**
       
    57      * Allowed timeserver schemes
       
    58      *
       
    59      * @var array
       
    60      */
       
    61     protected $_allowedSchemes = array(
       
    62         'Ntp',
       
    63         'Sntp'
       
    64     );
       
    65 
       
    66     /**
       
    67      * Configuration array, set using the constructor or using
       
    68      * ::setOptions() or ::setOption()
       
    69      *
       
    70      * @var array
       
    71      */
       
    72     public static $options = array(
       
    73         'timeout' => 1
       
    74     );
       
    75 
       
    76     /**
       
    77      * Zend_TimeSync constructor
       
    78      *
       
    79      * @param  string|array $target - OPTIONAL single timeserver, or an array of timeservers.
       
    80      * @param  string       $alias  - OPTIONAL an alias for this timeserver
       
    81      * @return  object
       
    82      */
       
    83     public function __construct($target = null, $alias = null)
       
    84     {
       
    85         if ($target !== null) {
       
    86             $this->addServer($target, $alias);
       
    87         }
       
    88     }
       
    89 
       
    90     /**
       
    91      * getIterator() - return an iteratable object for use in foreach and the like,
       
    92      * this completes the IteratorAggregate interface
       
    93      *
       
    94      * @return ArrayObject
       
    95      */
       
    96     public function getIterator()
       
    97     {
       
    98         return new ArrayObject($this->_timeservers);
       
    99     }
       
   100 
       
   101     /**
       
   102      * Add a timeserver or multiple timeservers
       
   103      *
       
   104      * Server should be a single string representation of a timeserver,
       
   105      * or a structured array listing multiple timeservers.
       
   106      *
       
   107      * If you provide an array of timeservers in the $target variable,
       
   108      * $alias will be ignored. you can enter these as the array key
       
   109      * in the provided array, which should be structured as follows:
       
   110      *
       
   111      * <code>
       
   112      * $example = array(
       
   113      *   'server_a' => 'ntp://127.0.0.1',
       
   114      *   'server_b' => 'ntp://127.0.0.1:123',
       
   115      *   'server_c' => 'ntp://[2000:364:234::2.5]',
       
   116      *   'server_d' => 'ntp://[2000:364:234::2.5]:123'
       
   117      * );
       
   118      * </code>
       
   119      *
       
   120      * If no port number has been suplied, the default matching port
       
   121      * number will be used.
       
   122      *
       
   123      * Supported protocols are:
       
   124      * - ntp
       
   125      * - sntp
       
   126      *
       
   127      * @param  string|array $target - Single timeserver, or an array of timeservers.
       
   128      * @param  string       $alias  - OPTIONAL an alias for this timeserver
       
   129      * @throws Zend_TimeSync_Exception
       
   130      */
       
   131     public function addServer($target, $alias = null)
       
   132     {
       
   133         if (is_array($target)) {
       
   134             foreach ($target as $key => $server) {
       
   135                 $this->_addServer($server, $key);
       
   136             }
       
   137         } else {
       
   138             $this->_addServer($target, $alias);
       
   139         }
       
   140     }
       
   141 
       
   142     /**
       
   143      * Sets the value for the given options
       
   144      *
       
   145      * This will replace any currently defined options.
       
   146      *
       
   147      * @param   array $options - An array of options to be set
       
   148      */
       
   149     public static function setOptions(array $options)
       
   150     {
       
   151         foreach ($options as $key => $value) {
       
   152             Zend_TimeSync::$options[$key] = $value;
       
   153         }
       
   154     }
       
   155 
       
   156     /**
       
   157      * Marks a nameserver as current
       
   158      *
       
   159      * @param   string|integer $alias - The alias from the timeserver to set as current
       
   160      * @throws  Zend_TimeSync_Exception
       
   161      */
       
   162     public function setServer($alias)
       
   163     {
       
   164         if (isset($this->_timeservers[$alias]) === true) {
       
   165             $this->_current = $this->_timeservers[$alias];
       
   166         } else {
       
   167             require_once 'Zend/TimeSync/Exception.php';
       
   168             throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver");
       
   169         }
       
   170     }
       
   171 
       
   172     /**
       
   173      * Returns the value to the option
       
   174      *
       
   175      * @param   string $key - The option's identifier
       
   176      * @return  mixed
       
   177      * @throws  Zend_TimeSync_Exception
       
   178      */
       
   179     public static function getOptions($key = null)
       
   180     {
       
   181         if ($key == null) {
       
   182             return Zend_TimeSync::$options;
       
   183         }
       
   184 
       
   185         if (isset(Zend_TimeSync::$options[$key]) === true) {
       
   186             return Zend_TimeSync::$options[$key];
       
   187         } else {
       
   188             require_once 'Zend/TimeSync/Exception.php';
       
   189             throw new Zend_TimeSync_Exception("'$key' does not point to valid option");
       
   190         }
       
   191     }
       
   192 
       
   193     /**
       
   194      * Return a specified timeserver by alias
       
   195      * If no alias is given it will return the current timeserver
       
   196      *
       
   197      * @param   string|integer $alias - The alias from the timeserver to return
       
   198      * @return  object
       
   199      * @throws  Zend_TimeSync_Exception
       
   200      */
       
   201     public function getServer($alias = null)
       
   202     {
       
   203         if ($alias === null) {
       
   204             if (isset($this->_current) && $this->_current !== false) {
       
   205                 return $this->_current;
       
   206             } else {
       
   207                 require_once 'Zend/TimeSync/Exception.php';
       
   208                 throw new Zend_TimeSync_Exception('there is no timeserver set');
       
   209             }
       
   210         }
       
   211         if (isset($this->_timeservers[$alias]) === true) {
       
   212             return $this->_timeservers[$alias];
       
   213         } else {
       
   214             require_once 'Zend/TimeSync/Exception.php';
       
   215             throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver");
       
   216         }
       
   217     }
       
   218 
       
   219     /**
       
   220      * Returns information sent/returned from the current timeserver
       
   221      *
       
   222      * @return  array
       
   223      */
       
   224     public function getInfo()
       
   225     {
       
   226         return $this->getServer()->getInfo();
       
   227     }
       
   228 
       
   229     /**
       
   230      * Query the timeserver list using the fallback mechanism
       
   231      *
       
   232      * If there are multiple servers listed, this method will act as a
       
   233      * facade and will try to return the date from the first server that
       
   234      * returns a valid result.
       
   235      *
       
   236      * @param   $locale - OPTIONAL locale
       
   237      * @return  object
       
   238      * @throws  Zend_TimeSync_Exception
       
   239      */
       
   240     public function getDate($locale = null)
       
   241     {
       
   242         require_once 'Zend/TimeSync/Exception.php';
       
   243         foreach ($this->_timeservers as $alias => $server) {
       
   244             $this->_current = $server;
       
   245             try {
       
   246                 return $server->getDate($locale);
       
   247             } catch (Zend_TimeSync_Exception $e) {
       
   248                 if (!isset($masterException)) {
       
   249                     $masterException = new Zend_TimeSync_Exception('all timeservers are bogus');
       
   250                 }
       
   251                 $masterException->addException($e);
       
   252             }
       
   253         }
       
   254 
       
   255         throw $masterException;
       
   256     }
       
   257 
       
   258     /**
       
   259      * Adds a timeserver object to the timeserver list
       
   260      *
       
   261      * @param  string|array $target   - Single timeserver, or an array of timeservers.
       
   262      * @param  string       $alias    - An alias for this timeserver
       
   263      */
       
   264     protected function _addServer($target, $alias)
       
   265     {
       
   266         if ($pos = strpos($target, '://')) {
       
   267             $protocol = substr($target, 0, $pos);
       
   268             $adress = substr($target, $pos + 3);
       
   269         } else {
       
   270             $adress = $target;
       
   271             $protocol = self::DEFAULT_PROTOCOL;
       
   272         }
       
   273 
       
   274         if ($pos = strrpos($adress, ':')) {
       
   275             $posbr = strpos($adress, ']');
       
   276             if ($posbr and ($pos > $posbr)) {
       
   277                 $port = substr($adress, $pos + 1);
       
   278                 $adress = substr($adress, 0, $pos);
       
   279             } else if (!$posbr and $pos) {
       
   280                 $port = substr($adress, $pos + 1);
       
   281                 $adress = substr($adress, 0, $pos);
       
   282             } else {
       
   283                 $port = null;
       
   284             }
       
   285         } else {
       
   286             $port = null;
       
   287         }
       
   288 
       
   289         $protocol = ucfirst(strtolower($protocol));
       
   290         if (!in_array($protocol, $this->_allowedSchemes)) {
       
   291             require_once 'Zend/TimeSync/Exception.php';
       
   292             throw new Zend_TimeSync_Exception("'$protocol' is not a supported protocol");
       
   293         }
       
   294 
       
   295         $className = 'Zend_TimeSync_' . $protocol;
       
   296         if (!class_exists($className)) {
       
   297             require_once 'Zend/Loader.php';
       
   298             Zend_Loader::loadClass($className);
       
   299         }
       
   300         $timeServerObj = new $className($adress, $port);
       
   301 
       
   302         $this->_timeservers[$alias] = $timeServerObj;
       
   303     }
       
   304 }