PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Measure/AbstractMeasure.php

https://github.com/Exercise/zf2
PHP | 407 lines | 212 code | 44 blank | 151 comment | 38 complexity | f43cac248a36c4dc5eeca4fb41f09fd8 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  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.
  14. *
  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$
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\Measure;
  25. use Zend\Registry;
  26. use Zend\Locale;
  27. use Zend\Locale\Math;
  28. /**
  29. * Abstract class for all measurements
  30. *
  31. * @uses Zend\Locale\Locale
  32. * @uses Zend\Locale\Locale\Math
  33. * @uses Zend\Registry
  34. * @category Zend
  35. * @package Zend_Measure
  36. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  37. * @license http://framework.zend.com/license/new-bsd New BSD License
  38. */
  39. abstract class AbstractMeasure
  40. {
  41. /**
  42. * Plain value in standard unit
  43. *
  44. * @var string $_value
  45. */
  46. protected $_value;
  47. /**
  48. * Original type for this unit
  49. *
  50. * @var string $_type
  51. */
  52. protected $_type;
  53. /**
  54. * Locale identifier
  55. *
  56. * @var string $_locale
  57. */
  58. protected $_locale = null;
  59. /**
  60. * Unit types for this measurement
  61. */
  62. protected $_units = array();
  63. /**
  64. * Zend\Measure\MeasureAbstract is an abstract class for the different measurement types
  65. *
  66. * @param $value mixed - Value as string, integer, real or float
  67. * @param $type type - OPTIONAL a measure type f.e. Zend\Measure\Length::METER
  68. * @param $locale locale - OPTIONAL a Zend\Zend\Locale Type
  69. * @throws Zend\Measure\Exception
  70. */
  71. public function __construct($value, $type = null, $locale = null)
  72. {
  73. if (($type !== null) and (Locale\Locale::isLocale($type, null, false))) {
  74. $locale = $type;
  75. $type = null;
  76. }
  77. $this->setLocale($locale);
  78. if ($type === null) {
  79. $type = $this->_units['STANDARD'];
  80. }
  81. if (isset($this->_units[$type]) === false) {
  82. throw new Exception("Type ($type) is unknown");
  83. }
  84. $this->setValue($value, $type, $this->_locale);
  85. }
  86. /**
  87. * Returns the actual set locale
  88. *
  89. * @return string
  90. */
  91. public function getLocale()
  92. {
  93. return $this->_locale;
  94. }
  95. /**
  96. * Sets a new locale for the value representation
  97. *
  98. * @param string|Zend\Locale\Locale $locale (Optional) New locale to set
  99. * @param boolean $check False, check but don't set; True, set the new locale
  100. * @return Zend\Measure\AbstractMeasure
  101. */
  102. public function setLocale($locale = null, $check = false)
  103. {
  104. if (empty($locale)) {
  105. if (Registry::isRegistered('Zend_Locale') === true) {
  106. $locale = Registry::get('Zend_Locale');
  107. }
  108. }
  109. if ($locale === null) {
  110. $locale = new Locale\Locale();
  111. }
  112. if (!Locale\Locale::isLocale($locale, true, false)) {
  113. if (!Locale\Locale::isLocale($locale, false, false)) {
  114. throw new Exception("Language (" . (string) $locale . ") is unknown");
  115. }
  116. $locale = new Locale\Locale($locale);
  117. }
  118. if (!$check) {
  119. $this->_locale = (string) $locale;
  120. }
  121. return $this;
  122. }
  123. /**
  124. * Returns the internal value
  125. *
  126. * @param integer $round (Optional) Rounds the value to an given precision,
  127. * Default is -1 which returns without rounding
  128. * @param string|Zend\Locale\Locale $locale (Optional) Locale for number representation
  129. * @return integer|string
  130. */
  131. public function getValue($round = -1, $locale = null)
  132. {
  133. if ($round < 0) {
  134. $return = $this->_value;
  135. } else {
  136. $return = Math::round($this->_value, $round);
  137. }
  138. if ($locale !== null) {
  139. $this->setLocale($locale, true);
  140. return Locale\Format::toNumber($return, array('locale' => $locale));
  141. }
  142. return $return;
  143. }
  144. /**
  145. * Set a new value
  146. *
  147. * @param integer|string $value Value as string, integer, real or float
  148. * @param string $type OPTIONAL A measure type f.e. Zend_Measure_Length::METER
  149. * @param string|Zend\Locale\Locale $locale OPTIONAL Locale for parsing numbers
  150. * @throws Zend\Measure\Exception
  151. * @return Zend\Measure\AbstractMeasure
  152. */
  153. public function setValue($value, $type = null, $locale = null)
  154. {
  155. if (($type !== null) and (Locale\Locale::isLocale($type, null, false))) {
  156. $locale = $type;
  157. $type = null;
  158. }
  159. if ($locale === null) {
  160. $locale = $this->_locale;
  161. }
  162. $this->setLocale($locale, true);
  163. if ($type === null) {
  164. $type = $this->_units['STANDARD'];
  165. }
  166. if (empty($this->_units[$type])) {
  167. throw new Exception("Type ($type) is unknown");
  168. }
  169. try {
  170. $value = Locale\Format::getNumber($value, array('locale' => $locale));
  171. } catch(\Exception $e) {
  172. throw new Exception($e->getMessage(), $e->getCode(), $e);
  173. }
  174. $this->_value = $value;
  175. $this->setType($type);
  176. return $this;
  177. }
  178. /**
  179. * Returns the original type
  180. *
  181. * @return type
  182. */
  183. public function getType()
  184. {
  185. return $this->_type;
  186. }
  187. /**
  188. * Set a new type, and convert the value
  189. *
  190. * @param string $type New type to set
  191. * @throws Zend\Measure\Exception
  192. * @return Zend\Measure\AbstractMeasure
  193. */
  194. public function setType($type)
  195. {
  196. if (empty($this->_units[$type])) {
  197. throw new Exception("Type ($type) is unknown");
  198. }
  199. if (empty($this->_type)) {
  200. $this->_type = $type;
  201. } else {
  202. // Convert to standard value
  203. $value = $this->_value;
  204. if (is_array($this->_units[$this->getType()][0])) {
  205. foreach ($this->_units[$this->getType()][0] as $key => $found) {
  206. switch ($key) {
  207. case "/":
  208. if ($found != 0) {
  209. $value = call_user_func(Math::$div, $value, $found, 25);
  210. }
  211. break;
  212. case "+":
  213. $value = call_user_func(Math::$add, $value, $found, 25);
  214. break;
  215. case "-":
  216. $value = call_user_func(Math::$sub, $value, $found, 25);
  217. break;
  218. default:
  219. $value = call_user_func(Math::$mul, $value, $found, 25);
  220. break;
  221. }
  222. }
  223. } else {
  224. $value = call_user_func(Math::$mul, $value, $this->_units[$this->getType()][0], 25);
  225. }
  226. // Convert to expected value
  227. if (is_array($this->_units[$type][0])) {
  228. foreach (array_reverse($this->_units[$type][0]) as $key => $found) {
  229. switch ($key) {
  230. case "/":
  231. $value = call_user_func(Math::$mul, $value, $found, 25);
  232. break;
  233. case "+":
  234. $value = call_user_func(Math::$sub, $value, $found, 25);
  235. break;
  236. case "-":
  237. $value = call_user_func(Math::$add, $value, $found, 25);
  238. break;
  239. default:
  240. if ($found != 0) {
  241. $value = call_user_func(Math::$div, $value, $found, 25);
  242. }
  243. break;
  244. }
  245. }
  246. } else {
  247. $value = call_user_func(Math::$div, $value, $this->_units[$type][0], 25);
  248. }
  249. $slength = strlen($value);
  250. $length = 0;
  251. for($i = 1; $i <= $slength; ++$i) {
  252. if ($value[$slength - $i] != '0') {
  253. $length = 26 - $i;
  254. break;
  255. }
  256. }
  257. $this->_value = Math::round($value, $length);
  258. $this->_type = $type;
  259. }
  260. return $this;
  261. }
  262. /**
  263. * Compare if the value and type is equal
  264. *
  265. * @param Zend\Measure\AbstractMeasure $object object to compare
  266. * @return boolean
  267. */
  268. public function equals($object)
  269. {
  270. if ((string) $object == $this->toString()) {
  271. return true;
  272. }
  273. return false;
  274. }
  275. /**
  276. * Returns a string representation
  277. *
  278. * @param integer $round (Optional) Runds the value to an given exception
  279. * @param string|Zend\Locale\Locale $locale (Optional) Locale to set for the number
  280. * @return string
  281. */
  282. public function toString($round = -1, $locale = null)
  283. {
  284. if ($locale === null) {
  285. $locale = $this->_locale;
  286. }
  287. return $this->getValue($round, $locale) . ' ' . $this->_units[$this->getType()][1];
  288. }
  289. /**
  290. * Returns a string representation
  291. *
  292. * @return string
  293. */
  294. public function __toString()
  295. {
  296. return $this->toString();
  297. }
  298. /**
  299. * Returns the conversion list
  300. *
  301. * @return array
  302. */
  303. public function getConversionList()
  304. {
  305. return $this->_units;
  306. }
  307. /**
  308. * Alias function for setType returning the converted unit
  309. *
  310. * @param string $type Constant Type
  311. * @param integer $round (Optional) Rounds the value to a given precision
  312. * @param string|Zend\Locale\Locale $locale (Optional) Locale to set for the number
  313. * @return string
  314. */
  315. public function convertTo($type, $round = 2, $locale = null)
  316. {
  317. $this->setType($type);
  318. return $this->toString($round, $locale);
  319. }
  320. /**
  321. * Adds an unit to another one
  322. *
  323. * @param Zend\Measure\AbstractMeasure $object object of same unit type
  324. * @return Zend\Measure\AbstractMeasure
  325. */
  326. public function add($object)
  327. {
  328. $object->setType($this->getType());
  329. $value = $this->getValue(-1) + $object->getValue(-1);
  330. $this->setValue($value, $this->getType(), $this->_locale);
  331. return $this;
  332. }
  333. /**
  334. * Substracts an unit from another one
  335. *
  336. * @param Zend\Measure\AbstractMeasure $object object of same unit type
  337. * @return Zend\Measure\AbstractMeasure
  338. */
  339. public function sub($object)
  340. {
  341. $object->setType($this->getType());
  342. $value = $this->getValue(-1) - $object->getValue(-1);
  343. $this->setValue($value, $this->getType(), $this->_locale);
  344. return $this;
  345. }
  346. /**
  347. * Compares two units
  348. *
  349. * @param Zend\Measure\AbstractMeasure $object object of same unit type
  350. * @return boolean
  351. */
  352. public function compare($object)
  353. {
  354. $object->setType($this->getType());
  355. $value = $this->getValue(-1) - $object->getValue(-1);
  356. if ($value < 0) {
  357. return -1;
  358. } else if ($value > 0) {
  359. return 1;
  360. }
  361. return 0;
  362. }
  363. }