<?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_mapper
{
	protected $allowedKeys=array(
		'forum'=>array(
			'name', 'describe', 'total_posts', 'total_themes', 'last_post_date', 'last_user_name',
			'last_user_id', 'closed'
		),
		'theme'=>array(
			'forum_id', 'author_name', 'author_id', 'subject', 'total_posts', 'last_post_date', 'last_user_name',
			'last_user_id', 'pinup', 'hidden'
		),
		'post'=>array(
			'theme_id', 'user_id', 'user_name', 'msg', 'email', 'putdate', 'ip', 'edited', 'hidden',
			'total_votes', 'vote_result', 'rating', 'first'
		)
	);

	/******* форумы ********/
	public function getAllForums(&$count)
	{
		$data=Db::i()->selectPage($count, "SELECT forum_id FROM ?_forum_forums");
		$result=array();
		if ($data) {
			foreach ($data as $item) {
				$result[]=$item['forum_id'];
			}
		}
		return $result;
	}

	public function getForumsByArrayId($id)
	{
		$result=Db::i()->select(
			"SELECT *
			FROM ?_forum_forums
			WHERE forum_id IN(?a)
			ORDER BY FIELD(forum_id, ?a)",
			$id, $id
		);

		$data=array();
		if ($result) {
			foreach ($result as $item) {
				$obj=Factory::create('forum.forum_entity', $item);
				$data[$obj->id]=$obj;
			}
		}
		return $data;
	}

	public function addForum($forum)
	{
		$insert=$forum->getFilteredKeys($this->allowedKeys['forum']);
		$forum->id=Db::i()->query("INSERT INTO ?_forum_forums (?#) VALUES(?a)", array_keys($insert), array_values($insert));
		return $forum;
	}

	public function updateForum($forum)
	{
		$data=$forum->getFilteredKeys($this->allowedKeys['forum']);
		return Db::i()->query("UPDATE ?_forum_forums SET ?a WHERE forum_id=?", $data, $forum->id);
	}

	public function deleteForum($forum)
	{
		return Db::i()->query("DELETE FROM ?_forum_forums WHERE forum_id=?", $forum->id);
	}

	/******* темы ********/
	public function getThemesByFilter(&$count, $filter, $page, $atPage)
	{
		if (empty($filter['pinups']) && empty($filter['orderby'])) {
			$orderby='last_post_date DESC';
		} elseif(!empty($filter['orderby'])) {
			$orderby=$filter['orderby'];
		} else {
			$orderby='pinup DESC, last_post_date DESC';
		}

		$data=Db::i()->selectPage(
			$count, 
			"SELECT theme_id
			FROM ?_forum_themes
			WHERE 1=1
			{AND forum_id=?}
			{AND hidden=?}
			{AND hidden<>?}
			{AND author_id=?}
			ORDER BY ".$orderby."
			LIMIT ?d, ?d",
			empty($filter['forum_id'])?DBSIMPLE_SKIP:$filter['forum_id'],
			empty($filter['show_hidden'])?0:DBSIMPLE_SKIP,
			empty($filter['show_only_hidden'])?DBSIMPLE_SKIP:0,
			empty($filter['user_id'])?DBSIMPLE_SKIP:$filter['user_id'],
			($page-1)*$atPage, $atPage
		);

		$result=array();
		if ($data) {
			foreach ($data as $item) {
				$result[]=$item['theme_id'];
			}
		}
		return $result;
	}

	public function getThemesByString(&$count, $string, $page, $atPage, $filter)
	{
		//разделяем фразу на отдельные слова, выделяем у них корень и составляем поисковый запрос
		$text_array=explode(" ", preg_replace('/[\s]+/', ' ', trim($string)));
		$stemmer = Factory::create('Stem_Ru');
		
		//формируем условия для всех слов
		$query_text='';
		foreach ($text_array as $val) {
			$query_text.="+".$stemmer->stem_word($val)."* ";
		}

		$data=Db::i()->selectPage(
			$count,
			"SELECT t.theme_id
			FROM ?_forum_posts p
			JOIN ?_forum_themes t ON p.theme_id=t.theme_id
			WHERE (MATCH(p.msg) AGAINST(? IN BOOLEAN MODE)
			OR MATCH(t.subject) AGAINST(? IN BOOLEAN MODE))
			{AND forum_id=?}
			{AND p.hidden=?}
			{AND t.hidden=?}
			GROUP BY t.theme_id
			ORDER BY t.last_post_date DESC
			LIMIT ?d, ?d",
			$query_text, $query_text,
			empty($filter['forum_id'])?DBSIMPLE_SKIP:$filter['forum_id'],
			empty($filter['show_hidden'])?0:DBSIMPLE_SKIP,
			empty($filter['show_hidden'])?0:DBSIMPLE_SKIP,
			($page-1)*$atPage, $atPage
		);

		$result=array();
		if ($data) {
			foreach ($data as $item) {
				$result[]=$item['theme_id'];
			}
		}
		return $result;
	}

	public function getThemesByArrayId($id)
	{
		$result=Db::i()->select(
			"SELECT * FROM ?_forum_themes WHERE theme_id IN(?a)
			ORDER BY FIELD(theme_id, ?a)",
			$id, $id
		);

		$data=array();
		if ($result) {
			foreach ($result as $item) {
				$obj=Factory::create('forum.theme_entity', $item);
				$data[$obj->id]=$obj;
			}
		}
		return $data;
	}

	public function updateTheme($theme)
	{
		$data=$theme->getFilteredKeys($this->allowedKeys['theme']);
		return Db::i()->query("UPDATE ?_forum_themes SET ?a WHERE theme_id=?", $data, $theme->id);
	}

	public function addTheme($theme)
	{
		$data=$theme->getFilteredKeys($this->allowedKeys['theme']);
		$theme->id=Db::i()->query(
			"INSERT INTO ?_forum_themes	(?#) VALUES (?a)", array_keys($data), array_values($data)
		);
	}

	public function deleteTheme($theme)
	{
		return Db::i()->query("DELETE FROM ?_forum_themes	WHERE theme_id=?", $theme->id);
	}

	public function hideThemesByForum($forum)
	{
		return Db::i()->query("UPDATE ?_forum_themes SET hidden=? WHERE forum_id=?", User::i()->id, $forum->id);
	}

	/******* посты ********/
	public function getPostsByFilter(&$count, $filter, $page, $atPage)
	{
		$order=(!empty($filter['order']))?$filter['order']:'putdate';

		$data=Db::i()->selectPage(
			$count,
			"SELECT post_id
			FROM ?_forum_posts
			WHERE
			1=1
			{AND theme_id=?}
			{AND hidden=?}
			{AND hidden<>?}
			{AND user_id=?}
			ORDER BY ".$order."
			LIMIT ?d, ?d",
			isset($filter['theme_id'])?$filter['theme_id']:DBSIMPLE_SKIP,
			empty($filter['show_hidden'])?0:DBSIMPLE_SKIP,
			empty($filter['show_only_hidden'])?DBSIMPLE_SKIP:0,
			empty($filter['user_id'])?DBSIMPLE_SKIP:$filter['user_id'],
			($page-1)*$atPage, $atPage
		);

		$result=array();
		if ($data) {
			foreach ($data as $item) {
				$result[]=$item['post_id'];
			}
		}
		return $result;
	}

	public function getPostsByArrayId($id)
	{
		$result=Db::i()->select(
			"SELECT * FROM ?_forum_posts WHERE post_id IN(?a)
			ORDER BY FIELD(post_id, ?a)",
			$id, $id
		);

		$data=array();
		if ($result) {
			foreach ($result as $item) {
				$item['ip']=inet_ntop($item['ip']);
				$obj=Factory::create('forum.post_entity', $item);
				$data[$obj->id]=$obj;
			}
		}
		return $data;
	}

	public function addPost($post)
	{
		$data=$post->getFilteredKeys($this->allowedKeys['post']);
		$data['ip']=inet_pton($data['ip']);
		$post->id=Db::i()->query(
			"INSERT INTO ?_forum_posts	(?#) VALUES (?a)", array_keys($data), array_values($data)
		);
	}

	public function updatePost($post)
	{
		$data=$post->getFilteredKeys($this->allowedKeys['post']);
		$data['ip']=inet_pton($data['ip']);
		return Db::i()->query("UPDATE ?_forum_posts SET ?a WHERE post_id=?", $data, $post->id);
	}

	public function movePostsToTheme($post, $theme)
	{
		return Db::i()->query(
			"UPDATE ?_forum_posts SET theme_id=?
			WHERE theme_id=?
			AND putdate>=?",
			$theme->id,
			$post->theme->id,
			$post->putdate
		);
	}

	public function deletePost($post)
	{
		return	Db::i()->query("DELETE FROM ?_forum_posts WHERE post_id=?", $post->id);

	}

	public function hidePostsByTheme($theme)
	{
		return Db::i()->query("UPDATE ?_forum_posts SET hidden=? WHERE theme_id=?", User::i()->id, $theme->id);
	}

	public function deletePostsByIds($ids)
	{
		return Db::i()->query("DELETE FROM ?_forum_posts WHERE post_id IN(?a)", $ids);
	}
}