Решил, вот, начать публикацию примеров работы с нашим фреймворком. Итак, сегодня были добавлены RSS-потоки в темах, позволяющие отслеживать ответы. Собственно, код RSS-модуля с комментариями по ходу.
code php
<?php
class_include('forum_topic');
class forum_topic_rss extends forum_topic
{
function render_engine() { return 'render_self'; }
function url() { return $this->rss_url(); }
function render()
{
include("3part/feedcreator.class.php");
$rss = &new UniversalFeedCreator();
$rss->encoding = 'utf-8';
$rss->title = $this->title();
$rss->description = ec("Ответы в топик ").$this->title();
$rss->link = parent
::url(1);
$rss->syndicationURL = $this->url();
$db = &new DataBase('punbb');
foreach($db->get_array("SELECT id FROM posts WHERE topic_id={$this->id()} ORDER BY posted DESC LIMIT 50") as $post_id)
{
$item = &new FeedItem();
$post = class_load('forum_post', $post_id);
$item->title = $this->title();
$item->link = $post->url();
$html = $post->body();
{
include_once("funcs/texts.php");
$html = strip_text($html, 1024);
$html .= "<br /><br /><a href=\"".$post->url(1).ec("\">Дальше »»»");
}
$item->description = $html;
$item->date = $post->create_time();
$item->source = "http://balancer.ru/forum/";
$item->author = $post->owner()->title();
$rss->addItem($item);
}
$result = $rss->createFeed("RSS1.0");
header("Content-Type: ".$rss->contentType."; charset=".$rss->encoding);
return $result;
}
function cache_static() { return 600; }
}
Этот модуль не использует ORM, являясь наследником базового класса forum_topic, который уже и обеспечивает все данные. Используется сторонний класс генерации RSS -
feedcreator.class.php, распространяющийся под LGPL лицензией.
Прокомментирую код.class_include('forum_topic');
Загружаем базовый класс по его имени. Система будет искать его как
forum/topic.php в корне или подкаталоге
bors/ каталогов BORS_INCLUDE, BORS_INCLUDE/vhosts/<имя_виртхоста> и BORS_INCLUDE_LOCAL.
class forum_topic_rss extends forum_topic
Создаём свой класс в файле
forum/topic/rss.php.
function render_engine() { return 'render_self'; }
Наш класс всю генерацию кода берёт на себя, поставляя не "запчасти" для сборки страницы сторонними классами, а обеспечивая метод, генерирующий данные "под ключ".
function url() { return $this->rss_url(); }
Собственная ссылка на RSS. Для удобства использования определена в классе-родителе, тут - только перенаправление вызова. url классов требуются как для вставки ссылок на них в шаблонах, так и для хранения статического кеша.
function render()
Функция render в классах рендеринга обеспечивает выдачу окончательного вида данных.
include("3part/feedcreator.class.php");
Используем сторонний класс для генерации RSS-фида.
$rss->title = $this->title();
Таким образом извлекаются наши данные. Заголовок - заголовок родительского класса, топика.
$db = &new DataBase('punbb');
Грязное решение, обычно экземпляр класса драйвера базы данных в рабочих классах заводить не нужно, например, когда они наследуются от класса def_dbpage. Но у нас ситуация особая, исторически сложилось, что классы форума от него не наследуются. Нужно будет изменить в будущем. Пока же инициируем драйвер базы данных
punbb.
$db->get_array("SELECT id FROM posts WHERE topic_id={$this->id()} ORDER BY posted DESC LIMIT 50")
Тут, вроде бы, понятно всё без комментариев. Читаем последние 50 сообщений топика и возвращаем массив их идентификаторов.
foreach(... as $post_id)
Цикл по ним.
$post = class_load('forum_post', $post_id);
Загружаем экземпляр класса постинга форума.
$item->title = $this->title();
Просто пример доступа к данным. Это заголовок топика.
$item->link = $post->url();
А это - ссылка на сообщение.
$html = $post->body();
Читаем HTML-код постинга.
if(strlen($html) > 1024)
Если длина больше 1024, то отсекаем конец, добавляя ссылку.
header("Content-Type: ".$rss->contentType."; charset=".$rss->encoding);
Поскольку мы создаём все данные сами, то надо и о заголовке позаботиться.
function cache_static() { return 600; }
Сообщаем системе, что она должна использовать статический кеш, который будет храниться 10 минут.
По классу - всё.
Теперь о его вызове.
В
BORS_INCLUDE/handlers/bors_map.php прописываем привязку этого класса к URL:
code text
<?php
$map = array(
// ...
'.*/\d{4}/\d{1,2}/\d{1,2}/topic\-(\d+)\-rss\.xml => forum_topic_rss(1)',
);
Т.е. модуль будет отзываться на ссылки вида _http://balancer.ru/society/2007/09/18/topic-56272-rss.xml. При совпадении шаблона ссылки будет создаваться экземпляр класса forum_topic_rss(56272), где 56272 - id топика.
Всё, наш RSS уже работает.
Можно его ещё прописать в HEAD-теги страницы топика, чтобы браузер знал об этом. В любой метод класса forum_topic, вызывающийся при генерации страницы (конструктор, body(), template() и т.д. и т.п.) можно вписать медод, добавляющий строчку в хедер шаблона страницы:
code php
<?
function body()
{
// ...
$this->add_template_data_array('header', "<link rel=\"alternate\" type=\"application/rss+xml\" href=\"".$this->rss_url()."\" title=\"Новые сообщения в теме '".addslashes($this->title())."'\" />");
// ...
}
После этого на страницах наших топиков мы увидем соответствующий значок.
Вот, собственно, и всё.