Простой вывод погоды на сайте

Спасибо Ивану за помощь в написании сниппета
<?php
$cityId = $modx->getOption('cityId', $scriptProperties, 27612);  // id города https://pogoda.yandex.ru/static/cities.xml
$tpl = $modx->getOption('tpl', $scriptProperties, 'tpl.Weather');
$cacheTime = $modx->getOption('cacheTime', $scriptProperties, 60 * 60); // 1 час по умолчанию

$source = "http://export.yandex.ru/weather-ng/forecasts/$cityId.xml"; // адрес xml файла

$key = 'weather_' . $cityId;

if (!$output = $modx->cacheManager->get($key)) {
    
    $status = get_headers($source); //проверка доступности сервера погоды

    if (!in_array("HTTP/1.1 200 OK", $status) 
        && !in_array("HTTP/1.0 200 OK", $status)) {
        
        return 'Сервер погоды недоступен';
    }

    $xml = simplexml_load_file($source); // раскладываем xml на массив

    $temperature = (int) $xml->fact->temperature;

    $weather = array(
        'city' => (string) $xml->attributes()->city,
        'temperature' => $temperature <= 0 ? $temperature : '+' . $temperature, // для наглядности добавляем "+" 
        'picture' => (string) $xml->fact->image,
        'type' => (string) $xml->fact->weather_type
    );
    
    $output = $modx->getChunk($tpl, $weather); // Шаблонизация
    
    $modx->cacheManager->set($key, $output, $cacheTime);
}

return $output;
Вызывается сниппет:
[[!weather? &cityId=`27612` &tpl=`tpl.Weather` &cacheTime=`7200`]]
где cityId = ID города.
ID нужного города можно найти здесь: Список городов

Чанк tpl.Weather
[[+city]] <img src="//img.yandex.net/i/wiz[[+picture]].png" title="[[+type]]">[[+temperature]]°C
Получается такой результат:
Klike
26 мая 2015, 07:06
modx.pro
8
4 315
+3

Комментарии: 11

Виктор
26 мая 2015, 10:38
0
А разве сайт не повесится если вдруг к яндексу доступа у пользователя не будет?
    Василий Наумкин
    26 мая 2015, 11:00
    0
    Не у пользователя, у сайта. И да, повесится на весь timeout php процесса.
      Klike
      26 мая 2015, 11:12
      0
      А если в таком варианте? (обновил код) Кстати, Василий, не знаешь, как можно достать из XML название города?
      <forecast xmlns="http://weather.yandex.ru/forecast" city="Москва"
        Іван Клімчук
        26 мая 2015, 11:33
        0
          Іван Клімчук
          26 мая 2015, 11:37
          0
          В обновленном варианте тоже не идеально, так как при каждом запросе будет запрашиваться сайт погоды, чтобы может быть медленно. Такие вещи как правило или запрашивают скриптом по расписанию (cron) или кешируют результат на определенное время. Часа хватит. Можно класть в кеш самого MODX через
          $modx->cacheManager->set('testdata', 'My cached data.', 3600);
          Механика проста:
          1. Проверяем, если ли значение к кеше.
          2. Если нет, делаем запрос на сервер и сохраняем полученное значение к кеш
          3. Выводим значение из кеша
            Klike
            26 мая 2015, 23:17
            0
            А можете помочь в доработке с кэшем? :)
              Іван Клімчук
              26 мая 2015, 23:56
              +1
              Вот, переписал.
              gist.github.com/Alroniks/e6ba41e16dbaeb780cdc
              В вашем сниппете много ошибок. Изучите мой код (он тоже не совершенен), если будет совсем непонятно, могу вам в частном порядке рассказать, что не так.
                Виктор
                27 мая 2015, 01:09
                0
                А расскажите:
                Почему ">" хуже, чем "<="?
                Как массив раскладывается на плейсхолдеры без setPlaceholder?
                Не стоит ли проверять доступность только если нет кэша?
                  Іван Клімчук
                  27 мая 2015, 01:35
                  0
                  setPlaceholder устанавливает значение для все страницы сразу, в итоге погоду для двух городов вы уже не выведете, так как последний вызов будет затирать предыдущие поля. Ну и в чанк ничего не передавалось, т.е. по сути был лишний бесполезный вызов. Метод использовался не правильно. Данный массив передается в метод $modx->getChunk($tpl, $data) — первый параметр имя чанка, второй — ассоциативный массив с данными, где ключ массива — плейсхолдер в чанке, значение — значение :).
                  В данном случае данные о температур приходят в виде числа, если отрицательное, то с минусов, если положительное, без плюса. Нулю плюс приписывать не нужно, поэтому для числе меньше либо равно 0 — оставляем как есть, если больше 0, ставим плюс. Не принципиально, но мне так легче в коде читать.

                  Не стоит ли проверять доступность только если нет кэша?
                  Да, стоит внести в условие. Исправил.
                    Виктор
                    27 мая 2015, 12:02
                    0
                    Спасибо, полезно.
                  Klike
                  27 мая 2015, 07:37
                  0
                  Спасибо огромное, Иван! Я пока новичок в php, буду учиться)

                  Кстати, город извлекается так (строчка из сниппета):
                  'city' => (string) $xml->attributes()->city,
                  В том виде, какой сейчас город не всегда корректно выводится. А в примере выше – то, что надо) И тогда в чанк можно добавить [[+city]] для вывода города.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        11