<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

class forum_theme extends DefaultObject
{
	protected $cache_key='forum_theme_';

	public function __construct($mapper=null)
	{
		if (is_object($mapper)) {
			$this->mapper=$mapper;
		} else {
			$this->mapper=Factory::create('forum.mapper');
		}
		Factory::load('forum.theme_entity');
	}

	public function getThemesByForum($forum, $page, $atPage)
	{
		$filter=array(
			'show_hidden'=>access('admin'),
			'pinups'=>1,
			'forum_id'=>$forum->id
		);

		return $this->getThemesByFilter($filter, $page, $atPage);
	}

	public function getLastThemeByForum($forum) {
		$filter=array(
			'forum_id'=>$forum->id,
			'show_hidden'=>0,
			'orderby'=>'last_post_date DESC'
		);
		$themes=$this->getThemesByFilter($filter, 1, 1);
		return array_shift($themes['collection']);
	}

	public function getThemesByFilter($filter, $page, $atPage)
	{
		$page=(intval($page)<=0)?1:intval($page);

		$key='forum_themes_by_filter_'.md5(serialize($filter)).'_'.$page.'_'.$atPage;
		if (false === ($data=TCache::get($key))) {
			$data = array(
				'collection'=>$this->mapper->getThemesByFilter($count, $filter, $page, $atPage),
				'count'=>$count
			);
			TCache::set($data, $key, array($this->_getCacheKeyCommon()));
		}

		$data['collection'] = $this->getThemesByArrayId($data['collection']);
		return $data;
	}

	public function getThemesByString($string, $page, $atPage, $filter)
	{
		$page=(intval($page)<=0)?1:intval($page);

		$key='forum_themes_by_string_'.md5($string.serialize($filter)).'_'.$page.'_'.$atPage;
		if (false === ($data=TCache::get($key))) {
			$data = array(
				'collection'=>$this->mapper->getThemesByString($count, $string, $page, $atPage, $filter),
				'count'=>$count
			);
			TCache::set($data, $key, array($this->_getCacheKeyCommon()));
		}

		$data['collection'] = $this->getThemesByArrayId($data['collection']);
		return $data;
	}

	public function add($theme)
	{
		return $this->mapper->addTheme($theme);
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
	}

	public function update($theme)
	{
		$this->mapper->updateTheme($theme);
		TCache::remove($this->_getCacheKey().$theme->id);
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
	}

	public function delete($theme)
	{
		$this->_getPost()->hidePostsByTheme($theme);
		$this->updateStat($theme, -$theme->total_posts);

		$this->_getPost()->deletePostsByTheme($theme);
		$this->mapper->deleteTheme($theme);

		TCache::remove($this->_getCacheKey().$theme->id);
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));

		if (!$theme->hidden) {
			$this->_getForum()->updateStat($theme->forum, -$theme->total_posts, -1);
		}
		return true;
	}
	
	public function hideThemesByForum($forum)
	{
		$this->mapper->hideThemesByForum($forum);
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));

	}

	public function deleteThemesByForum($forum)
	{
		$filter=array(
			'forum_id'=>$forum->id,
			'show_hidden'=>true,
			'order'=>'last_post_date'
		);

		//удаляем по тридцать тем начиная с конца форума
		$themes=array('count'=>1);
		while ($themes['count']) {
			if ($themes=$this->getThemesByFilter($filter, 1, 30)) {
				foreach ($themes['collection'] as $theme) {
					$this->delete($theme);
				}
			}
		}
		
	}

	public function getThemeById($id)
	{
		$data=$this->getThemesByArrayId(array($id));
		if (isset($data[$id])) {
			return $data[$id];
		}
		return null;
	}

	public function getThemesByArrayId($id)
	{
		$data=$this->_getItemsByArrayId($id);
		if ($data) {
			$this->_setAddtitionalData($data);
		}
		return $data;
	}

	public function _getItemsByArrayIdFromStorage($id)
	{
		return $this->mapper->getThemesByArrayId($id);
	}

	protected function _setAddtitionalData(&$themes)
	{
		$users=$forums=array();
		foreach ($themes as $theme) {
			if ($theme->author_id) $users[]=$theme->author_id;
			if ($theme->last_user_id) $users[]=$theme->last_user_id;
			if ($theme->hidden) $users[]=$theme->hidden;
			$forums[]=$theme->forum_id;
		}

		$users=User::i()->getUsersByIds($users);
		$forums=$this->_getForum()->getForumsByArrayId($forums);

		foreach ($themes as $theme) {
			$theme->forum=$forums[$theme->forum_id];
			$theme->author=$this->getUserObj($theme->author_id, $users, array('login'=>$theme->author_name));
			$theme->last_user=$this->getUserObj($theme->last_user_id, $users, array('login'=>$theme->last_user_name));
			$theme->hidden_by=$this->getUserObj($theme->hidden, $users);
		}
	}

	
	public function toggle($theme)
	{
		$theme->pinup=$theme->pinup?0:1;
		$this->update($theme);
	}

	public function hide($theme)
	{
		if ($theme->hidden) return false;
		$theme->hidden_by=User::i()->getCurrentUser();

		$this->update($theme);
		$this->_getForum()->updateStat($theme->forum, -$theme->total_posts, -1);
		return true;
	}

	public function unhide($theme)
	{
		if (!$theme->hidden) return false;
		$theme->hidden_by=null;

		$this->update($theme);
		$this->_getForum()->updateStat($theme->forum, $theme->total_posts, 1);
		return true;
	}

	public function moveToForum($theme, $new_forum)
	{
		$old_forum=$theme->forum;
		$theme->forum=$new_forum;
		$this->update($theme);
		$this->_getForum()->updateStat($new_forum, $theme->total_posts, 1);
		$this->_getForum()->updateStat($old_forum, -($theme->total_posts), -1);
	}

	public function updateStat($theme, $count_post, $count_theme=0, $last_user=null, $last_post_date=null)
	{
		if (!is_object($last_user)) {
			if ($post=$this->_getPost()->getLastPostByTheme($theme)) {
				$last_user=$post->user;
				$last_post_date=$post->putdate;
			}
		}

		$theme->total_posts+=$count_post;
		$theme->last_user=$last_user;
		$theme->last_post_date=$last_post_date;


		$this->update($theme);
		$this->_getForum()->updateStat($theme->forum, $count_post, $count_theme, $last_user, $last_post_date);
	}

	public function extract($data, $post)
	{
		$theme=Factory::create('forum.theme_entity', $data);
		$theme->author=$post->user;

		if ($data['forum_id']!=$post->theme->forum->id) {
			$theme->forum=$this->_getForum()->getForumById($data['forum_id']);
		} else {
			$theme->forum=$post->theme->forum;
		}

		//создаем новую тему
		$this->add($theme);

		//переносим в нее посты
		$moved_count=$this->_getPost()->moveToTheme($post, $theme);
		
		//обновляем статистику темы
		$this->updateStat($theme, $moved_count, 1);
		$this->updateStat($post->theme, -$moved_count);
		
		//помечаем пост как первый и отмечаем кто его исправлял
		$post->first=1;
		$post->theme=$theme;
		if ($post->user->id!=User::i()->id) $post->edited_by=User::i()->id;
		$this->_getPost()->update($post);
		return $theme;
	}

	public function buildExtractForm()
	{
		$form = Factory::create('HTML_QuickForm2', null, 'post', array('action'=>''));
		$token=$form->addElement('hidden', 'token', array('value' => User::i()->token));
		
		$name=$form->addElement('text', 'subject', null, array('label' => _m('Название темы:')));
		$name->addRule('required', _m('Нужно указать тему сообщения'), null, $this->validation);

		$allFourms=$this->_getForum()->getAllForumsArray();

		$name=$form->addElement('select', 'forum_id', null, array('options'=>$allFourms, 'label' => _m('Перенести в форум:')));
		$form->addElement('submit', null, array('value'=>_m('Сохранить')));
		return $form;
	}

	public function resetCommonCache()
	{
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
	}

	protected function _getPost()
	{
		return Factory::create('forum.post');
	}

	protected function _getForum()
	{
		return Factory::create('forum.forum');
	}
}