Плагин парсер валют для WordPress

  • 6 993
  • Комментарии: 14

Сейчас мы с вами напишем парсер курсов валют с сайта http://www.cbr.ru/ и оформим его в виде плагина WordPress.

Кстати, вот хороший WordPress плагин для отображения курсов валют: Скачать плагин курсов валют для WordPress

Пример работы плагина CurrencyConverter вы можете увидеть прямо у меня на сайте: в сайдбаре в блоке «Курс обмена валют».

Постановка задачи

Написать плагин, который каждый день собирает данные курсов валют с сайта ЦентроБанка и кладёт их в базу WP.

Алгоритм

Теперь давайте представим в общих чертах как наш парсер будет работать:

  1. При установке парсера выполняется скрипт создания таблицы в БД WP.
  2. При обращении к парсеру выполняется следующая проверка: если время последней загрузки отсутствует или временной интервал между моментом последней загрузки и текущим моментом составляет больше суток, то загружаем xml-файл и заносим данные из него в базу и отдаём массив с курсами. После этого обновляем время последней загрузки. Иначе (если условие не выполнено) отдаём массив с курсами из базы.
  3. Всё 😉

Не волнуйтесь если сейчас что-то непонятно, мы всё разберём по полочкам!

Приступаем к работе

Добавим информацию о плагине

Первым делом создайте файл «ex_rates.php». Наш плагин будет состоять всего из одного файла (зато какого! 😉 и весь последующий код будет добавляться именно в него. Добавьте в самое начало файла следующие строки:

/*
Plugin Name: EX-rates CBR
Description: Сборщик курсов валют с Центрального банка РФ
Version: 0.1
Author: Заболотских Борис
Author URI: https://zabolotskikh.com/
*/

Это краткая информация о плагине. Я решил назвать плагин EX-rates CBR. А также добавил информацию о себе и описание плагина.

Создаём активатор и реализуем удаление плагина

Теперь реализуем действия, которые будут выполнятся при активации и удалении плагина.

/**
 * Активатор
 * Создаёт две таблицы в БД
 * @global type $wpdb
 */
function ex_rates_activation()
{
    //Это глобальный объект для работы с БД
    global $wpdb;

    //Выполняем запросы (создаём две таблицы)
    $wpdb->query('DROP TABLE IF EXISTS '.$wpdb->prefix.'ex_rates;');
    $wpdb->query(
     'CREATE TABLE IF NOT EXISTS '.$wpdb->prefix.'ex_rates (
       code VARCHAR(3) NOT NULL,
       currency VARCHAR(255) NOT NULL,
       course DECIMAL(8,4) NOT NULL,
       nominal INT NOT NULL,
       PRIMARY KEY (code))
     ENGINE = InnoDB;');

    $wpdb->query('DROP TABLE IF EXISTS '.$wpdb->prefix.'ex_log;');
    $wpdb->query(
     'CREATE TABLE IF NOT EXISTS '.$wpdb->prefix.'ex_log (
       updated INT NOT NULL,
       PRIMARY KEY (updated))
     ENGINE = InnoDB;');
}

/**
 * Удаление плагина
 * Удаляет таблицы из БД
 * @global type $wpdb
 */
function ex_rates_uninstall()
{
    global $wpdb;
    $wpdb->query('DROP TABLE IF EXISTS '.$wpdb->prefix.'ex_rates;');
    $wpdb->query('DROP TABLE IF EXISTS '.$wpdb->prefix.'ex_log;');
}

//Регистрируем хук установки
register_activation_hook(__FILE__, 'ex_rates_activation');
//Регистрируем хук удаления
register_uninstall_hook(__FILE__, 'ex_rates_uninstall');

Как мы видим, в активаторе создаётся следующая структура таблиц:

Структура таблиц в БД

В таблице «ex_rates» лежит информация по курсам валют:

  • «code» — код валюты, например «USD»
  • «currency» — русское название валюты, например «Доллар США»
  • «course» — курс валюты по отношению к рублю, например «33.2578»
  • «nominal» — номинал валюты по отношению к рублю, например «1»

В таблице «ex_log» всего одно поле «updated» и в нём в формате unix timestamp лежит время последней загрузки xml файла.

Когда плагин удаляется, считается хорошим тоном чтобы он не оставлял после себя ничего, в том числе и таблицы в БД, что мы и реализовали.

 Функционал плагина

Итак, таблица у нас создаётся при активации, логику удаления мы реализовали, информацию о плагине добавили, теперь самое время заняться функционалом. Добавьте после информации о плагине и перед функцией активации следующий код:

class EX_rates
{
    //Задаём интервал обновления (в секундах) "43200" - половина суток (12 часов)
    CONST interval = 43200;
    //Путь, откуда забираем данные
    CONST source = 'http://www.cbr.ru/scripts/XML_daily.asp';
    //Здесь будет WP'шный лежать объект для работы с БД
    private $wpdb;
    //Здесь будут имена таблиц
    private $table_rates;
    private $table_log;

    /**
     * В конструкторе определяем объект для работы с БД, имена таблиц, и если
     * надо то обновляем данные
     */
    public function __construct()
    {
        global $wpdb;
        //Устанавливаем объект для работы с БД
        $this->wpdb = $wpdb;
        //Устанавливам имена таблиц
        $this->table_rates = $this->wpdb->prefix.'ex_rates';
        $this->table_log = $this->wpdb->prefix.'ex_log';

        //(Текущее время - время последнего обновления), если оно больше чем
        //заданный интервал, то обновляем данные
        if ( (time() - $this->updatedTime()) > self::interval )
        {
            $this->refresh();
        }
    }

    /**
     * Возвращает все данные из таблицы с курсами в виде объекта
     * @return object
     */
    public function courses()
    {
        return $this->wpdb->get_results('SELECT * FROM '.$this->table_rates);
    }

    /**
     * Возвращает данные из таблицы с курсами в массиве вида:
     *  'USD' => array(
            'nominal' => 1,
            'value' => 33.8161,
            ),
        'EUR' => array(
            'nominal' => 1,
            'value' => 45.8242,
            ),
     * @return array
     */
    public function coursesInArray()
    {
        foreach ($this->courses() as $rate)
        {
            $arr[$rate->code] = array(
                'value' => $rate->course,
                'nominal' => $rate->nominal,
            );
        }

        return $arr;
    }

    /**
     * Возвращает время последнего обновления данных в формате unix timestamp
     * @return int
     */
    private function updatedTime()
    {
        return $this->wpdb->get_var('SELECT updated FROM '.$this->table_log);
    }

    /**
     * Обновляет данные в таблице
     * @return boolean
     */
    private function refresh()
    {
        //Если не удалось загрузить xml файл, то возвращаем false;
        if (!$xml = simplexml_load_file(self::source))
        {
            return false;
        }

        //Очищаем таблицу с курсами
        if ( !$this->wpdb->query('TRUNCATE TABLE '.$this->table_rates.';') )
        {
            return false;
        }
        //Очищаем таблицу с логом
        if ( !$this->wpdb->query('TRUNCATE TABLE '.$this->table_log.';') )
        {
            return false;
        }

        //Прогоняем в цикле валюты
        foreach($xml->Valute as $rate)
        {
            //Формируем массив с курсами
            $rates = array(
                    'code' => $rate->CharCode,
                    'currency' => $rate->Name,
                    //Делаем эту нелепую заменую, потому что так отдаётся xml)
                    'course' => str_replace(',', '.', $rate->Value),
                    'nominal' => $rate->Nominal,
                );

            //Вставлям массив с курсами в БД.
            if ( !$this->wpdb->insert($this->table_rates, $rates) )
            {
                return false;
            }
        }

        //Записываем время обновления данных (текущее время)
        if ( !$this->wpdb->insert( $this->table_log, array('updated'=>time())) )
        {
            return false;
        }

        return true;
    }
}

Я старался комментировать свои действия, чтобы вам было понятнее.

Стоит обратить внимание на конструктор, в нём в самом начала определяется глобальный объект $wpdb, это вордпрессовский объект для работы с БД, именно через него у нас происходят все обращения к БД, а чтобы в каждом методе не писать global $wpdb, мы кладём его в приватное свойство $this->wpdb;. Теперь по поводу имён таблиц: $this->table_rates = $this->wpdb->prefix.'ex_rates';. Т.к. наши таблицы имеют следующий шаблон имени: <префикс вордпресса (скорее всего у вас это "wp_")> + <наш префикс (ex_)> + <имя таблицы>, то каждый раз определять это не имеет смысла, поэтому сразу кладём всё в свойства объекта. Далее идёт проверка (если (<текущее время><время последнего обновления>) > <заданный интервал>) если это условие верно, то выполняется обновление данных.

Надеюсь, что остальные методы понятны и не вызовут вопросов)

Теперь кладём файл в папку (можно назвать её так же как и плагин), запаковываем в zip архив и устанавливаем обычным способом.

Самое время попробовать получить данные из нашего плагина! 😉 В любом месте нам доступен объект EX_rates и мы можем его использовать, попробуйте сделать следующее:

$ex_rates = new EX_rates();
var_dump($ex_rates-&amp;gt;coursesInArray()); // Вернёт массив с курсами валют

Вот и всё, удачи! =)

Понравилась статья? Оцени её!
14 комментариев
  • Евгений пишет:

    Плагин активировал а что дальше не понятно ???? подскажите плиз

    • Борис Заболотских пишет:

      $ex_rates = new EX_rates();
      $arr = $ex_rates->coursesInArray();
      вот массив с курсами, можете их где-нибудь вывести.

      • Евгений пишет:

        соответственно надо coursesInArray();
        вот массив с курсами, можете их где-нибудь вывести.
        ?>

      • Евгений пишет:

        coursesInArray();
        ?>
        так да ?
        вот массив с курсами, можете их где-нибудь вывести.

        • Борис Заболотских пишет:

          Смотря что вы хотите сделать…
          У вас есть массив, вы можете вытащить из него информацию и отобразить где-нибудь.

          • Евгений пишет:

            попроьовал вставить в файл индекс ни чего не выводит

  • Евгений пишет:

    уцда только не вставлял не раьотает и в виджет пхп и так взгляните http://рубль-евро.рф/
    внизу в подвале
    11111111

    $ex_rates = new EX_rates(); $arr = $ex_rates->coursesInArray(); выводит

    • Борис Заболотских пишет:

      Этот плагин даёт лишь массив с курсами! Т.е. готовой красивой таблички с курсами нет. Но вы можете сделать её самостоятельно при помощи полученного массива.

  • Евгений пишет:

    нокак ?

    • Борис Заболотских пишет:

      Думаю, вам удобнее будет воспользоваться другим плагином.

      • Артем пишет:

        Здравствуйте, при активации плагина выходит фатальная ошибка

        Parse error: syntax error, unexpected ‘&’ in \www\wp-content\plugins\parser\parser.php on line 21

  • Евгений пишет:

    был массив но он один раз появился и все

  • Андрей пишет:

    Добрейшей вечерок.
    скажите, пожалуйста, а как с помощью foreach цикла я могу вывести значения из массива?
    $ex_rates->coursesInArray(); возвращает массив.
    Если я пробую сделать переменную
    $custom_array = $ex_rates->coursesInArray();
    А после этого в цикле
    foreach($custom_array as $value){
    echo ».$value.»;
    }
    Получают или ошибку или пустоту. Как быть?!
    Большое спасибо заранее.
    В долгу не останусь.

    • Борис Заболотских пишет:

      Здравствуйте!
      Посмотрите с помощью var_dump() что возвращает $value внутри цикла. Если там массив, то нужен вложенный цикл.

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

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