Спасибо за рецензирование.
<?php
/**
* @version 1.0
* @package mod_exchange_rates
* @author Author
* [member=126442]copyright[/member] Copyright (c) 2024 SeoProsto.Net. All rights reserved.
* @license http://www.gnu.org/licenses/gpl.html GNU/GPL
*/
defined('_JEXEC') or die();
function object_properties_inventory(&$standard, &$content) {
foreach ($standard as $key => $value) {
if ( gettype ($value) == 'string' )
{
//echo $key . ' = ' . $content->$key . '<br />'; // ### Отладочная информация
if ( isset($content->$key) ) {
//echo 'Переменная существует<br />'; // ### Отладочная информация
if ( !empty($content->$key) ) {
//echo '...и она не пустая<br />'; // ### Отладочная информация
} else {
//echo '...однако она пустая<br />'; // ### Отладочная информация
return false;
}
} else {
//echo 'Переменная не существует<br />'; // ### Отладочная информация
return false;
}
} else {
if ( !object_properties_inventory($value, $content->$key) )
return false;
}
}
return true;
}
$exchange_rates = function() {
setlocale(LC_TIME, "ru-Ru");
$chas_p = 3; // Время MSK: +3GMT
$now = time() + $chas_p*3600;
//$weekday_now_local = gmdate('w', $now); // день недели, неделя начинается с воскресенья (= 0) !!
//$date_now_local = gmdate('d.m.Y', $now);
//$time_now_local = gmdate('H:i', $now);
$need_load_data_from_site = false; // Флаг указывающий на необходимость выполнения блока для скачивания данных с сайта ЦБ
// Проверка наличия актуальных данных в кэше
header("Content-Type: application/json"); // на какие данные рассчитан этот скрипт
// Проверяем, есть ли на сервере нужный нам файл с данными — json.data.
$filename = __DIR__ . '/data.json'; // Берём новую переменную и пишем в неё имя файла
// Если есть — запоминаем его содержимое, а если такого файла нет — создаём его отдельной командой.
if (file_exists($filename)) { // Если файл есть...
// ... — открываем его и читаем данные
$file = file_get_contents($filename);
$list_of_exchange_rates = json_decode($file);
if ( (($now - $list_of_exchange_rates->cache_local_time) < 4 * 3600) && // Если разница между временем из кэша и текущим временем не превышает 4 часа,...
!($list_of_exchange_rates->date_now_crb == '00.00.0000') ) { // ...и дата котировки не "заглушка"
//echo "Данные из кэша" . "<br />"; // ### Отладочная информация
//echo "Разница времени: " . ($now - $list_of_exchange_rates->cache_local_time) . "<br />"; // ### Отладочная информация
} else {
$difference = 10; // Разница в секундах, между отмеченным временем и текущим
if ( ($now - $list_of_exchange_rates->time_attempt_file_get) > $difference ) {
// Если расхождение между временем последней попытки скачать данные с сайта ЦБ и текущим временем превышает 10 секунд...
$need_load_data_from_site = true; // ... - выставить флаг необходимости скачать данные с сайта ЦБ
} else { // Иначе - ничего не делать
//echo "Информация о курсах просрочена.<br />Но, попытка скачать актуальные<br />данные будет через "; // ### Отладочная информация
//echo ($difference - ($now - $list_of_exchange_rates->time_attempt_file_get)) . " секунд.<br />"; // ### Отладочная информация
}
}
} else { // Если такого файла нет...
// ...то создаём его сами
$file = fopen($filename, "a+");
$need_load_data_from_site = true;
}
// Проверка контейнера с данными на комплектность значимых переменных
$file = '{"date_now_crb":"00.00.0000","cache_local_time":"0000000000","time_attempt_file_get":"0000000000",';
$file .= '"ValueID":{"R01235":{"CharCode":"USD","Value":"00.0000"},"R01239":{"CharCode":"EUR","Value":"00.0000"}}}';
$list_layout = json_decode($file);
if ( object_properties_inventory($list_layout, $list_of_exchange_rates) ) {
//echo 'Проверка пройдена<br />'; // ### Отладочная информация
} else {
//echo 'Проверка не пройдена<br />'; // ### Отладочная информация
$list_of_exchange_rates = $list_layout; // Пересоздаем контейнер
file_put_contents($filename, json_encode($list_of_exchange_rates));
}
// Получение данных с сайта ЦБ
if ($need_load_data_from_site) {
$document_address;
$info_address;
$supplier;
$curr_filename;
//откуда будем парсить информацию
$document_address = 'https://www.cbr.ru/scripts/XML_daily.asp';
$info_address = 'https://www.cbr.ru';
$supplier = 'Центральный банк Российской Федерации';
// адрес xml файла, для получения котировок на заданный день
$curr_filename = $document_address.'?date_req='.gmdate( 'd/m/Y', $now );
//$curr_filename = $document_address; // если параметр(date_req) отсутствует, то Вы получите документ на последнюю зарегистрированную дату.
try {
$content = file_get_contents($curr_filename);
$document = new SimpleXMLElement($content);
$attributes = current($document->attributes());
$list_of_exchange_rates->date_now_crb = $attributes[Date];
foreach ($document->Valute as $value) {
$attributes = current($value->attributes());
switch($attributes[ID])
{
case 'R01235':
case 'R01239':
$list_of_exchange_rates->ValueID->$attributes[ID]->CharCode = (string)$value->CharCode;
$list_of_exchange_rates->ValueID->$attributes[ID]->Value = str_replace(",",".","$value->Value");
break;
}
}
$list_of_exchange_rates->cache_local_time = $now; // В случае успешной закачки данных - отмечаем текущее время
} catch (Exception $e) {
// Сервер www.cbr.ru недоступен
echo JText::_('MOD_EXCHANGE_RATES_SERVER_NOT_AVAILABLE') . '<br />';
$list_of_exchange_rates->time_attempt_file_get = $now; // В случае неудачи закачки данных - отмечаем время попытки
}
// Записываем Обновленные данные в кэш-файл
file_put_contents($filename, json_encode($list_of_exchange_rates));
$need_load_data_from_site = false;
//echo "Данные с сайта ЦБ" . "<br />"; // ### Отладочная информация
}
/* ?><pre><?php print_r($list_of_exchange_rates); ?></pre><?php // ### Отладочная информация */
$currency_icon = array
(
'R01235' => '<img alt="Курс Доллара к рублю на сегодня" src="modules/mod_exchange_rates/images/icons/usd.png" />',
'R01239' => '<img alt="Курс Евро к рублю на сегодня" src="modules/mod_exchange_rates/images/icons/eur.png" />',
);
$currency_title = array
(
'R01235' => 'MOD_EXCHANGE_RATES_USD',
'R01239' => 'MOD_EXCHANGE_RATES_EUR',
);
?>
<table id="exchange_rates">
<thead>
<tr>
<td><a href="https://cbr.ru/curreNcy_base/daily/"><?php echo JText::_('MOD_EXCHANGE_RATES_CAPTCURS_LABEL'); ?></a></td>
</tr>
</thead>
<tbody>
<tr>
<td><?php echo $list_of_exchange_rates->date_now_crb; ?></td>
</tr>
<?php
foreach ($list_of_exchange_rates->ValueID as $key => $value) { ?>
<tr>
<td>
<table>
<tbody>
<tr title="<?php echo JText::_($currency_title[$key]); ?>">
<td><?php echo $value->CharCode; ?></td>
<td><?php echo $currency_icon[$key]; ?></td>
<td><?php echo number_format($value->Value, 3, '.', ''); ?></td>
<td>
<span><?php echo JText::_('MOD_EXCHANGE_RATES_SHORT_RUB'); ?></span>
<img src="modules/mod_exchange_rates/images/arr_red.png">
</td>
</tr>
</tbody>
</table>
</td>
</tr><?php
}
?>
</tbody>
<tfoot>
<tr>
<td>
<a href="https://converter.by/cbr?ysclid=lq6ak6tj91210828053&calc_usd=10">
<?php echo JText::_('MOD_EXCHANGE_RATES_CURRENCY_CONVERTER'); ?>
</a>
</td>
</tr>
</tfoot>
</table><?php
};
$exchange_rates();
?>
Вкратце: Скрипт проверяет на внутреннем ресурсе наличие 'data.json' (если его нет - создает). Проверяет условие: если разница во времени, между текущим временем и хранимым в кэше - не превышает 4 часа; и дата валютной ставки, хранимой в кеше - не "заглушка" ('00.00.0000') - берет данные из файла; иначе - берет данные с сайта ЦБ, но перед этим проверяет - прошло ли 10 секунд после предудущей попытки взять эти данные. Если актуальных данных в кэше нет, а сайт ЦБ недоступен - выводит сообщение о недоступности сайта ЦБ; записывает в кэш время попытки скачать данные; выводит таблицу курсов с абстрактными данными.