Взаимодействие с Twitter (XML API)

Материал из Umicms
Перейти к:навигация, поиск

Актуально для версии 2.9

В данной статье будут представлены макросы, для взаимодействия с сервисом Twitter через Twitter XML API. Макрос для получения информации о пользователе и макрос получения ленты твитов.

Для незарегистрированных пользователей количество запросов к XML API ограничено. В час можно произвести только 150 запросов. Чтобы обойти данное ограничение, будут использоваться два вспомогательных макроса, для организации своего рода кэша. Макрос "writeCache" будет записывать полученные данные во временный файл, а макрос "readCache" считывать их. В последствии, чтобы каждый раз при обращение к странице, где будут использоваться макросы получения информации о пользователе или ленты твитов, не производился запрос к серверу Twitter, данные будут браться из временных файлов.

Все макросы необходимо разместить в файле "/classes/modules/custom.php", сразу после строки "//TODO: Write your macroses here". Для удобства написания и чтения кода воспользуемся константами, их нужно будет разместить после текста "<?php". В результате, файл "custom.php" будет выглядеть примерно следующим образом:

Листинг 1. Файл "custom.php"

<?php

  // Константы для макросов взаимодействия с Twitter
  define('CACHE_PATH', './sys-temp/twitter/', true); // Директория для файлов кэша
  define('SCREEN_LINK', 'http://twitter.com/users/show.xml?screen_name=', true); // URL для получения информации о пользователе
  define('TIMELINE_LINK', 'http://twitter.com/statuses/user_timeline/', true); // URL для получения ленты твитов
  
  class custom extends def_module {
    public function cms_callMethod($method_name, $args) {
      return call_user_func_array(Array($this, $method_name), $args);
    }
		
    public function __call($method, $args) {
      throw new publicException("Method " . get_class($this) . "::" . $method . " doesn't exists");
    }
    //TODO: Write your own macroses here
    
    // + Twitter
    
    /*
      @title
        Макрос записи данных в кэш
      @param String
        $filename - имя файла
      @param String
        $content - содержание файла
     */
    private function writeCache($filename, $content) {
      if(!file_exists(CACHE_PATH))
        mkdir(CACHE_PATH);
      
      try {
        $fp = fopen(CACHE_PATH.$filename, 'w');
        flock($fp, LOCK_EX);
        fwrite($fp, $content);
        flock($fp, LOCK_UN);
        fclose($fp);
      } catch(Exception $e) {
        echo $e->getMessage();
      }
    }
    
    /*
      @title
        Макрос чтения данных из кэша
      @param String
        $filename - имя файла
      @param Integer
        $expiry - время в миллисекундах (необходимо для вычисления актуальности данных)
     */
    private function readCache($filename, $expiry) {
      $cache_filename = CACHE_PATH.$filename;
      if(file_exists($cache_filename)) {
        if((time() - $expiry) > filemtime($cache_filename))
          return false;
          
        return simplexml_load_file($cache_filename);
      }
      
      return false;
    }
    
    /*
      @title
        Макрос получения информации о пользователе
      @param String
        $id - идентификатор пользователя
      @param String
        $template - шаблон вывода в TPL
     */
    public function twitterScreen($id, $template = 'default') {
      if(!isset($template))
        $template = 'default';
        
      list($widget_block, $error_block) =
        self::loadTemplates('twitter/user/'.$template, 'widget_block', 'error_block');
        
      if(!isset($id))
        return $error_block;
      
      $user_cache_filename = $id.'.user.cache';
      if(!($user = $this->readCache($user_cache_filename, 1800))) {
        $user = simplexml_load_file(SCREEN_LINK.$id);
        $this->writeCache($user_cache_filename, $user->asXML());
      }
      
      if(!$user)
        return $error_block;
      
      $block_arr = array();
      $block_arr['id'] = (string)$user[0]->id;
      $block_arr['name'] = (string)$user[0]->name;
      $block_arr['screen_name'] = (string)$user[0]->screen_name;
      $block_arr['location'] = (string)$user[0]->location;
      $block_arr['description'] = (string)$user[0]->description;
      $block_arr['profile_image_url'] = (string)$user[0]->profile_image_url;
      $block_arr['url'] = (string)$user[0]->url;
      $block_arr['followers_count'] = (string)$user[0]->followers_count;
      $block_arr['statuses_count'] = (string)$user[0]->statuses_count;
      $block_arr['lang'] = (string)$user[0]->lang;
      $block_arr['status'] = (string)$user[0]->status->text;

      return self::parseTemplate($widget_block, $block_arr);
    }
    
    /*
      @title
        Макрос получения ленты твитов
      @param String
        $id - идентификатор пользователя
      @param Integer
        $count - количество выводимых твитов
      @param String
        $template - шаблон вывода в TPL
     */
    public function twitterTimeline($id, $count = 3, $template = 'default') {
      if(!isset($template))
        $template = 'default';
        
      list($timeline_block, $lines_block, $error_block) =
        self::loadTemplates('twitter/timeline/'.$template, 'timeline_block', 'lines_block', 'error_block');
        
      if(!isset($id))
        return $error_block;
      
      $user_cache_filename = $id.'.user.cache';
      if(!($user = $this->readCache($user_cache_filename, 1800))) {
        $user = simplexml_load_file(SCREEN_LINK.$id);
        $this->writeCache($user_cache_filename, $user->asXML());
      }
      
      if(!$user)
        return $error_block;
      
      $timeline_cache_filename = $id.'.timeline.cache';
      if(!($timeline = $this->readCache($timeline_cache_filename, 1800))) {
        $timeline = simplexml_load_file(TIMELINE_LINK.$id.'.rss');
        $this->writeCache($timeline_cache_filename, $timeline->asXML());
      }

      if(!$timeline)
        return $error_block;
        
      if($count < 1)
        $count = 1;
        
      $length = count($timeline->channel->item);
      if($count > $length)
        $count = $length;
      
      $lines = array();
      for($i = 0; $i < $count; $i++) {
        $line_arr = array();
        $line_arr['date'] = (string)date('d.m.Y G:i', strtotime($timeline->channel->item[$i]->pubDate));
        $line_arr['title'] = (string)$timeline->channel->item[$i]->title;
        $line_arr['link'] = (string)$timeline->channel->item[$i]->link;
        $lines[] = self::parseTemplate($lines_block, $line_arr);
      }
      
      $block_arr = array();
      $block_arr['id'] = (string)$user[0]->id;
      $block_arr['name'] = (string)$user[0]->name;
      $block_arr['screen_name'] = (string)$user[0]->screen_name;
      $block_arr['count'] = (integer)$count;
      $block_arr['subnodes:lines'] = (array)$lines;
      
      return self::parseTemplate($timeline_block, $block_arr);
    }
    
    // - Twitter
  };
?>

Макросы "writeCache" и "readCache" имеют модификаторы "private". Это сделано для того, чтобы они были недоступны для пользователей на прямую.

Теперь можно посмотреть ответ UData, к примеру, макроса "twitterScreen". Для этого наберите в адресной сроке браузера текст: "domain.ru/udata/custom/twitterScreen/umi_cms/notemplate". В результате будет получен ответ UData:

<udata xmlns:xlink="http://www.w3.org/TR/xlink" module="custom" method="twitterScreen" generation-time="0.707462">
  <id>63716372</id>
  <name>UMI</name>
  <screen_name>umi_cms</screen_name>
  <description>UMI.CMS среди лидеров рынка CMS в России. Каждый третий разработчик Рунета использует UMI.CMS для создания сайтов.</description>
  <profile_image_url>http://a0.twimg.com/profile_images/1850324360/vert1_normal.png</profile_image_url>
  <url>http://www.umi-cms.ru</url>
  <followers_count>469</followers_count>
  <statuses_count>905</statuses_count>
  <lang>ru</lang>
  <status>RT @fullspace_: Внедрили поддержку @umi_cms в настройки Nginx. Ускоряем сайты как никто! :) http://t.co/2N3Sbo2l</status>
</udata>

При использовании XSLT-шаблонизатора макросы готовы к работе. Если Вы используете TPL-шаблонизатор, необходимо организовать шаблоны вывода информации. Создайте файл "/tpls/twitter/user/default.tpl" - шаблон вывода информации о пользователе. Его содержание будет следующим:

Листинг 2. Шаблон вывода информации о пользователе

<?php
$FORMS = Array();

$FORMS['widget_block'] = <<<END

    <p>%id%</p>
    <p>%description%</p>
    <img src="%profile_image_url%" alt="" />
  
END;

$FORMS['error_block'] = <<<END

<p>Ошибка!</p>

END;
?>

Далее нужно создать файл "/tpls/twitter/timeline/default.tpl" - шаблон вывода ленты твитов. Содержание данного файла будет таким:

Листинг 3. Шаблон вывода ленты твитов

<?php
$FORMS = Array();

$FORMS['timeline_block'] = <<<END

    <p>Последние <strong>%count%</strong> твитов пользователя 
    <strong>%name%</strong> (%id%)</p><br />
    <div>%lines%</div>
  
END;

$FORMS['lines_block'] = <<<END

<p><strong>%date%</strong></p>
<p><em>%title%.</em></p>
<p><a href="%link%">Twitter</a></p>
<br />

END;

$FORMS['error_block'] = <<<END

<p>Ошибка!</p>

END;

?>

После создания шаблонов вывода, макросы готовы к использованию и в TPL-шаблонизаторе.

Для примера, выведем последние 3 твита пользователя "umi_cms" в TPL-шаблон "Интернет-магазин" (Хомячки). Откройте файл "/tpls/content/index.tpl" и пропишите макрос "custom twitterTimeline" в блоке "<div class="column">":

<div class="column">			
  %search insert_form('home')%
					
  %custom twitterTimeline('umi_cms')%
</div>

Twitter screen.png

Последние 3 твита пользователя "umi_cms"

Примечание.

Данный функционал был проверен на работоспособность в версии системы 2.8.5.1.