<?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 bug_tracker_post extends DefaultObject
{
	protected $cache_key='bt_post_';

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

	public function getPostsByItem($item, $page=1)
	{
		$page=(intval($page)<=0)?1:intval($page);

		$key='bug_tracker_posts_by_item_'.$item->id.'_'.$page;
		if (false === ($data=TCache::get($key))) {
			$data = array(
				'collection'=>$this->mapper->getPostsByItem($count, $item, $page),
				'count'=>$count
			);
			TCache::set($data, $key, array($this->_getCacheKeyCommon()));
		}

		$data['collection'] = $this->getPostsByArrayId($data['collection']);

		return $data;
	}

	public function getLastPosts($limit)
	{
		$key='bug_tracker_last_posts_'.$limit;
		if (false === ($data=TCache::get($key))) {
			$data = $this->mapper->getLastPosts($limit);
			TCache::set($data, $key, array($this->_getCacheKeyCommon()));
		}
		return $this->getPostsByArrayId($data);
	}

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

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

	public function add($post)
	{
		$this->mapper->addPost($post);
		if (is_array($post->files)) {
			$file_obj=$this->_getFile();
			foreach ($post->files as $file) {
				$file->post_id=$post->id;
				$file_obj->update($file);
			}
		}
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
		return $post;
	}

	public function update($post)
	{
		TCache::remove($this->_getCacheKey().$post->id);
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
		$this->mapper->updatePost($post);
	}
	
	public function delete($posts)
	{
		if (!is_array($posts)) $posts=array($posts->id=>$posts);
		$this->mapper->deletePosts($posts);
		foreach ($posts as $post) {
			if ($post->files) {
				foreach ($post->files as $file) {
					$this->_getFile()->delete($file);
				}
			}
			$this->_getItem()->updateLastPost($post->bug);
			TCache::remove($this->_getCacheKey().$post->id);
		}
		TCache::clean('MATCH_TAG', array($this->_getCacheKeyCommon()));
	}
	
	public function deleteFilesByIds($post, $ids)
	{
		$fileObj=$this->_getFile();
		foreach ($post->files as $file) {
			if (in_array($file->id, $ids)) {
				$fileObj->delete($file);
			}
		}
	}

	protected function _getItemsByArrayIdFromStorage($id)
	{
		return $this->mapper->getPostsByArrayId($id);
	}

	protected function _setAddtitionalData(&$posts)
	{
		$users=$items=array();
		foreach ($posts as $post) {
			$users[]=$post->user_id;
			$items[]=$post->bug_id;
		}

		//добавляем пользователей
		if ($users=User::i()->getUsersByIds($users)) {
			foreach ($posts as $post) {
				$post->user=$this->getUserObj($post->user_id, $users);
			}
		}

		//добавляем родителей
		if ($items=$this->_getItem()->getItemsByArrayId($items)) {
			foreach ($posts as $post) {
				$post->bug=$items[$post->bug_id];
			}
		}

		if ($files=$this->_getFile()->getFilesByPosts($posts)) {
			foreach ($files as $file) {
				$posts[$file->post_id]->addFile($file);
			}
		}
	}

	public function addFilesToPost($files, $post)
	{
		$this->_getFile()->upload($files, $post);
	}

	public function buildEditForm($post=null, $first=false)
	{
		$form=Factory::create('HTML_QuickForm2', null, 'post', array('action'=>''), false);

		$token=$form->addElement('hidden', 'token', array('value'=>User::i()->token));

		if ($first || ($post && $post->isFirst())) {
			$summary=$form->addElement('text', 'summary', null,	array('label'=>'Тема'));
			$summary->addRule('required', _m('Не заполнена тема сообщения'), null, $this->validation);
			
			$type=$form->addElement(
				'select', 'type', null,	array('options'=>array(1=>_m("Ошибка"), 2=>_m("Доработка")), 'label'=>'Тип')
			);
			$type->addRule('required', _m('Необходимо указать тип сообщения'), null, $this->validation);
			
			$version=Factory::create('bug_tracker.version');
			$version=$form->addElement('select', 'version_id', null,	array('options'=>$version->getSupportedVersionsArray(), 'label'=>'Версия'));
			$version->addRule('required', _m('Необходимо указать версию'), null, $this->validation);
		}
		
		$msg=$form->addElement(
			'textarea', 'msg',
			array(
				'class'=>'bbcode',
				'rows'=>5,
				'cols'=>50
			),
			array('label'=>_m('Комментарий'))
		);
		
		if ($post && $post->files) {
			foreach ($post->files as $file) {
				if ($file->isImage()) {
					$form->addElement(
						'checkbox', 'del['.$file->id.']', null,
						array('content'=>'<img src="'.$file->path['small'].'" />', 'label'=>'удалить')
					);
				} else {
					$form->addElement(
						'checkbox', 'del['.$file->id.']', null,
						array('content'=>htmlspecialchars($file->name), 'label'=>'удалить')
					);
				}
			}
		}

		$form->addElement(
			'static', null, null, array(
				'content'=>(config::get('allowed_types'))?'<div>'._m('Разрешены следующие типы файлов:')
				.' '.config::get('allowed_types').'<div>':''
				.(config::get('max_upload_size'))?'<div>'._m('не более').' '.config::get('max_upload_size').'Кб</div>':''
			)
		);

		$file=$form->addElement(
			'file', 'shot[]',
			array('id'=>'shot', 'multiple'=>'multiple'), array('label'=>_m('Добавить файлы или скриншоты'))
		);
		
		$file->addRule('callback', 'Ошибка загрузки файла', array('callback'=>array($this, 'checkFiles')));

		$form->addElement(
			'submit', null, array('value'=>_m('Сохранить')),
			array('label'=>'&nbsp;')
		);
		
		
		$msg->addRule(
			'required', _m('Не заполнен текст сообщения'), null, $this->validation
		);

		if ($post) {
			$data=$post->getArray();
			$data['summary']=$post->bug->summary;
			$data['version_id']=$post->bug->version_id;
			$form->addDataSource(Factory::create('HTML_QuickForm2_DataSource_Array', $data));
		}
		
		return $form;
	}

	public function checkFiles($files)
	{
		if (is_array($files)) {
			foreach ($files as $key=>$file) {
				if (empty($file['size']) && count($files)==1) {
					continue;
				}
			
				if (config::get('max_upload_size') && $file['size']>config::get('max_upload_size')*1024) {
					LabCMS::i()->error(sprintf(_m("Файл %s слишком большой"), $file['name']));
				}
				
				if (config::get('allowed_types')) {
					$info=pathinfo(strtolower($file['name']));
					if (!in_array($info['extension'], config::get('allowed_types'))) {
						LabCMS::i()->error(sprintf(_m("Данный тип файлов (%s) не разрешен для загрузки"), $info['extension']));
					}
				}
			}
			if (LabCMS::i()->isError()) return false;
		}
		return true;
	}

	protected function _getFile()
	{
		return Factory::create('bug_tracker.file');
	}

	protected function _getItem()
	{
		return Factory::create('bug_tracker.item');
	}
}
