Взаимодействие с Twitter (XML API)
В данной статье будут представлены макросы, для взаимодействия с сервисом 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-шаблонизаторе.
Для примера, выведем информацию о пользователе "umi_cms" в TPL-шаблон "Интернет-магазин" (Хомячки). Откройте файл "/tpls/content/index.tpl" и пропишите макрос "custom twitterScreen" в блоке "<div class="column">":
<div class="column">
%search insert_form('home')%
%custom twitterTimeline('umi_cms')%
</div>
Последние 3 твита пользователя "umi_cms" |
Примечание.
Данный функционал был проверен на работоспособность в версии системы 2.8.5.1. |