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.
17 * @package Zend_TimeSync
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
20 * @license http://framework.zend.com/license/new-bsd New BSD License
26 require_once 'Zend/Date.php';
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
34 class Zend_TimeSync
implements IteratorAggregate
37 * Set the default timeserver protocol to "Ntp". This will be called
38 * when no protocol is specified
40 const DEFAULT_PROTOCOL
= 'Ntp';
43 * Contains array of timeserver objects
47 protected $_timeservers = array();
50 * Holds a reference to the timeserver that is currently being used
57 * Allowed timeserver schemes
61 protected $_allowedSchemes = array(
67 * Configuration array, set using the constructor or using
68 * ::setOptions() or ::setOption()
72 public static $options = array(
77 * Zend_TimeSync constructor
79 * @param string|array $target - OPTIONAL single timeserver, or an array of timeservers.
80 * @param string $alias - OPTIONAL an alias for this timeserver
83 public function __construct($target = null, $alias = null)
85 if ($target !== null) {
86 $this->addServer($target, $alias);
91 * getIterator() - return an iteratable object for use in foreach and the like,
92 * this completes the IteratorAggregate interface
96 public function getIterator()
98 return new ArrayObject($this->_timeservers
);
102 * Add a timeserver or multiple timeservers
104 * Server should be a single string representation of a timeserver,
105 * or a structured array listing multiple timeservers.
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:
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'
120 * If no port number has been suplied, the default matching port
121 * number will be used.
123 * Supported protocols are:
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
131 public function addServer($target, $alias = null)
133 if (is_array($target)) {
134 foreach ($target as $key => $server) {
135 $this->_addServer($server, $key);
138 $this->_addServer($target, $alias);
143 * Sets the value for the given options
145 * This will replace any currently defined options.
147 * @param array $options - An array of options to be set
149 public static function setOptions(array $options)
151 foreach ($options as $key => $value) {
152 Zend_TimeSync
::$options[$key] = $value;
157 * Marks a nameserver as current
159 * @param string|integer $alias - The alias from the timeserver to set as current
160 * @throws Zend_TimeSync_Exception
162 public function setServer($alias)
164 if (isset($this->_timeservers
[$alias]) === true) {
165 $this->_current
= $this->_timeservers
[$alias];
167 require_once 'Zend/TimeSync/Exception.php';
168 throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver");
173 * Returns the value to the option
175 * @param string $key - The option's identifier
177 * @throws Zend_TimeSync_Exception
179 public static function getOptions($key = null)
182 return Zend_TimeSync
::$options;
185 if (isset(Zend_TimeSync
::$options[$key]) === true) {
186 return Zend_TimeSync
::$options[$key];
188 require_once 'Zend/TimeSync/Exception.php';
189 throw new Zend_TimeSync_Exception("'$key' does not point to valid option");
194 * Return a specified timeserver by alias
195 * If no alias is given it will return the current timeserver
197 * @param string|integer $alias - The alias from the timeserver to return
199 * @throws Zend_TimeSync_Exception
201 public function getServer($alias = null)
203 if ($alias === null) {
204 if (isset($this->_current
) && $this->_current
!== false) {
205 return $this->_current
;
207 require_once 'Zend/TimeSync/Exception.php';
208 throw new Zend_TimeSync_Exception('there is no timeserver set');
211 if (isset($this->_timeservers
[$alias]) === true) {
212 return $this->_timeservers
[$alias];
214 require_once 'Zend/TimeSync/Exception.php';
215 throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver");
220 * Returns information sent/returned from the current timeserver
224 public function getInfo()
226 return $this->getServer()->getInfo();
230 * Query the timeserver list using the fallback mechanism
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.
236 * @param $locale - OPTIONAL locale
238 * @throws Zend_TimeSync_Exception
240 public function getDate($locale = null)
242 require_once 'Zend/TimeSync/Exception.php';
243 foreach ($this->_timeservers
as $alias => $server) {
244 $this->_current
= $server;
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');
251 $masterException->addException($e);
255 throw $masterException;
259 * Adds a timeserver object to the timeserver list
261 * @param string|array $target - Single timeserver, or an array of timeservers.
262 * @param string $alias - An alias for this timeserver
264 protected function _addServer($target, $alias)
266 if ($pos = strpos($target, '://')) {
267 $protocol = substr($target, 0, $pos);
268 $adress = substr($target, $pos +
3);
271 $protocol = self
::DEFAULT_PROTOCOL
;
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);
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");
295 $className = 'Zend_TimeSync_' . $protocol;
296 if (!class_exists($className)) {
297 require_once 'Zend/Loader.php';
298 Zend_Loader
::loadClass($className);
300 $timeServerObj = new $className($adress, $port);
302 $this->_timeservers
[$alias] = $timeServerObj;