[image]

Примеры: реализация RSS-потока.

 
+
-
edit
 

Balancer

администратор
★★★★★
Решил, вот, начать публикацию примеров работы с нашим фреймворком. Итак, сегодня были добавлены RSS-потоки в темах, позволяющие отслеживать ответы. Собственно, код RSS-модуля с комментариями по ходу.

code php
  1. <?php
  2. class_include('forum_topic');
  3.  
  4. class forum_topic_rss extends forum_topic
  5. {
  6.     function render_engine() { return 'render_self'; }
  7.  
  8.     function url() { return $this->rss_url(); }
  9.  
  10.     function render()
  11.     {
  12.         include("3part/feedcreator.class.php");
  13.  
  14.         $rss = &new UniversalFeedCreator();
  15.         $rss->encoding = 'utf-8';
  16.         $rss->title = $this->title();
  17.         $rss->description = ec("Ответы в топик ").$this->title();
  18.         $rss->link = parent::url(1);
  19.         $rss->syndicationURL = $this->url();
  20.  
  21.         $db = &new DataBase('punbb');
  22.         foreach($db->get_array("SELECT id FROM posts WHERE topic_id={$this->id()} ORDER BY posted DESC LIMIT 50") as $post_id)
  23.         {
  24.             $item = &new FeedItem();
  25.             $post = class_load('forum_post', $post_id);
  26.             $item->title = $this->title();
  27.             $item->link = $post->url();
  28.  
  29.             $html = $post->body();
  30.             if(strlen($html) > 1024)
  31.             {
  32.                 include_once("funcs/texts.php");
  33.                 $html = strip_text($html, 1024);
  34.                 $html .= "<br /><br /><a href=\"".$post->url(1).ec("\">Дальше »»»");
  35.             }
  36.  
  37.             $item->description = $html;
  38.             $item->date = $post->create_time();
  39.             $item->source = "http://balancer.ru/forum/";
  40.             $item->author = $post->owner()->title();
  41.  
  42.             $rss->addItem($item);
  43.         }
  44.  
  45.         $result = $rss->createFeed("RSS1.0");
  46.         header("Content-Type: ".$rss->contentType."; charset=".$rss->encoding);
  47.         return $result;
  48.     }
  49.  
  50.     function cache_static() { return 600; }
  51. }


Этот модуль не использует 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
  1. <?php
  2. $map = array(
  3. // ...
  4.     '.*/\d{4}/\d{1,2}/\d{1,2}/topic\-(\d+)\-rss\.xml => forum_topic_rss(1)',
  5. );


Т.е. модуль будет отзываться на ссылки вида _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
  1. <?
  2. function body()
  3. {
  4. // ...
  5.     $this->add_template_data_array('header', "<link rel=\"alternate\" type=\"application/rss+xml\" href=\"".$this->rss_url()."\" title=\"Новые сообщения в теме '".addslashes($this->title())."'\" />");
  6. // ...
  7. }


После этого на страницах наших топиков мы увидем соответствующий значок.

Вот, собственно, и всё.
   

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru