Выводим в Top блогов количество постов вместо рейтинга
Для начала находим Экшен блока. Структура LS подробно описана, поэтому легко находим нужный блок: /classes/blocks/BlockBlogs.class.php В блоке вызывается единственная функция: Blog_GetBlogsRating, с ней и будем работать.
Сначала захотелось по-быстрому исправить эту функцию в коде движка, но после недолгих размышлений захотелось сделать правильно и красиво, потому что работа с Livestreet подталкивает к этому. Поэтому, оформим решение в виде модуля, который может оказаться полезным и другим пользователям.
Шаг 1. Инициализируем модуль
Есть достаточно много статей описывающих как написать простой модуль, поэтому останавливаться на этом вопросе не будем. Создаем папку /plugins/topblogs2 и в ней делаем XML описание плагина, файл plugin.xml:
Далее создаем класс активации нашего плагина — /plugins/topblogs2/PluginTopblogs2.class.php:
Шаг 2. Пишем код модуля
Согласно тем названиям, которые мы придумали и объявили в конфигурации плагина код модуля должен находится в файле: /plugins/topblogs2/classes/modules/top/Top.class.php:
Сначала объявляем стандартную функцию GetBlogsRating для того, чтобы переопределить ее в нашем файле. Затем из нее мы вызываем уже нашу функцию GetTopBlogsByPosts, которая и будет делать то что нам нужно. При отладке может возникнуть желание вызвать исходную функцию GetBlogsRating, пример такого вызова в строчке с комментарием.
Обратите внимание, что мы инициализировали свой Маппер, поскольку нам потребуется еще работа с базой данных.
Не применяется кеширование, поскольку мы получаем из Маппера два массива. Придумывать корректный алгоритм было лень, тем более что в моих проектах пока проблемы с нагрузкой не стоит.
Затем мы для всех блогов подменяем поле рейтинг значением из второго массива, содержащего количество постов в каждом блоге. Этот нехитрый трюк позволяет сделать модуль совместимым с абсолютно любым шаблоном, поскольку вся информация в отображение поступает только в стандартных массивах и объектах.
Шаг 3. Пишем код маппера
Маппер у нас окажется тут: /plugins/topblogs2/classes/modules/top/mapper/Top.mapper.class.php.
В отличие от стандартной функции мы возвращаем два массива — массив ID найденных блогов и ассоциативный массив блог->рейтинг. Сделано так потому что в стандартном объекте «блог» нет значения количества постов. Наверно можно было расширить свойства блога, но так было проще. Буду рад услышать предложения и идеи как изменить или улучшить код.
Аналогично нужно изменить функции GetBlogsRatingJoin и GetBlogsRatingSelf чтобы получился законченный модуль.
Сначала захотелось по-быстрому исправить эту функцию в коде движка, но после недолгих размышлений захотелось сделать правильно и красиво, потому что работа с Livestreet подталкивает к этому. Поэтому, оформим решение в виде модуля, который может оказаться полезным и другим пользователям.
Шаг 1. Инициализируем модуль
Есть достаточно много статей описывающих как написать простой модуль, поэтому останавливаться на этом вопросе не будем. Создаем папку /plugins/topblogs2 и в ней делаем XML описание плагина, файл plugin.xml:
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<name>
<lang name="default">TopBlogs2</lang>
</name>
<author>
<lang name="default">Begetan</lang>
</author>
<homepage></homepage>
<version>0.1</version>
<requires>
<livestreet>0.5.0</livestreet>
<plugins>
</plugins>
</requires>
<description>
<lang name="default">Show top rated blogs by count of posts instead of standart LiveStreet blog's rating</lang>
<lang name="russian">Выводит топ блогов по количеству постов, а не по стандартному рейтингу блогов LiveStreet</lang>
</description>
</plugin>
Далее создаем класс активации нашего плагина — /plugins/topblogs2/PluginTopblogs2.class.php:
if (!class_exists('Plugin')) die('Are you sure?');
class PluginTopBlogs2 extends Plugin
{
protected $aInherits=array(
'module' => array('ModuleBlog' => '_ModuleTop'),
);
public function Activate() {
return true;
}
public function Init() {
}
}
Шаг 2. Пишем код модуля
Согласно тем названиям, которые мы придумали и объявили в конфигурации плагина код модуля должен находится в файле: /plugins/topblogs2/classes/modules/top/Top.class.php:
<?php
class PluginTopBlogs2_ModuleTop extends PluginTopBlogs2_Inherit_ModuleBlog {
protected $oMapperBlog2;
public function GetBlogsRating($iCurrPage,$iPerPage) {
$this->oMapperBlog2 = Engine::GetMapper ( __CLASS__ );
# $aResult=parent::GetBlogsRating($iCurrPage, $iPerPage);
$aResult=$this->GetTopBlogsByPosts($iCurrPage, $iPerPage);
return $aResult;
}
public function GetTopBlogsByPosts($iCurrPage,$iPerPage) {
list ($aTopBlogs, $aRating) = $this->oMapperBlog2->GetTopBlogsByPosts($iCount,$iCurrPage,$iPerPage);
$data = array('collection'=>$aTopBlogs,'count'=>$iCount);
$aBlogs = parent::GetBlogsAdditionalData($data['collection'],array('owner'=>array(),'relation_user'));
# Подменяем рейтинг блога на новый
foreach ( $aBlogs as $oBlog ) {
$oBlog->setRating($aRating[$oBlog->getId()]);
$data2[] = $oBlog;
}
# Обновляем список блогов
$data['collection'] = $data2;
return $data;
}
}
?>
Сначала объявляем стандартную функцию GetBlogsRating для того, чтобы переопределить ее в нашем файле. Затем из нее мы вызываем уже нашу функцию GetTopBlogsByPosts, которая и будет делать то что нам нужно. При отладке может возникнуть желание вызвать исходную функцию GetBlogsRating, пример такого вызова в строчке с комментарием.
Обратите внимание, что мы инициализировали свой Маппер, поскольку нам потребуется еще работа с базой данных.
Не применяется кеширование, поскольку мы получаем из Маппера два массива. Придумывать корректный алгоритм было лень, тем более что в моих проектах пока проблемы с нагрузкой не стоит.
Затем мы для всех блогов подменяем поле рейтинг значением из второго массива, содержащего количество постов в каждом блоге. Этот нехитрый трюк позволяет сделать модуль совместимым с абсолютно любым шаблоном, поскольку вся информация в отображение поступает только в стандартных массивах и объектах.
Шаг 3. Пишем код маппера
Маппер у нас окажется тут: /plugins/topblogs2/classes/modules/top/mapper/Top.mapper.class.php.
<?php
class PluginTopBlogs2_ModuleTop_MapperTop extends Mapper {
public function GetTopBlogsByPosts (&$iCount,$iCurrPage,$iPerPage) {
$sql = "SELECT t.blog_id, COUNT(t.blog_id) as rating " .
"FROM ".Config::Get('db.table.topic')." as t " .
"GROUP BY t.blog_id " .
"ORDER BY 2 DESC " .
"LIMIT ?d, ?d";
$aReturn=array();
$aReturn2=array();
if ($aRows=$this->oDb->selectPage($iCount,$sql,($iCurrPage-1)*$iPerPage, $iPerPage)) {
foreach ($aRows as $aRow) {
$aReturn[]=$aRow['blog_id'];
$aReturn2[$aRow['blog_id']]=$aRow['rating'];
}
}
return array ($aReturn, $aReturn2);
}
}
?>
В отличие от стандартной функции мы возвращаем два массива — массив ID найденных блогов и ассоциативный массив блог->рейтинг. Сделано так потому что в стандартном объекте «блог» нет значения количества постов. Наверно можно было расширить свойства блога, но так было проще. Буду рад услышать предложения и идеи как изменить или улучшить код.
Аналогично нужно изменить функции GetBlogsRatingJoin и GetBlogsRatingSelf чтобы получился законченный модуль.
0 комментариев