Модуль погоды для Joomla — Joomla Weather Module

weather

Здравствуй<username>, давненько я не писал ничего стоящего для своего блога и это незамедлительно надо исправить. Сегодня я хотел бы поделиться с всеми желающими модулем погоды для CMS Joomla.

Вы наверное захотите узнать: Почему я решил сделать свой модуль погоды для Joomla?  Конечно же вы можете сказать, что для Joomla куча подобных модулей и наверняка, если по искать можно найти достойный модуль погоды для Joomla, но увы я вас разочарую я в течении нескольких часов пробовал найти простенький модуль погоды для Joomla и не нашел ничего подходящего. Попадались всякие модули некоторые из них были совсем не рабочие или не работали на php 5.5, были и такие которые пихали свою рекламу везде где можно было и нельзя, попадались мне и нормальные в которых не было рекламы, но увы эти модули все буржуйские и как принято все не на нашем могучем языке, а локализацией мне было заниматься лень в связи с чем было принято решение делать совой велосипед.

Перед созданием модуля я поставил для себя следующие цели:

  1. Модуль должен выводить контент на русском (название городов, состояние суток и т.п.)
  2. Модуль должен позволять пользователю выбрать любую точку мира, особенно нашей великой родины.
  3. Модуль должен быть легковесным и не включать в себя излишнюю статику (стили, скрипты, картинки)
  4. Модуль должен позволять пользователю использовать его из коробки, без всяких излишних ухищрений для получения доступа к стороннему API.

Поискав в качестве источника данных, я выбрал сервис Яндекс.Погода (официального, публичного API для получения погоды Яндекс не представляет, но с помощью различных ухищрений мне получилось получить погоду с данного сервиса). В итоге закатав рукава я принялся за написание модуля, в результате за несколько часов был сделан модуль который меня полностью удовлетворял. (Я не буду полностью описывать код и комментировать его, по моему там все очень просто, а просто приведу 2 основных файла в которых расположена основная логика модуля).

Файл helper.php

<?php defined('_JEXEC') or die;

class modWeatherHelper
{
    /**
     * @var $this
     */
    protected static $_instance = null;

    /**
     * Singleton
     *
     * @return $this
     */
    public static function getInstance()
    {
        if (is_null(self::$_instance)) {
            self::$_instance = new self;
        }

        return self::$_instance;
    }

    /**
     * Get weather info
     *
     * @param  JRegistry $params Module params
     *
     * @return array
     */
    public function getWeather(JRegistry $params)
    {
        if (!class_exists('SimpleXMLElement')) {
            return array();
        }

        // init content
        $weather = array();
        $content = $this->getRemoteContent('http://export.yandex.ru/weather-ng/forecasts/%d.xml',
            $params->get('city', 29467));

        try {
            $xml = new SimpleXMLElement($content);
            if ($xml->fact instanceof SimpleXMLElement) {
                $weather = array(
                    'country'       => (string) $xml['country'],
                    'part'          => (string) $xml['part'],
                    'city'          => (string) $xml['city'],
                    'image'         => sprintf('http://yandex.st/weather/1.2.1/i/icons/48x48/%s.png',
                        (string) $xml->fact->{'image-v3'}),
                    'temperature'   => (string) $xml->fact->temperature,
                    'weather_type'  => (string) $xml->fact->weather_type,
                );
            }

        } catch (Exception $e) { }

        return $weather;
    }

    public function getCityOptions()
    {
        // prepare
        $cities  = array();
        $content = $this->getRemoteContent('http://weather.yandex.ru/static/cities.xml');

        // load
        $xml = new SimpleXMLElement($content);
        foreach ($xml->country as $country) { /** @var SimpleXMLElement $country **/
            $index = (string) $country['name'];
            foreach ($country->city as $city) { /** @var SimpleXMLElement $city **/
                $cities[$index][(string) $city['id']] = (string) $city;
            }
            natsort($cities[$index]);
        }

        return $cities;
    }

    /**
     * Load remote content
     *
     * @param string $url Url string
     * @param mixed $_ Url replace paths
     *
     * @return string
     */
    public function getRemoteContent($url, $_ = null)
    {
        $arg = func_get_args();
        $url = vsprintf($url, array_slice($arg, 1));

        if (function_exists('curl_init')) {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_TIMEOUT, 20);
            curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            $content = curl_exec($curl);
            curl_close($curl);

            return $content;
        }

        return file_get_contents($url);
    }
}

Файл tmpl/default.php

<?php defined('_JEXEC') or die;

/**
 * @var JRegistry     $params                 Module params
 * @var array         $weather                Weather info
 * @var string        $moduleclass_sfx        Module class sfx
 */
?>

<?php if (count($weather) > 0) :  ?>
    <div class="weather">
        <img src="<?php echo $weather['image'] ?>" alt="<?php echo $weather['weather_type'] ?>" />
        <span class="weather-city"><?php echo $weather['city'] ?></span>
        <span class="weather-temperature"><?php echo $weather['temperature'] ?></span>
    </div>
<?php endif ?>

Как ведите решение достаточно простое, конечно можно было сделать кучу настроек для модуля т.к. Яндекс.Погода в своем ответе возвращает массу информации, но увы мне требовалось показывать только текущую погоду и по этому далее развивать идею я не стал, но не унывайте весь код модуля доступен на Github, в связи с чем вы всегда можете сделать Fork расширить функционал и сделать Pull Request в основной репозиторий для того, что бы поделиться со всеми своими наработками.

Скачать модуль | Исходный код модуля

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *