Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
currencymanager.php
1<?php
2namespace Bitrix\Currency;
3
8
15{
16 public const CACHE_BASE_CURRENCY_ID = 'currency_base_currency';
17 public const CACHE_CURRENCY_LIST_ID = 'currency_currency_list';
18 public const CACHE_CURRENCY_SHORT_LIST_ID = 'currency_short_list_';
19 public const CACHE_CURRENCY_SYMBOL_LIST_ID = 'currency_symbol_list_';
20 public const CACHE_CURRENCY_NAME_LIST_ID = 'currency_name_list_';
21
22 public const EVENT_ON_AFTER_UPDATE_BASE_RATE = 'onAfterUpdateCurrencyBaseRate';
23 public const EVENT_ON_UPDATE_BASE_CURRENCY = 'onUpdateBaseCurrency';
24 public const EVENT_ON_AFTER_UPDATE_BASE_CURRENCY = 'onAfterUpdateBaseCurrency';
25
26 protected static ?string $baseCurrency = null;
27
34 public static function checkCurrencyID($currency)
35 {
36 $currency = (string)$currency;
37 return ($currency === '' || mb_strlen($currency) > 3 ? false : $currency);
38 }
39
46 public static function checkLanguage($language)
47 {
48 $language = (string)$language;
49 return ($language === '' || mb_strlen($language) > 2 ? false : $language);
50 }
51
57 public static function getBaseCurrency(): ?string
58 {
59 if (self::$baseCurrency === null)
60 {
62 $skipCache = (defined('CURRENCY_SKIP_CACHE') && CURRENCY_SKIP_CACHE);
63 $currencyFound = false;
64 $currencyFromCache = false;
65 if (!$skipCache)
66 {
67 $cacheTime = (int)(defined('CURRENCY_CACHE_TIME') ? CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME);
68 $managedCache = Application::getInstance()->getManagedCache();
69 $currencyFromCache = $managedCache->read($cacheTime, self::CACHE_BASE_CURRENCY_ID, CurrencyTable::getTableName());
70 if ($currencyFromCache)
71 {
72 $currencyFound = true;
73 self::$baseCurrency = (string)$managedCache->get(self::CACHE_BASE_CURRENCY_ID);
74 }
75 }
76 if ($skipCache || !$currencyFound)
77 {
78 $currencyIterator = CurrencyTable::getList([
79 'select' => [
80 'CURRENCY',
81 ],
82 'filter' => [
83 '=BASE' => 'Y',
84 '=AMOUNT' => 1,
85 ],
86 ]);
87 if ($currency = $currencyIterator->fetch())
88 {
89 $currencyFound = true;
90 self::$baseCurrency = $currency['CURRENCY'];
91 }
92 unset($currency, $currencyIterator);
93 }
94 if (!$skipCache && $currencyFound && !$currencyFromCache)
95 {
96 $managedCache->set(self::CACHE_BASE_CURRENCY_ID, self::$baseCurrency);
97 }
98 }
99
100 return self::$baseCurrency;
101 }
102
108 public static function getCurrencyList(): array
109 {
110 $currencyTableName = CurrencyTable::getTableName();
111 $managedCache = Application::getInstance()->getManagedCache();
112
113 $cacheTime = (int)(defined('CURRENCY_CACHE_TIME') ? CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME);
114 $cacheId = self::CACHE_CURRENCY_SHORT_LIST_ID.LANGUAGE_ID;
115
116 if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
117 {
118 $currencyList = $managedCache->get($cacheId);
119 }
120 else
121 {
122 $currencyList = [];
123 $currencyIterator = CurrencyTable::getList([
124 'select' => [
125 'CURRENCY',
126 'FULL_NAME' => 'CURRENT_LANG_FORMAT.FULL_NAME',
127 'SORT',
128 ],
129 'order' => [
130 'SORT' => 'ASC',
131 'CURRENCY' => 'ASC',
132 ],
133 ]);
134 while ($currency = $currencyIterator->fetch())
135 {
136 $currency['FULL_NAME'] = (string)$currency['FULL_NAME'];
137 $currencyList[$currency['CURRENCY']] = $currency['CURRENCY']
138 . ($currency['FULL_NAME'] !== '' ? ' (' . $currency['FULL_NAME'] . ')' : '')
139 ;
140 }
141 unset($currency, $currencyIterator);
142 $managedCache->set($cacheId, $currencyList);
143 }
144
145 return $currencyList;
146 }
147
153 public static function getSymbolList(): array
154 {
155 $currencyTableName = CurrencyTable::getTableName();
156 $managedCache = Application::getInstance()->getManagedCache();
157
158 $cacheTime = defined('CURRENCY_CACHE_TIME') ? (int)CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME;
159 $cacheId = self::CACHE_CURRENCY_SYMBOL_LIST_ID.LANGUAGE_ID;
160
161 if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
162 {
163 $currencyList = $managedCache->get($cacheId);
164 }
165 else
166 {
167 $sanitizer = new \CBXSanitizer();
168 $sanitizer->setLevel(\CBXSanitizer::SECURE_LEVEL_LOW);
169 $sanitizer->ApplyDoubleEncode(false);
170
171 $currencyList = [];
172 $currencyIterator = CurrencyTable::getList([
173 'select' => [
174 'CURRENCY',
175 'FORMAT_STRING' => 'CURRENT_LANG_FORMAT.FORMAT_STRING',
176 'SORT',
177 ],
178 'order' => [
179 'SORT' => 'ASC',
180 'CURRENCY' => 'ASC',
181 ],
182 ]);
183 while ($currency = $currencyIterator->fetch())
184 {
185 $showValue = $currency['CURRENCY'];
186 $currencyFormat = (string)$currency['FORMAT_STRING'];
187 if ($currencyFormat !== '')
188 {
189 $symbol = \CCurrencyLang::applyTemplate('', $currencyFormat);
190 if (is_string($symbol))
191 {
192 $symbol = trim($symbol);
193 if ($symbol !== '')
194 {
195 $showValue = $symbol;
196 }
197 }
198 }
199 $currencyList[$currency['CURRENCY']] = $sanitizer->SanitizeHtml($showValue);
200 }
201
202 $managedCache->set($cacheId, $currencyList);
203 }
204
205 return $currencyList;
206 }
207
213 public static function getNameList(): array
214 {
215 $currencyTableName = CurrencyTable::getTableName();
216 $managedCache = Application::getInstance()->getManagedCache();
217
218 $cacheTime = defined('CURRENCY_CACHE_TIME') ? (int)CURRENCY_CACHE_TIME : CURRENCY_CACHE_DEFAULT_TIME;
219 $cacheId = self::CACHE_CURRENCY_NAME_LIST_ID.LANGUAGE_ID;
220
221 if ($managedCache->read($cacheTime, $cacheId, $currencyTableName))
222 {
223 $currencyList = $managedCache->get($cacheId);
224 }
225 else
226 {
227 $currencyList = [];
228 $currencyIterator = CurrencyTable::getList([
229 'select' => [
230 'CURRENCY',
231 'FULL_NAME' => 'CURRENT_LANG_FORMAT.FULL_NAME',
232 'SORT',
233 ],
234 'order' => [
235 'SORT' => 'ASC',
236 'CURRENCY' => 'ASC',
237 ],
238 ]);
239 while ($currency = $currencyIterator->fetch())
240 {
241 $fullName = (string)$currency['FULL_NAME'];
242 if ($fullName === '')
243 {
244 $fullName = $currency['CURRENCY'];
245 }
246
247 $currencyList[$currency['CURRENCY']] = $fullName;
248 }
249
250 $managedCache->set($cacheId, $currencyList);
251 }
252
253 return $currencyList;
254 }
255
262 public static function isCurrencyExist($currency): bool
263 {
264 $currency = static::checkCurrencyID($currency);
265 if ($currency === false)
266 {
267 return false;
268 }
269 $currencyList = static::getCurrencyList();
270
271 return isset($currencyList[$currency]);
272 }
273
279 public static function getInstalledCurrencies(): array
280 {
281 $installedCurrencies = Option::get('currency', 'installed_currencies');
282 if ($installedCurrencies === '')
283 {
284 $bitrix24 = Main\ModuleManager::isModuleInstalled('bitrix24');
285
286 $languageID = '';
287 $siteIterator = Main\SiteTable::getList([
288 'select' => [
289 'LID',
290 'LANGUAGE_ID',
291 ],
292 'filter' => [
293 '=DEF' => 'Y',
294 '=ACTIVE' => 'Y',
295 ],
296 ]);
297 $site = $siteIterator->fetch();
298 if (!empty($site))
299 {
300 $languageID = (string)$site['LANGUAGE_ID'];
301 }
302 unset($site, $siteIterator);
303
304 if ($languageID === '')
305 {
306 $languageID = 'en';
307 }
308
309 if (!$bitrix24 && $languageID === 'ru')
310 {
311 $languageList = [];
312 $languageIterator = LanguageTable::getList([
313 'select' => [
314 'ID',
315 ],
316 'filter' => [
317 '@ID' => [
318 'kz',
319 'by',
320 'ua'
321 ],
322 '=ACTIVE' => 'Y',
323 ],
324 ]);
325 while ($language = $languageIterator->fetch())
326 {
327 $languageList[$language['ID']] = $language['ID'];
328 }
329 unset($language, $languageIterator);
330 if (isset($languageList['kz']))
331 {
332 $languageID = 'kz';
333 }
334 elseif (isset($languageList['by']))
335 {
336 $languageID = 'by';
337 }
338 elseif (isset($languageList['ua']))
339 {
340 $languageID = 'ua';
341 }
342 unset($languageList);
343 }
344 unset($bitrix24);
345
346 switch ($languageID)
347 {
348 case 'br':
349 $currencyList = [
350 'BYN',
351 'RUB',
352 'USD',
353 'EUR',
354 ];
355 break;
356 case 'ua':
357 $currencyList = [
358 'UAH',
359 'RUB',
360 'USD',
361 'EUR',
362 ];
363 break;
364 case 'kz':
365 $currencyList = [
366 'KZT',
367 'RUB',
368 'USD',
369 'EUR',
370 ];
371 break;
372 case 'ru':
373 $currencyList = [
374 'RUB',
375 'USD',
376 'EUR',
377 'UAH',
378 'BYN',
379 ];
380 break;
381 case 'de':
382 case 'en':
383 case 'tc':
384 case 'sc':
385 case 'la':
386 default:
387 $currencyList = [
388 'USD',
389 'EUR',
390 'CNY',
391 'BRL',
392 'INR',
393 ];
394 break;
395 }
396
397 Option::set('currency', 'installed_currencies', implode(',', $currencyList), '');
398
399 return $currencyList;
400 }
401 else
402 {
403 return explode(',', $installedCurrencies);
404 }
405 }
406
413 public static function clearCurrencyCache($language = '')
414 {
415 $language = static::checkLanguage($language);
416 $currencyTableName = CurrencyTable::getTableName();
417
418 $managedCache = Application::getInstance()->getManagedCache();
419 $managedCache->clean(self::CACHE_CURRENCY_LIST_ID, $currencyTableName);
420 if (empty($language))
421 {
422 $languageIterator = LanguageTable::getList([
423 'select' => ['ID']
424 ]);
425 while ($oneLanguage = $languageIterator->fetch())
426 {
427 $managedCache->clean(self::CACHE_CURRENCY_LIST_ID.'_'.$oneLanguage['ID'], $currencyTableName);
428 $managedCache->clean(self::CACHE_CURRENCY_SHORT_LIST_ID.$oneLanguage['ID'], $currencyTableName);
429 $managedCache->clean(self::CACHE_CURRENCY_SYMBOL_LIST_ID.$oneLanguage['ID'], $currencyTableName);
430 $managedCache->clean(self::CACHE_CURRENCY_NAME_LIST_ID.$oneLanguage['ID'], $currencyTableName);
431 }
432 unset($oneLanguage, $languageIterator);
433 }
434 else
435 {
436 $managedCache->clean(self::CACHE_CURRENCY_LIST_ID.'_'.$language, $currencyTableName);
437 $managedCache->clean(self::CACHE_CURRENCY_SHORT_LIST_ID.$language, $currencyTableName);
438 $managedCache->clean(self::CACHE_CURRENCY_SYMBOL_LIST_ID.$language, $currencyTableName);
439 $managedCache->clean(self::CACHE_CURRENCY_NAME_LIST_ID.$language, $currencyTableName);
440 }
441 $managedCache->clean(self::CACHE_BASE_CURRENCY_ID, $currencyTableName);
442
444 global $stackCacheManager;
445 $stackCacheManager->clear('currency_rate');
446 $stackCacheManager->clear('currency_currency_lang');
447 }
448
455 public static function clearTagCache($currency)
456 {
457 if (!defined('BX_COMP_MANAGED_CACHE'))
458 return;
459 $currency = static::checkCurrencyID($currency);
460 if ($currency === false)
461 return;
462 Application::getInstance()->getTaggedCache()->clearByTag('currency_id_'.$currency);
463 }
464
470 public static function currencyBaseRateAgent(): string
471 {
472 static::updateBaseRates();
473
474 return '\Bitrix\Currency\CurrencyManager::currencyBaseRateAgent();';
475 }
476
485 public static function updateBaseRates($updateCurrency = '')
486 {
487 $currency = static::getBaseCurrency();
488 if ($currency === '')
489 return;
490
491 $currencyIterator = CurrencyTable::getList([
492 'select' => [
493 'CURRENCY',
494 'CURRENT_BASE_RATE',
495 ],
496 'filter' => ($updateCurrency == '' ? [] : ['=CURRENCY' => $updateCurrency])
497 ]);
498 while ($existCurrency = $currencyIterator->fetch())
499 {
500 $baseRate = ($existCurrency['CURRENCY'] != $currency
501 ? \CCurrencyRates::getConvertFactorEx($existCurrency['CURRENCY'], $currency)
502 : 1
503 );
504 $updateResult = CurrencyTable::update($existCurrency['CURRENCY'], array('CURRENT_BASE_RATE' => $baseRate));
505 if ($updateResult->isSuccess())
506 {
507 $event = new Main\Event(
508 'currency',
509 self::EVENT_ON_AFTER_UPDATE_BASE_RATE,
510 [
511 'OLD_BASE_RATE' => (float)$existCurrency['CURRENT_BASE_RATE'],
512 'CURRENT_BASE_RATE' => $baseRate,
513 'BASE_CURRENCY' => $currency,
514 'CURRENCY' => $existCurrency['CURRENCY'],
515 ]
516 );
517 $event->send();
518 }
519 unset($updateResult);
520 unset($baseRate);
521 }
522 unset($existCurrency, $currencyIterator);
523 }
524
531 public static function updateBaseCurrency($currency): bool
532 {
534 global $USER;
535 $currency = CurrencyManager::checkCurrencyID($currency);
536 if ($currency === false)
537 return false;
538
539 $event = new Main\Event(
540 'currency',
541 self::EVENT_ON_UPDATE_BASE_CURRENCY,
542 [
543 'NEW_BASE_CURRENCY' => $currency,
544 ]
545 );
546 $event->send();
547 unset($event);
548
549 $conn = Main\Application::getConnection();
550 $helper = $conn->getSqlHelper();
551
552 $userID = (isset($USER) && $USER instanceof \CUser ? (int)$USER->getID() : 0);
553
554 $tableName = $helper->quote(CurrencyTable::getTableName());
555 $baseField = $helper->quote('BASE');
556 $dateUpdateField = $helper->quote('DATE_UPDATE');
557 $modifiedByField = $helper->quote('MODIFIED_BY');
558 $amountField = $helper->quote('AMOUNT');
559 $amountCntField = $helper->quote('AMOUNT_CNT');
560 $currencyField = $helper->quote('CURRENCY');
561 $query = 'update '.$tableName.' set '.$baseField.' = \'N\', '.
562 $dateUpdateField.' = '.$helper->getCurrentDateTimeFunction().', '.
563 $modifiedByField.' = '.($userID == 0 ? 'NULL' : $userID).
564 ' where '.$currencyField.' <> \''.$helper->forSql($currency).'\' and '.$baseField.' = \'Y\'';
565 $conn->queryExecute($query);
566 $query = 'update '.$tableName.' set '.$baseField.' = \'Y\', '.
567 $dateUpdateField.' = '.$helper->getCurrentDateTimeFunction().', '.
568 $modifiedByField.' = '.($userID == 0 ? 'NULL' : $userID).', '.
569 $amountField.' = 1, '.$amountCntField.' = 1 where '.$currencyField.' = \''.$helper->forSql($currency).'\'';
570 $conn->queryExecute($query);
571
572 static::updateBaseRates();
573
574 $event = new Main\Event(
575 'currency',
576 self::EVENT_ON_AFTER_UPDATE_BASE_CURRENCY,
577 [
578 'NEW_BASE_CURRENCY' => $currency,
579 ]
580 );
581 $event->send();
582 unset($event);
583 self::$baseCurrency = null;
584
585 return true;
586 }
587}
static clearCurrencyCache($language='')
static updateBaseRates($updateCurrency='')