Bitrix-D7  20.5.0
currencymanager.php
См. документацию.
1 <?php
2 namespace Bitrix\Currency;
3 
4 use Bitrix\Main;
10 
11 Loc::loadMessages(__FILE__);
12 
13 /**
14  * Class CurrencyTable
15  *
16  * @package Bitrix\Currency
17  **/
19 {
20  const CACHE_BASE_CURRENCY_ID = 'currency_base_currency';
21  const CACHE_CURRENCY_LIST_ID = 'currency_currency_list';
22  const CACHE_CURRENCY_SHORT_LIST_ID = 'currency_short_list_';
23  const CACHE_CURRENCY_SYMBOL_LIST_ID = 'currency_symbol_list_';
24  const CACHE_CURRENCY_NAME_LIST_ID = 'currency_name_list_';
25 
26  const EVENT_ON_AFTER_UPDATE_BASE_RATE = 'onAfterUpdateCurrencyBaseRate';
27  const EVENT_ON_UPDATE_BASE_CURRENCY = 'onUpdateBaseCurrency';
28  const EVENT_ON_AFTER_UPDATE_BASE_CURRENCY = 'onAfterUpdateBaseCurrency';
29 
30  protected static $baseCurrency = '';
31 
32  /**
33  * Check currency id.
34  *
35  * @param string $currency Currency id.
36  * @return bool|string
37  */
38  public static function checkCurrencyID($currency)
39  {
40  $currency = (string)$currency;
41  return ($currency === '' || mb_strlen($currency) > 3 ? false : $currency);
42  }
43 
44  /**
45  * Check language id.
46  *
47  * @param string $language Language.
48  * @return bool|string
49  */
50  public static function checkLanguage($language)
51  {
52  $language = (string)$language;
53  return ($language === '' || mb_strlen($language) > 2 ? false : $language);
54  }
55 
56  /**
57  * Return base currency.
58  *
59  * @return string
60  */
61  public static function getBaseCurrency()
62  {
63  if (self::$baseCurrency === '')
64  {
65  /** @var \Bitrix\Main\Data\ManagedCache $managedCache */
66  $skipCache = (defined('CURRENCY_SKIP_CACHE') && CURRENCY_SKIP_CACHE);
67  $currencyFound = false;
68  $currencyFromCache = false;
69  if (!$skipCache)
70  {
71  $cacheTime = (int)(defined('CURRENCY_CACHE_TIME') ? CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME);
72  $managedCache = Application::getInstance()->getManagedCache();
73  $currencyFromCache = $managedCache->read($cacheTime, self::CACHE_BASE_CURRENCY_ID, CurrencyTable::getTableName());
74  if ($currencyFromCache)
75  {
76  $currencyFound = true;
77  self::$baseCurrency = (string)$managedCache->get(self::CACHE_BASE_CURRENCY_ID);
78  }
79  }
80  if ($skipCache || !$currencyFound)
81  {
82  $currencyIterator = CurrencyTable::getList(array(
83  'select' => array('CURRENCY'),
84  'filter' => array('=BASE' => 'Y', '=AMOUNT' => 1)
85  ));
86  if ($currency = $currencyIterator->fetch())
87  {
88  $currencyFound = true;
89  self::$baseCurrency = $currency['CURRENCY'];
90  }
91  unset($currency, $currencyIterator);
92  }
93  if (!$skipCache && $currencyFound && !$currencyFromCache)
94  {
95  $managedCache->set(self::CACHE_BASE_CURRENCY_ID, self::$baseCurrency);
96  }
97  }
98  return self::$baseCurrency;
99  }
100 
101  /**
102  * Return currency short list.
103  *
104  * @return array
105  * @throws \Bitrix\Main\ArgumentException
106  */
107  public static function getCurrencyList()
108  {
109  $currencyTableName = CurrencyTable::getTableName();
110  $managedCache = Application::getInstance()->getManagedCache();
111 
112  $cacheTime = (int)(defined('CURRENCY_CACHE_TIME') ? CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME);
113  $cacheId = self::CACHE_CURRENCY_SHORT_LIST_ID.LANGUAGE_ID;
114 
115  if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
116  {
117  $currencyList = $managedCache->get($cacheId);
118  }
119  else
120  {
121  $currencyList = array();
122  $currencyIterator = CurrencyTable::getList(array(
123  'select' => array('CURRENCY', 'FULL_NAME' => 'CURRENT_LANG_FORMAT.FULL_NAME', 'SORT'),
124  'order' => array('SORT' => 'ASC', 'CURRENCY' => 'ASC')
125  ));
126  while ($currency = $currencyIterator->fetch())
127  {
128  $currency['FULL_NAME'] = (string)$currency['FULL_NAME'];
129  $currencyList[$currency['CURRENCY']] = $currency['CURRENCY'].($currency['FULL_NAME'] != '' ? ' ('.$currency['FULL_NAME'].')' : '');
130  }
131  unset($currency, $currencyIterator);
132  $managedCache->set($cacheId, $currencyList);
133  }
134  return $currencyList;
135  }
136 
137  /**
138  * Returns currency symbol list.
139  *
140  * @return array
141  * @throws \Bitrix\Main\ArgumentException
142  */
143  public static function getSymbolList(): array
144  {
145  $currencyTableName = CurrencyTable::getTableName();
146  $managedCache = Application::getInstance()->getManagedCache();
147 
148  $cacheTime = defined('CURRENCY_CACHE_TIME') ? (int)CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME;
149  $cacheId = self::CACHE_CURRENCY_SYMBOL_LIST_ID.LANGUAGE_ID;
150 
151  if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
152  {
153  $currencyList = $managedCache->get($cacheId);
154  }
155  else
156  {
157  $currencyList = [];
158  $currencyIterator = CurrencyTable::getList([
159  'select' => [
160  'CURRENCY',
161  'FORMAT_STRING' => 'CURRENT_LANG_FORMAT.FORMAT_STRING',
162  'SORT'
163  ],
164  'order' => [
165  'SORT' => 'ASC',
166  'CURRENCY' => 'ASC'
167  ]
168  ]);
169  while ($currency = $currencyIterator->fetch())
170  {
171  $currencyFormat = (string)$currency['FORMAT_STRING'];
172 
173  if ($currencyFormat !== '')
174  {
175  $symbol = \CCurrencyLang::applyTemplate('', $currencyFormat);
176  if (is_string($symbol))
177  {
178  $symbol = trim($symbol);
179  if ($symbol !== '')
180  {
181  $currencyList[$currency['CURRENCY']] = $symbol;
182  }
183  }
184  }
185  }
186 
187  $managedCache->set($cacheId, $currencyList);
188  }
189 
190  return $currencyList;
191  }
192 
193  /**
194  * Returns currency name list.
195  *
196  * @return array
197  * @throws \Bitrix\Main\ArgumentException
198  */
199  public static function getNameList(): array
200  {
201  $currencyTableName = CurrencyTable::getTableName();
202  $managedCache = Application::getInstance()->getManagedCache();
203 
204  $cacheTime = defined('CURRENCY_CACHE_TIME') ? (int)CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME;
205  $cacheId = self::CACHE_CURRENCY_NAME_LIST_ID.LANGUAGE_ID;
206 
207  if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
208  {
209  $currencyList = $managedCache->get($cacheId);
210  }
211  else
212  {
213  $currencyList = [];
214  $currencyIterator = CurrencyTable::getList([
215  'select' => [
216  'CURRENCY',
217  'FULL_NAME' => 'CURRENT_LANG_FORMAT.FULL_NAME',
218  'SORT'
219  ],
220  'order' => [
221  'SORT' => 'ASC',
222  'CURRENCY' => 'ASC'
223  ]
224  ]);
225  while ($currency = $currencyIterator->fetch())
226  {
227  $fullName = (string)$currency['FULL_NAME'];
228  if ($fullName === '')
229  {
230  $fullName = $currency['CURRENCY'];
231  }
232 
233  $currencyList[$currency['CURRENCY']] = $fullName;
234  }
235 
236  $managedCache->set($cacheId, $currencyList);
237  }
238 
239  return $currencyList;
240  }
241 
242  /**
243  * Verifying the existence of the currency by its code.
244  *
245  * @param string $currency Currency code.
246  * @return bool
247  */
248  public static function isCurrencyExist($currency)
249  {
250  $currency = static::checkCurrencyID($currency);
251  if ($currency === false)
252  return false;
253  $currencyList = static::getCurrencyList();
254  return isset($currencyList[$currency]);
255  }
256 
257  /**
258  * Return currency list, create to install module.
259  *
260  * @return array
261  */
262  public static function getInstalledCurrencies()
263  {
264  $installedCurrencies = (string)Option::get('currency', 'installed_currencies');
265  if ($installedCurrencies === '')
266  {
267  $bitrix24 = Main\ModuleManager::isModuleInstalled('bitrix24');
268 
269  $languageID = '';
270  $siteIterator = Main\SiteTable::getList(array(
271  'select' => array('LID', 'LANGUAGE_ID'),
272  'filter' => array('=DEF' => 'Y', '=ACTIVE' => 'Y')
273  ));
274  if ($site = $siteIterator->fetch())
275  $languageID = (string)$site['LANGUAGE_ID'];
276  unset($site, $siteIterator);
277 
278  if ($languageID == '')
279  $languageID = 'en';
280 
281  if (!$bitrix24 && $languageID == 'ru')
282  {
283  $languageList = array();
284  $languageIterator = LanguageTable::getList(array(
285  'select' => array('ID'),
286  'filter' => array('@ID' => array('kz', 'by', 'ua'), '=ACTIVE' => 'Y')
287  ));
288  while ($language = $languageIterator->fetch())
289  $languageList[$language['ID']] = $language['ID'];
290  unset($language, $languageIterator);
291  if (isset($languageList['kz']))
292  $languageID = 'kz';
293  elseif (isset($languageList['by']))
294  $languageID = 'by';
295  elseif (isset($languageList['ua']))
296  $languageID = 'ua';
297  unset($languageList);
298  }
299  unset($bitrix24);
300 
301  switch ($languageID)
302  {
303  case 'br':
304  $currencyList = array('BYN', 'RUB', 'USD', 'EUR');
305  break;
306  case 'ua':
307  $currencyList = array('UAH', 'RUB', 'USD', 'EUR');
308  break;
309  case 'kz':
310  $currencyList = array('KZT', 'RUB', 'USD', 'EUR');
311  break;
312  case 'ru':
313  $currencyList = array('RUB', 'USD', 'EUR', 'UAH', 'BYN');
314  break;
315  case 'de':
316  case 'en':
317  case 'tc':
318  case 'sc':
319  case 'la':
320  default:
321  $currencyList = array('USD', 'EUR', 'CNY', 'BRL', 'INR');
322  break;
323  }
324 
325  Option::set('currency', 'installed_currencies', implode(',', $currencyList), '');
326  return $currencyList;
327  }
328  else
329  {
330  return explode(',', $installedCurrencies);
331  }
332  }
333 
334  /**
335  * Clear currency cache.
336  *
337  * @param string $language Language id.
338  * @return void
339  */
340  public static function clearCurrencyCache($language = '')
341  {
342  $language = static::checkLanguage($language);
343  $currencyTableName = CurrencyTable::getTableName();
344 
345  $managedCache = Application::getInstance()->getManagedCache();
346  $managedCache->clean(self::CACHE_CURRENCY_LIST_ID, $currencyTableName);
347  if (empty($language))
348  {
349  $languageIterator = LanguageTable::getList(array(
350  'select' => array('ID')
351  ));
352  while ($oneLanguage = $languageIterator->fetch())
353  {
354  $managedCache->clean(self::CACHE_CURRENCY_LIST_ID.'_'.$oneLanguage['ID'], $currencyTableName);
355  $managedCache->clean(self::CACHE_CURRENCY_SHORT_LIST_ID.$oneLanguage['ID'], $currencyTableName);
356  $managedCache->clean(self::CACHE_CURRENCY_SYMBOL_LIST_ID.$oneLanguage['ID'], $currencyTableName);
357  $managedCache->clean(self::CACHE_CURRENCY_NAME_LIST_ID.$oneLanguage['ID'], $currencyTableName);
358  }
359  unset($oneLanguage, $languageIterator);
360  }
361  else
362  {
363  $managedCache->clean(self::CACHE_CURRENCY_LIST_ID.'_'.$language, $currencyTableName);
364  $managedCache->clean(self::CACHE_CURRENCY_SHORT_LIST_ID.$language, $currencyTableName);
365  $managedCache->clean(self::CACHE_CURRENCY_SYMBOL_LIST_ID.$language, $currencyTableName);
366  $managedCache->clean(self::CACHE_CURRENCY_NAME_LIST_ID.$language, $currencyTableName);
367  }
368  $managedCache->clean(self::CACHE_BASE_CURRENCY_ID, $currencyTableName);
369 
370  /** @global \CStackCacheManager $stackCacheManager */
371  global $stackCacheManager;
372  $stackCacheManager->clear('currency_rate');
373  $stackCacheManager->clear('currency_currency_lang');
374  }
375 
376  /**
377  * Clear tag currency cache.
378  *
379  * @param string $currency Currency id.
380  * @return void
381  */
382  public static function clearTagCache($currency)
383  {
384  if (!defined('BX_COMP_MANAGED_CACHE'))
385  return;
386  $currency = static::checkCurrencyID($currency);
387  if ($currency === false)
388  return;
389  Application::getInstance()->getTaggedCache()->clearByTag('currency_id_'.$currency);
390  }
391 
392  /**
393  * Agent for update current currencies rates to base currency.
394  *
395  * @return string
396  */
397  public static function currencyBaseRateAgent()
398  {
399  static::updateBaseRates();
400  return '\Bitrix\Currency\CurrencyManager::currencyBaseRateAgent();';
401  }
402 
403  /**
404  * Update current currencies rates to base currency.
405  *
406  * @param string $updateCurrency Update currency id.
407  * @return void
408  * @throws Main\ArgumentException
409  * @throws \Exception
410  */
411  public static function updateBaseRates($updateCurrency = '')
412  {
413  $currency = (string)static::getBaseCurrency();
414  if ($currency === '')
415  return;
416 
417  $currencyIterator = CurrencyTable::getList(array(
418  'select' => array('CURRENCY', 'CURRENT_BASE_RATE'),
419  'filter' => ($updateCurrency == '' ? array() : array('=CURRENCY' => $updateCurrency))
420  ));
421  while ($existCurrency = $currencyIterator->fetch())
422  {
423  $baseRate = ($existCurrency['CURRENCY'] != $currency
424  ? \CCurrencyRates::getConvertFactorEx($existCurrency['CURRENCY'], $currency)
425  : 1
426  );
427  $updateResult = CurrencyTable::update($existCurrency['CURRENCY'], array('CURRENT_BASE_RATE' => $baseRate));
428  if ($updateResult->isSuccess())
429  {
430  $event = new Main\Event(
431  'currency',
432  self::EVENT_ON_AFTER_UPDATE_BASE_RATE,
433  array(
434  'OLD_BASE_RATE' => (float)$existCurrency['CURRENT_BASE_RATE'],
435  'CURRENT_BASE_RATE' => $baseRate,
436  'BASE_CURRENCY' => $currency,
437  'CURRENCY' => $existCurrency['CURRENCY']
438  )
439  );
440  $event->send();
441  }
442  unset($updateResult);
443  unset($baseRate);
444  }
445  unset($existCurrency, $currencyIterator);
446  }
447 
448  /**
449  * Update base currency.
450  *
451  * @param string $currency Currency id.
452  * @return bool
453  */
454  public static function updateBaseCurrency($currency)
455  {
456  /** @global \CUser $USER */
457  global $USER;
458  $currency = CurrencyManager::checkCurrencyID($currency);
459  if ($currency === false)
460  return false;
461 
462  $event = new Main\Event(
463  'currency',
464  self::EVENT_ON_UPDATE_BASE_CURRENCY,
465  array(
466  'NEW_BASE_CURRENCY' => $currency
467  )
468  );
469  $event->send();
470  unset($event);
471 
473  $helper = $conn->getSqlHelper();
474 
475  $userID = (isset($USER) && $USER instanceof \CUser ? (int)$USER->getID() : 0);
476 
477  $tableName = $helper->quote(CurrencyTable::getTableName());
478  $baseField = $helper->quote('BASE');
479  $dateUpdateField = $helper->quote('DATE_UPDATE');
480  $modifiedByField = $helper->quote('MODIFIED_BY');
481  $amountField = $helper->quote('AMOUNT');
482  $amountCntField = $helper->quote('AMOUNT_CNT');
483  $currencyField = $helper->quote('CURRENCY');
484  $query = 'update '.$tableName.' set '.$baseField.' = \'N\', '.
485  $dateUpdateField.' = '.$helper->getCurrentDateTimeFunction().', '.
486  $modifiedByField.' = '.($userID == 0 ? 'NULL' : $userID).
487  ' where '.$currencyField.' <> \''.$helper->forSql($currency).'\' and '.$baseField.' = \'Y\'';
488  $conn->queryExecute($query);
489  $query = 'update '.$tableName.' set '.$baseField.' = \'Y\', '.
490  $dateUpdateField.' = '.$helper->getCurrentDateTimeFunction().', '.
491  $modifiedByField.' = '.($userID == 0 ? 'NULL' : $userID).', '.
492  $amountField.' = 1, '.$amountCntField.' = 1 where '.$currencyField.' = \''.$helper->forSql($currency).'\'';
493  $conn->queryExecute($query);
494 
495  static::updateBaseRates();
496 
497  $event = new Main\Event(
498  'currency',
499  self::EVENT_ON_AFTER_UPDATE_BASE_CURRENCY,
500  array(
501  'NEW_BASE_CURRENCY' => $currency
502  )
503  );
504  $event->send();
505  unset($event);
506  self::$baseCurrency = '';
507 
508  return true;
509  }
510 }
static clearTagCache($currency)
Clear tag currency cache.
static clearCurrencyCache($language='')
Clear currency cache.
static getCurrencyList()
Return currency short list.
static currencyBaseRateAgent()
Agent for update current currencies rates to base currency.
static updateBaseRates($updateCurrency='')
Update current currencies rates to base currency.
static isCurrencyExist($currency)
Verifying the existence of the currency by its code.
static getSymbolList()
Returns currency symbol list.
static updateBaseCurrency($currency)
Update base currency.
static checkLanguage($language)
Check language id.
static getBaseCurrency()
Return base currency.
static getInstalledCurrencies()
Return currency list, create to install module.
static getNameList()
Returns currency name list.
static checkCurrencyID($currency)
Check currency id.
static getTableName()
Returns DB table name for entity.
Base class for any application.
static getInstance()
Returns current instance of the Application.
static getConnection($name="")
Static method returns database connection for the specified name.
static get($moduleId, $name, $default="", $siteId=false)
Returns a value of an option.
static set($moduleId, $name, $value="", $siteId="")
Sets an option value and saves it into a DB.
static loadMessages($file)
Loads language messages for specified file in a lazy way.
Definition: loc.php:67
static isModuleInstalled($moduleName)
static getList(array $parameters=array())
Executes the query and returns selection by parameters of the query.