Руководство: Как обеспечить вывод топиков по типу.

В данной статье хотел бы рассказать о реализации фильтрации по типам топиков в блоге.

(навеяно livestreet.ru/blog/sollutions/206.html)
Чтобы создать свой вид топика, см. Создание своего вида топика

Для начала как всё это выглядит:
У меня:




На харбре:



Для фильтрации нам необходимо:
1. Создать ссылки вида /blog/название_блога/тип_топика/ в шаблоне смарти. У себя я это реализовал вот так:

    {if $sMenuSubItemSelect=='topic'}
		<span>Статьи ({$iCountTopics})</span>
	{else}
		<a class="{$sel}" href="{$DIR_WEB_ROOT}/blog/{$oBlog->getUrl()}/topic/">Статьи ({$iCountTopics})</a> 
	{/if}

	{if $sMenuSubItemSelect=='place'}
		<span>Мероприятия ({$iCountPlaces})</span>
	{else}
		<a class="{$sel}" href="{$DIR_WEB_ROOT}/blog/{$oBlog->getUrl()}/event/">Места ({$iCountPlaces})</a> 
	{/if}

(конец файла шаблона actions/actionBlog/blog.tpl)
Переменные в шаблоне:
$sMenuSubItemSelect — выбранный пункт меню
$iCountTopics — число топиков для данного блога
$oBlog->getUrl() — урл блога

Если выбранный пункт меню topic, то выводится просто текст (ссылка нажата), если не topic, выводится ссылка.

2. Добавить эвенты:
Если мы реализуем вывод через ссылки вышеупомянутого вида, то за вывод отвечает экншн «blog»(/classes/actions/ActionBlog.class.php).
В этом экшене в методе RegisterEvent указываются эвенты, которые будут вызываться.
У меня это выглядит так:

	$this->AddEventPreg('/^\w+$/i','/^topic$/i','/^$/i','EventShowBlogTopicByType');
	$this->AddEventPreg('/^\w+$/i','/^topic$/i','/^page(\d+)$/i','EventShowBlogTopicByType');		
	
	$this->AddEventPreg('/^\w+$/i','/^place$/i','/^$/i','EventShowBlogTopicByType');
	$this->AddEventPreg('/^\w+$/i','/^place$/i','/^page(\d+)$/i','EventShowBlogTopicByType');		

Что же это такое?
В этих строках добавляется эвент для урл вида /blog/название_блога/topic/ и /blog/название_блога/place/ с помощью регулярных выражений. Для обычного вывода и вывода постраничного.
Т.е. если пользователь переходит по ссылке place, то вызывается метод EventShowBlogTopicByType
3. Добавить функцию для эвентов:
Итак, теперь необходимо описать метод EventShowBlogTopicByType. За основу я взял метод
EventShowBlogNew:


	protected function EventShowBlogTopicByType() {
		$sBlogUrl=$this->sCurrentEvent;
		$sPage=$this->getParam(1);
		$type=$this->getParam(0);
		
		
		/**
		 * Меню
		 */
		$this->sMenuSubItemSelect=$type;
		$this->sMenuSubBlogUrl=DIR_WEB_ROOT.'/blog/'.$sBlogUrl;
		/**
		 * Проверяем есть ли блог с таким УРЛ
		 */
		if (!($oBlog=$this->Blog_GetBlogByUrl($sBlogUrl))) {
			return parent::EventNotFound();
		}			
		/**
		 * Проверяем является ли текущий пользователь пользователем блога
		 */
		$bNeedJoin=true;
		if ($this->oUserCurrent) {
			if ($this->Blog_GetRelationBlogUserByBlogIdAndUserId($oBlog->getId(),$this->oUserCurrent->getId())) {
				$bNeedJoin=false;
			}
		}
		/**
		 * Передан ли номер страницы
		 */
		if (preg_match("/^page(\d+)$/i",$sPage,$aMatch)) {			
			$iPage=$aMatch[1];
		} else {
			$iPage=1;
		}		
		/**
		 * Получаем список топиков
		 */
		$iCount=0;			
		$aResult=$this->Topic_GetTopicsByTopicType($oBlog,$iCount,$iPage,BLOG_TOPIC_PER_PAGE,$type);	
		$aTopics=$aResult['collection'];	
		/**
		 * Формируем постраничность
		 */			
		$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,BLOG_TOPIC_PER_PAGE,4,DIR_WEB_ROOT.'/blog/'.$sBlogUrl.'');			
		/**
		 * Получаем число новых топиков в текущем блоге
		 */
		$this->iCountTopicsBlogNew=$this->Topic_GetCountTopicsByBlogNew($oBlog);		
		/**
		 * Загружаем переменные в шаблон
		 */		
		$this->Viewer_Assign('sMenuSubItemSelected',$this->sMenuSubItemSelect);
		$this->Viewer_Assign('aPaging',$aPaging);
		$this->Viewer_Assign('aTopics',$aTopics);
		$this->Viewer_Assign('oBlog',$oBlog);
		$this->Viewer_Assign('bNeedJoin',$bNeedJoin);
		$this->Viewer_AddHtmlTitle($oBlog->getTitle());
		/**
		 * Устанавливаем шаблон вывода
		 */
		$this->SetTemplateAction('blog');
	}

Данная функция служит для вывода коллекции топиков (aTopics)в смарти. Последняя строчка содержит название шаблона blog, соответственно используется шаблон actions/ActionBlog/blog.tpl

В этой функции появилась новая переменная $type, в которой хранится тип топика, взятый из УРЛа. Эта переменная передается в Topic_GetTopicsByTopicType, функцию которая должна быть создана в классе classes/modules/topic/Topic.class.php
Код функции:

	public function GetTopicsByTopicType($oBlog,$iCount,$iPage,$iPerPage,$type) {
		$aFilter=array(
			'topic_publish' => 1,
			'blog_id' => $oBlog->getId(),
			'topic_type'  => array(
				$type,
			),
		);
		return $this->GetTopicsByFilter($aFilter,$iPage,$iPerPage);		
	}

Функция забирает из базы все топики для указанного блога с указанным типом.
Для корректной работы нам потребуется подправить метод buildFilter из класса classes/modules/topic/mapper/Topic.mapper.class.php. В него необходимо добавить пару строчек:

		if (isset($aFilter['topic_type']) and is_array($aFilter['topic_type'])) {
			$sWhere.=" AND t.topic_type in ('".join("','",$aFilter['topic_type'])."') ";
		}


На этом всё. Если понадобится пример работы, могу скинуть в личку.

10 комментариев

avatar
ап
avatar
Спасибо, добавил в закладки.
avatar
на здоровье:)
avatar
Оч. круто, спасибо!
avatar
  • ort
  • 0
avatar
Супер! Спасибо огромное, это как раз то, за что я планировал платить программисту! (Которого еще и не найдешь) =)
avatar
кстати, под 0.3 это будет работать?
avatar
и всетаки, работать будет с 0.3.1?
Если кто знает, подскажите
avatar
Да все работает под 0.3.1
только во втором пункте вместо:

$this->AddEventPreg('/^\w+$/i','/^topic$/i','/^$/i','EventShowBlogTopicByType');
$this->AddEventPreg('/^\w+$/i','/^topic$/i','/^page(\d+)$/i','EventShowBlogTopicByType');               
        
$this->AddEventPreg('/^\w+$/i','/^place$/i','/^$/i','EventShowBlogTopicByType');
$this->AddEventPreg('/^\w+$/i','/^place$/i','/^page(\d+)$/i','EventShowBlogTopicByType');

я поставил:

$this->AddEventPreg('/^[\w\-\_]+$/i','/^topic$/i','/^$/i','EventShowBlogTopicByType');
$this->AddEventPreg('/^[\w\-\_]+$/i','/^topic$/i','/^page(\d+)$/i','EventShowBlogTopicByType');               

$this->AddEventPreg('/^[\w\-\_]+$/i','/^place$/i','/^$/i','EventShowBlogTopicByType');
$this->AddEventPreg('/^[\w\-\_]+$/i','/^place$/i','/^page(\d+)$/i','EventShowBlogTopicByType');
avatar
Реализовывал ли кто-нибудь к 0.5.1?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.