[ZF-9078] Zend_Measure:
[zend.git] / library / Zend / Measure / Abstract.php
blob4a8b81fab72946e5fa19a33d72a917023d7f884c
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
15 * @category Zend
16 * @package Zend_Measure
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
19 * @version $Id$
22 /**
23 * @see Zend_Locale
25 require_once 'Zend/Locale.php';
27 /**
28 * @see Zend_Locale_Math
30 require_once 'Zend/Locale/Math.php';
32 /**
33 * @see Zend_Locale_Format
35 require_once 'Zend/Locale/Format.php';
37 /**
38 * Abstract class for all measurements
40 * @category Zend
41 * @package Zend_Measure
42 * @subpackage Zend_Measure_Abstract
43 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
44 * @license http://framework.zend.com/license/new-bsd New BSD License
46 abstract class Zend_Measure_Abstract
48 /**
49 * Plain value in standard unit
51 * @var string $_value
53 protected $_value;
55 /**
56 * Original type for this unit
58 * @var string $_type
60 protected $_type;
62 /**
63 * Locale identifier
65 * @var string $_locale
67 protected $_locale = null;
69 /**
70 * Unit types for this measurement
72 protected $_units = array();
74 /**
75 * Zend_Measure_Abstract is an abstract class for the different measurement types
77 * @param $value mixed - Value as string, integer, real or float
78 * @param $type type - OPTIONAL a measure type f.e. Zend_Measure_Length::METER
79 * @param $locale locale - OPTIONAL a Zend_Locale Type
80 * @throws Zend_Measure_Exception
82 public function __construct($value, $type = null, $locale = null)
84 if (($type !== null) and (Zend_Locale::isLocale($type, null, false))) {
85 $locale = $type;
86 $type = null;
89 $this->setLocale($locale);
90 if ($type === null) {
91 $type = $this->_units['STANDARD'];
94 if (isset($this->_units[$type]) === false) {
95 require_once 'Zend/Measure/Exception.php';
96 throw new Zend_Measure_Exception("Type ($type) is unknown");
99 $this->setValue($value, $type, $this->_locale);
103 * Returns the actual set locale
105 * @return string
107 public function getLocale()
109 return $this->_locale;
113 * Sets a new locale for the value representation
115 * @param string|Zend_Locale $locale (Optional) New locale to set
116 * @param boolean $check False, check but don't set; True, set the new locale
117 * @return Zend_Measure_Abstract
119 public function setLocale($locale = null, $check = false)
121 if (empty($locale)) {
122 require_once 'Zend/Registry.php';
123 if (Zend_Registry::isRegistered('Zend_Locale') === true) {
124 $locale = Zend_Registry::get('Zend_Locale');
128 if ($locale === null) {
129 $locale = new Zend_Locale();
132 if (!Zend_Locale::isLocale($locale, true, false)) {
133 if (!Zend_Locale::isLocale($locale, false, false)) {
134 require_once 'Zend/Measure/Exception.php';
135 throw new Zend_Measure_Exception("Language (" . (string) $locale . ") is unknown");
138 $locale = new Zend_Locale($locale);
141 if (!$check) {
142 $this->_locale = (string) $locale;
144 return $this;
148 * Returns the internal value
150 * @param integer $round (Optional) Rounds the value to an given precision,
151 * Default is -1 which returns without rounding
152 * @param string|Zend_Locale $locale (Optional) Locale for number representation
153 * @return integer|string
155 public function getValue($round = -1, $locale = null)
157 if ($round < 0) {
158 $return = $this->_value;
159 } else {
160 $return = Zend_Locale_Math::round($this->_value, $round);
163 if ($locale !== null) {
164 $this->setLocale($locale, true);
165 return Zend_Locale_Format::toNumber($return, array('locale' => $locale));
168 return $return;
172 * Set a new value
174 * @param integer|string $value Value as string, integer, real or float
175 * @param string $type OPTIONAL A measure type f.e. Zend_Measure_Length::METER
176 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing numbers
177 * @throws Zend_Measure_Exception
178 * @return Zend_Measure_Abstract
180 public function setValue($value, $type = null, $locale = null)
182 if (($type !== null) and (Zend_Locale::isLocale($type, null, false))) {
183 $locale = $type;
184 $type = null;
187 if ($locale === null) {
188 $locale = $this->_locale;
191 $this->setLocale($locale, true);
192 if ($type === null) {
193 $type = $this->_units['STANDARD'];
196 if (empty($this->_units[$type])) {
197 require_once 'Zend/Measure/Exception.php';
198 throw new Zend_Measure_Exception("Type ($type) is unknown");
201 try {
202 $value = Zend_Locale_Format::getNumber($value, array('locale' => $locale));
203 } catch(Exception $e) {
204 require_once 'Zend/Measure/Exception.php';
205 throw new Zend_Measure_Exception($e->getMessage(), $e->getCode(), $e);
208 $this->_value = $value;
209 $this->setType($type);
210 return $this;
214 * Returns the original type
216 * @return type
218 public function getType()
220 return $this->_type;
224 * Set a new type, and convert the value
226 * @param string $type New type to set
227 * @throws Zend_Measure_Exception
228 * @return Zend_Measure_Abstract
230 public function setType($type)
232 if (empty($this->_units[$type])) {
233 require_once 'Zend/Measure/Exception.php';
234 throw new Zend_Measure_Exception("Type ($type) is unknown");
237 if (empty($this->_type)) {
238 $this->_type = $type;
239 } else {
240 // Convert to standard value
241 $value = $this->_value;
242 if (is_array($this->_units[$this->getType()][0])) {
243 foreach ($this->_units[$this->getType()][0] as $key => $found) {
244 switch ($key) {
245 case "/":
246 if ($found != 0) {
247 $value = call_user_func(Zend_Locale_Math::$div, $value, $found, 25);
249 break;
250 case "+":
251 $value = call_user_func(Zend_Locale_Math::$add, $value, $found, 25);
252 break;
253 case "-":
254 $value = call_user_func(Zend_Locale_Math::$sub, $value, $found, 25);
255 break;
256 default:
257 $value = call_user_func(Zend_Locale_Math::$mul, $value, $found, 25);
258 break;
261 } else {
262 $value = call_user_func(Zend_Locale_Math::$mul, $value, $this->_units[$this->getType()][0], 25);
265 // Convert to expected value
266 if (is_array($this->_units[$type][0])) {
267 foreach (array_reverse($this->_units[$type][0]) as $key => $found) {
268 switch ($key) {
269 case "/":
270 $value = call_user_func(Zend_Locale_Math::$mul, $value, $found, 25);
271 break;
272 case "+":
273 $value = call_user_func(Zend_Locale_Math::$sub, $value, $found, 25);
274 break;
275 case "-":
276 $value = call_user_func(Zend_Locale_Math::$add, $value, $found, 25);
277 break;
278 default:
279 if ($found != 0) {
280 $value = call_user_func(Zend_Locale_Math::$div, $value, $found, 25);
282 break;
285 } else {
286 $value = call_user_func(Zend_Locale_Math::$div, $value, $this->_units[$type][0], 25);
289 $slength = strlen($value);
290 $length = 0;
291 for($i = 1; $i <= $slength; ++$i) {
292 if ($value[$slength - $i] != '0') {
293 $length = 26 - $i;
294 break;
298 $this->_value = Zend_Locale_Math::round($value, $length);
299 $this->_type = $type;
301 return $this;
305 * Compare if the value and type is equal
307 * @param Zend_Measure_Abstract $object object to compare
308 * @return boolean
310 public function equals($object)
312 if ((string) $object == $this->toString()) {
313 return true;
316 return false;
320 * Returns a string representation
322 * @param integer $round (Optional) Runds the value to an given exception
323 * @param string|Zend_Locale $locale (Optional) Locale to set for the number
324 * @return string
326 public function toString($round = -1, $locale = null)
328 if ($locale === null) {
329 $locale = $this->_locale;
332 return $this->getValue($round, $locale) . ' ' . $this->_units[$this->getType()][1];
336 * Returns a string representation
338 * @return string
340 public function __toString()
342 return $this->toString();
346 * Returns the conversion list
348 * @return array
350 public function getConversionList()
352 return $this->_units;
356 * Alias function for setType returning the converted unit
358 * @param string $type Constant Type
359 * @param integer $round (Optional) Rounds the value to a given precision
360 * @param string|Zend_Locale $locale (Optional) Locale to set for the number
361 * @return string
363 public function convertTo($type, $round = 2, $locale = null)
365 $this->setType($type);
366 return $this->toString($round, $locale);
370 * Adds an unit to another one
372 * @param Zend_Measure_Abstract $object object of same unit type
373 * @return Zend_Measure_Abstract
375 public function add($object)
377 $object->setType($this->getType());
378 $value = $this->getValue(-1) + $object->getValue(-1);
380 $this->setValue($value, $this->getType(), $this->_locale);
381 return $this;
385 * Substracts an unit from another one
387 * @param Zend_Measure_Abstract $object object of same unit type
388 * @return Zend_Measure_Abstract
390 public function sub($object)
392 $object->setType($this->getType());
393 $value = $this->getValue(-1) - $object->getValue(-1);
395 $this->setValue($value, $this->getType(), $this->_locale);
396 return $this;
400 * Compares two units
402 * @param Zend_Measure_Abstract $object object of same unit type
403 * @return boolean
405 public function compare($object)
407 $object->setType($this->getType());
408 $value = $this->getValue(-1) - $object->getValue(-1);
410 if ($value < 0) {
411 return -1;
412 } else if ($value > 0) {
413 return 1;
416 return 0;