PageRenderTime 54ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/Currency.php

https://bitbucket.org/enurkov/prestashop
PHP | 418 lines | 258 code | 55 blank | 105 comment | 37 complexity | 166d556f1deb1f8a226a05ab5a6870ca MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2012 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  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@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2012 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class CurrencyCore extends ObjectModel
  27. {
  28. public $id;
  29. /** @var string Name */
  30. public $name;
  31. /** @var string Iso code */
  32. public $iso_code;
  33. /** @var string Iso code numeric */
  34. public $iso_code_num;
  35. /** @var string Symbol for short display */
  36. public $sign;
  37. /** @var int bool used for displaying blank between sign and price */
  38. public $blank;
  39. /** @var string Conversion rate from euros */
  40. public $conversion_rate;
  41. /** @var boolean True if currency has been deleted (staying in database as deleted) */
  42. public $deleted = 0;
  43. /** @var int ID used for displaying prices */
  44. public $format;
  45. /** @var int bool Display decimals on prices */
  46. public $decimals;
  47. /** @var int bool active */
  48. public $active;
  49. /**
  50. * @see ObjectModel::$definition
  51. */
  52. public static $definition = array(
  53. 'table' => 'currency',
  54. 'primary' => 'id_currency',
  55. 'multilang_shop' => true,
  56. 'fields' => array(
  57. 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32),
  58. 'iso_code' => array('type' => self::TYPE_STRING, 'validate' => 'isLanguageIsoCode', 'required' => true, 'size' => 3),
  59. 'iso_code_num' => array('type' => self::TYPE_STRING, 'validate' => 'isNumericIsoCode', 'size' => 3),
  60. 'blank' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
  61. 'sign' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 8),
  62. 'format' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
  63. 'decimals' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
  64. 'conversion_rate' =>array('type' => self::TYPE_FLOAT, 'validate' => 'isFloat', 'required' => true, 'shop' => true),
  65. 'deleted' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
  66. 'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
  67. ),
  68. );
  69. /** @var array Currency cache */
  70. static protected $currencies = array();
  71. protected $webserviceParameters = array(
  72. 'objectsNodeName' => 'currencies',
  73. );
  74. /**
  75. * contains the sign to display before price, according to its format
  76. * @var string
  77. */
  78. public $prefix = null;
  79. /**
  80. * contains the sign to display after price, according to its format
  81. * @var string
  82. */
  83. public $suffix = null;
  84. public function __construct($id = null, $id_lang = null, $id_shop = null)
  85. {
  86. parent::__construct($id, $id_lang, $id_shop);
  87. // prefix and suffix are convenient shortcut for displaying
  88. // price sign before or after the price number
  89. $this->prefix = $this->format % 2 != 0 ? $this->sign.' ' : '';
  90. $this->suffix = $this->format % 2 == 0 ? ' '.$this->sign : '';
  91. }
  92. /**
  93. * Overriding check if currency with the same iso code already exists.
  94. * If it's true, currency is doesn't added.
  95. *
  96. * @see ObjectModelCore::add()
  97. */
  98. public function add($autodate = true, $nullValues = false)
  99. {
  100. return Currency::exists($this->iso_code, $this->iso_code_num) ? false : parent::add();
  101. }
  102. /**
  103. * Check if a curency already exists.
  104. *
  105. * @param int|string $iso_code int for iso code number string for iso code
  106. * @return boolean
  107. */
  108. public static function exists($iso_code, $iso_code_num, $id_shop = 0)
  109. {
  110. if (is_int($iso_code))
  111. $id_currency_exists = Currency::getIdByIsoCodeNum((int)$iso_code_num, (int)$id_shop);
  112. else
  113. $id_currency_exists = Currency::getIdByIsoCode($iso_code, (int)$id_shop);
  114. if ($id_currency_exists)
  115. return true;
  116. else
  117. return false;
  118. }
  119. public function deleteSelection($selection)
  120. {
  121. if (!is_array($selection))
  122. die(Tools::displayError());
  123. foreach ($selection as $id)
  124. {
  125. $obj = new Currency((int)($id));
  126. $res[$id] = $obj->delete();
  127. }
  128. foreach ($res as $value)
  129. if (!$value)
  130. return false;
  131. return true;
  132. }
  133. public function delete()
  134. {
  135. if ($this->id == Configuration::get('PS_CURRENCY_DEFAULT'))
  136. {
  137. $result = Db::getInstance()->getRow('SELECT `id_currency` FROM '._DB_PREFIX_.'currency WHERE `id_currency` != '.(int)($this->id).' AND `deleted` = 0');
  138. if (!$result['id_currency'])
  139. return false;
  140. Configuration::updateValue('PS_CURRENCY_DEFAULT', $result['id_currency']);
  141. }
  142. $this->deleted = 1;
  143. return $this->update();
  144. }
  145. /**
  146. * Return formated sign
  147. *
  148. * @param string $side left or right
  149. * @return string formated sign
  150. */
  151. public function getSign($side = null)
  152. {
  153. if (!$side)
  154. return $this->sign;
  155. $formated_strings = array(
  156. 'left' => $this->sign.' ',
  157. 'right' => ' '.$this->sign
  158. );
  159. $formats = array(
  160. 1 => array('left' => &$formated_strings['left'], 'right' => ''),
  161. 2 => array('left' => '', 'right' => &$formated_strings['right']),
  162. 3 => array('left' => &$formated_strings['left'], 'right' => ''),
  163. 4 => array('left' => '', 'right' => &$formated_strings['right']),
  164. 5 => array('left' => '', 'right' => &$formated_strings['right'])
  165. );
  166. return ($formats[$this->format][$side]);
  167. }
  168. /**
  169. * Return available currencies
  170. *
  171. * @return array Currencies
  172. */
  173. public static function getCurrencies($object = false, $active = 1)
  174. {
  175. $sql = 'SELECT *
  176. FROM `'._DB_PREFIX_.'currency` c
  177. '.Shop::addSqlAssociation('currency', 'c').'
  178. WHERE `deleted` = 0'
  179. .($active == 1 ? ' AND c.`active` = 1' : '').'
  180. GROUP BY c.id_currency
  181. ORDER BY `name` ASC';
  182. $tab = Db::getInstance()->executeS($sql);
  183. if ($object)
  184. foreach ($tab as $key => $currency)
  185. $tab[$key] = Currency::getCurrencyInstance($currency['id_currency']);
  186. return $tab;
  187. }
  188. public static function getCurrenciesByIdShop($id_shop = 0)
  189. {
  190. $sql = 'SELECT *
  191. FROM `'._DB_PREFIX_.'currency` c
  192. LEFT JOIN `'._DB_PREFIX_.'currency_shop` cs ON (cs.`id_currency` = c.`id_currency`)
  193. '.($id_shop != 0 ? ' WHERE cs.`id_shop` = '.(int)$id_shop : '').'
  194. GROUP BY c.id_currency
  195. ORDER BY `name` ASC';
  196. return Db::getInstance()->executeS($sql);
  197. }
  198. public static function getPaymentCurrenciesSpecial($id_module, $id_shop = null)
  199. {
  200. if (is_null($id_shop))
  201. $id_shop = Context::getContext()->shop->id;
  202. $sql = 'SELECT *
  203. FROM '._DB_PREFIX_.'module_currency
  204. WHERE id_module = '.(int)$id_module.'
  205. AND id_shop ='.(int)$id_shop;
  206. return Db::getInstance()->getRow($sql);
  207. }
  208. public static function getPaymentCurrencies($id_module, $id_shop = null)
  209. {
  210. if (is_null($id_shop))
  211. $id_shop = Context::getContext()->shop->id;
  212. $sql = 'SELECT c.*
  213. FROM `'._DB_PREFIX_.'module_currency` mc
  214. LEFT JOIN `'._DB_PREFIX_.'currency` c ON c.`id_currency` = mc.`id_currency`
  215. WHERE c.`deleted` = 0
  216. AND mc.`id_module` = '.(int)$id_module.'
  217. AND c.`active` = 1
  218. AND mc.id_shop = '.(int)$id_shop.'
  219. ORDER BY c.`name` ASC';
  220. return Db::getInstance()->executeS($sql);
  221. }
  222. public static function checkPaymentCurrencies($id_module, $id_shop = null)
  223. {
  224. if (empty($id_module))
  225. return false;
  226. if (is_null($id_shop))
  227. $id_shop = Context::getContext()->shop->id;
  228. $sql = 'SELECT *
  229. FROM `'._DB_PREFIX_.'module_currency`
  230. WHERE `id_module` = '.(int)$id_module.'
  231. AND `id_shop` = '.(int)$id_shop;
  232. return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
  233. }
  234. public static function getCurrency($id_currency)
  235. {
  236. return Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
  237. SELECT *
  238. FROM `'._DB_PREFIX_.'currency`
  239. WHERE `deleted` = 0
  240. AND `id_currency` = '.(int)($id_currency));
  241. }
  242. /**
  243. * @static
  244. * @param $iso_code
  245. * @param int $id_shop
  246. * @return int
  247. */
  248. public static function getIdByIsoCode($iso_code, $id_shop = 0)
  249. {
  250. $query = Currency::getIdByQuery($id_shop);
  251. $query->where('iso_code = \''.pSQL($iso_code).'\'');
  252. return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query->build());
  253. }
  254. /**
  255. * @static
  256. * @param $iso_code
  257. * @param int $id_shop
  258. * @return int
  259. */
  260. public static function getIdByIsoCodeNum($iso_code_num, $id_shop = 0)
  261. {
  262. $query = Currency::getIdByQuery($id_shop);
  263. $query->where('iso_code_num = \''.pSQL($iso_code_num).'\'');
  264. return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query->build());
  265. }
  266. /**
  267. * @static
  268. * @param int $id_shop
  269. * @return DbQuery
  270. */
  271. public static function getIdByQuery($id_shop = 0)
  272. {
  273. $query = new DbQuery();
  274. $query->select('c.id_currency');
  275. $query->from('currency', 'c');
  276. $query->where('deleted = 0');
  277. if (Shop::isFeatureActive() && $id_shop > 0)
  278. {
  279. $query->leftJoin('currency_shop', 'cs', 'cs.id_currency = c.id_currency');
  280. $query->where('id_shop = '.(int)$id_shop);
  281. }
  282. return $query;
  283. }
  284. /**
  285. * Refresh the currency conversion rate
  286. * The XML file define conversion rate for each from a default currency ($isoCodeSource).
  287. *
  288. * @param $data XML content which contains all the conversion rates
  289. * @param $isoCodeSource The default currency used in the XML file
  290. * @param $defaultCurrency The default currency object
  291. */
  292. public function refreshCurrency($data, $isoCodeSource, $defaultCurrency)
  293. {
  294. // fetch the conversion rate of the default currency
  295. $conversion_rate = 1;
  296. if ($defaultCurrency->iso_code != $isoCodeSource)
  297. {
  298. foreach ($data->currency as $currency)
  299. if ($currency['iso_code'] == $defaultCurrency->iso_code)
  300. {
  301. $conversion_rate = round((float)$currency['rate'], 6);
  302. break;
  303. }
  304. }
  305. if ($defaultCurrency->iso_code == $this->iso_code)
  306. $this->conversion_rate = 1;
  307. else
  308. {
  309. if ($this->iso_code == $isoCodeSource)
  310. $rate = 1;
  311. else
  312. {
  313. foreach ($data->currency as $obj)
  314. if ($this->iso_code == strval($obj['iso_code']))
  315. {
  316. $rate = (float)$obj['rate'];
  317. break;
  318. }
  319. }
  320. if (isset($rate))
  321. $this->conversion_rate = round($rate / $conversion_rate, 6);
  322. }
  323. $this->update();
  324. }
  325. public static function getDefaultCurrency()
  326. {
  327. $id_currency = (int)Configuration::get('PS_CURRENCY_DEFAULT');
  328. if ($id_currency == 0)
  329. return false;
  330. return new Currency($id_currency);
  331. }
  332. public static function refreshCurrencies()
  333. {
  334. // Parse
  335. if (!$feed = Tools::simplexml_load_file('http://api.prestashop.com/xml/currencies.xml'))
  336. return Tools::displayError('Cannot parse feed.');
  337. // Default feed currency (EUR)
  338. $isoCodeSource = strval($feed->source['iso_code']);
  339. if (!$default_currency = Currency::getDefaultCurrency())
  340. return Tools::displayError('No default currency');
  341. $currencies = Currency::getCurrencies(true, false);
  342. foreach ($currencies as $currency)
  343. if ($currency->id != $default_currency->id)
  344. $currency->refreshCurrency($feed->list, $isoCodeSource, $default_currency);
  345. }
  346. /**
  347. * Get current currency
  348. *
  349. * @deprecated as of 1.5 use $context->currency instead
  350. * @return Currency
  351. */
  352. public static function getCurrent()
  353. {
  354. Tools::displayAsDeprecated();
  355. return Context::getContext()->currency;
  356. }
  357. public static function getCurrencyInstance($id)
  358. {
  359. if (!isset(self::$currencies[$id]))
  360. self::$currencies[(int)($id)] = new Currency($id);
  361. return self::$currencies[(int)($id)];
  362. }
  363. }