<?php 

// h-source, a web software to build a community of people that want to share their hardware information.
// Copyright (C) 2010  Antonio Gallo (h-source-copyright.txt)
//
// This file is part of h-source
//
// h-source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// h-source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with h-source.  If not, see <http://www.gnu.org/licenses/>.

if (!defined('EG')) die('Direct access not allowed!');

class HistoryController extends BaseController
{

	public static $typeTable = array(
		'message'			=>	'message',
		'talk'				=>	'talk',
		'user'				=>	'user',
		'issue'				=>	'issue',
		'wiki_talk'			=>	'wiki talk',
		'page'				=>	'wiki page',
		'page_del'			=>	'wiki page',
		'device'			=>	'device page',
		'device_app'		=>	'device page',
		'device_cl'			=>	'device page',
		'issue_del'			=>	'issue',	//registered
		'issue_ins'			=>	'issue',	//registered
		'message_ins'		=>	'message',	//registered
		'talk_ins'			=>	'talk',		//registered
		'wiki_talk_ins'		=>	'wiki talk',//registered
		'hardware'			=>	'hardware',	//registered
		'wiki'				=>	'wiki',		//registered
	);

	public static $actionTable = array(
		'hide'		=>	'hide',
		'show'		=>	'show',
		'block'		=>	'block',
		'unblock'	=>	'unblock',
		'open'		=>	'open',
		'close'		=>	'close',
		'pageblock'	=>	'block',
		'pageunblock'	=>	'unblock',
		'pagehide'	=>	'hide',
		'pageshow'	=>	'show',
		'devicehide'	=>	'hide',
		'deviceshow'	=>	'show',
		'deviceapprove'	=>	'approve',
		'deviceclear'	=>	'perm deleted',
		'issuehide'		=>	'hide',
		'issueshow'		=>	'show',
		'insert'		=>	'insert', //registered
		'update'		=>	'update', //registered
	);

	protected $strings = array(
		
		'hide'	=>	array(
			
			'action' 		=>	'hide',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The message has been hidden. Just reload the page',
			'error_string'	=>	'Error: the message is already hidden',
		
		),
		
		'show'	=>	array(
		
			'action'		=>	'show',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The message is no more hidden. Just reload the page',
			'error_string'	=>	'Error: the message is already visible',
			
		),
		
		'block'	=>	array(
			
			'action' 		=>	'block',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The user has been blocked. Just reload the page',
			'error_string'	=>	'Error: the user is already blocked',
		
		),
		
		'unblock'	=>	array(
		
			'action'		=>	'unblock',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The user is no more blocked. Just reload the page',
			'error_string'	=>	'Error: the user is already un-blocked',
			
		),
		
		'open'	=>	array(
			
			'action' 		=>	'open',
			'check_status'	=>	'closed',
			'to_status'		=>	'opened',
			'exec_string'	=>	'The issue has been opened. Just reload the page',
			'error_string'	=>	'Error: the issue is already opened',
		
		),
		
		'close'	=>	array(
			
			'action' 		=>	'close',
			'check_status'	=>	'opened',
			'to_status'		=>	'closed',
			'exec_string'	=>	'The issue has been closed. Just reload the page',
			'error_string'	=>	'Error: the issue is already closed',
		
		),

		'pageblock'	=>	array(

			'action' 		=>	'pageblock',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The wiki page has been blocked. Just reload the page',
			'error_string'	=>	'Error: the wiki page is already blocked',

		),

		'pageunblock'	=>	array(

			'action'		=>	'pageunblock',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The wiki page is no more blocked. Just reload the page',
			'error_string'	=>	'Error: the wiki page is already un-blocked',

		),

		'pagehide'	=>	array(

			'action' 		=>	'pagehide',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The wiki page has been hidden. Just reload the page',
			'error_string'	=>	'Error: the wiki page is already hidden',

		),

		'pageshow'	=>	array(

			'action'		=>	'pageshow',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The wiki page is no more hidden. Just reload the page',
			'error_string'	=>	'Error: the wiki page is already visible',

		),

		'issuehide'	=>	array(

			'action' 		=>	'issuehide',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The issue has been hidden. Just reload the page',
			'error_string'	=>	'Error: the issue is already hidden',

		),

		'issueshow'	=>	array(

			'action'		=>	'issueshow',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The issue is no more hidden. Just reload the page',
			'error_string'	=>	'Error: the issue is already visible',

		),
		
		'devicehide'	=>	array(

			'action' 		=>	'devicehide',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The device page has been hidden. Just reload the page',
			'error_string'	=>	'Error: the device page is already hidden',
			'allowed_only_if'	=> array('cleared'=>'no'),
			
		),

		'deviceshow'	=>	array(

			'action'		=>	'deviceshow',
			'check_status'	=>	'yes',
			'to_status'		=>	'no',
			'exec_string'	=>	'The device page is no more hidden. Just reload the page',
			'error_string'	=>	'Error: the device page is already visible',
			'allowed_only_if'	=> array('cleared'=>'no'),
			
		),

		'deviceapprove'	=>	array(

			'action'		=>	'deviceapprove',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The device page has been approved. Just reload the page',
			'error_string'	=>	'Error: the device page is already approved',
			'allowed_only_if'	=> array('cleared'=>'no'),
			
		),

		'deviceclear'	=>	array(

			'action'		=>	'deviceclear',
			'check_status'	=>	'no',
			'to_status'		=>	'yes',
			'exec_string'	=>	'The device page has been permanently deleted. Just reload the page',
			'error_string'	=>	'Error: the device page has already been permanently deleted',
			'method'		=>	'permanentlyDelete',

		),
	);
	
	protected $types = array(
	
		'message'	=>	array(
		
			'clean_type'	=>	'message',
			'model_name'	=>	'MessagesModel',
			'id_name'		=>	'id_mes',
			'field_name'	=>	'deleted',
			'actions'		=>	array('hide','show'),
			'group'			=>	'moderator',
		
		),

		'talk'	=>	array(
		
			'clean_type'	=>	'talk',
			'model_name'	=>	'TalkModel',
			'id_name'		=>	'id_talk',
			'field_name'	=>	'deleted',
			'actions'		=>	array('hide','show'),
			'group'			=>	'moderator',
		
		),
		
		'user'	=>	array(
		
			'clean_type'	=>	'user',
			'model_name'	=>	'UsersModel',
			'id_name'		=>	'id_user',
			'field_name'	=>	'blocked',
			'actions'		=>	array('block','unblock'),
			'group'			=>	'admin',
		
		),
		
		'issue'	=>	array(
		
			'clean_type'	=>	'issue',
			'model_name'	=>	'IssuesModel',
			'id_name'		=>	'id_issue',
			'field_name'	=>	'status',
			'actions'		=>	array('open','close'),
			'group'			=>	'moderator',
			'types_to_show'	=>	'issue,issue_del',
		
		),

		'wiki_talk'	=>	array(

			'clean_type'	=>	'wiki_talk',
			'model_name'	=>	'WikitalkModel',
			'id_name'		=>	'id_talk',
			'field_name'	=>	'deleted',
			'actions'		=>	array('hide','show'),
			'group'			=>	'moderator',

		),

		//page blocked or not
		'page'	=>	array(

			'clean_type'	=>	'page',
			'model_name'	=>	'WikiModel',
			'id_name'		=>	'id_wiki',
			'field_name'	=>	'blocked',
			'actions'		=>	array('pageblock','pageunblock'),
			'group'			=>	'admin',
			'types_to_show'	=>	'page,page_del',

		),

		//page hidden or not
		'page_del'	=>	array(

			'clean_type'	=>	'page_del',
			'model_name'	=>	'WikiModel',
			'id_name'		=>	'id_wiki',
			'field_name'	=>	'-deleted',
			'actions'		=>	array('pagehide','pageshow'),
			'group'			=>	'admin',

		),

		//issue hidden or not
		'issue_del'	=>	array(

			'clean_type'	=>	'issue_del',
			'model_name'	=>	'IssuesModel',
			'id_name'		=>	'id_issue',
			'field_name'	=>	'deleted',
			'actions'		=>	array('issuehide','issueshow'),
			'group'			=>	'moderator',
			
		),
		
		//device page blocked or not
		'device'	=>	array(

			'clean_type'	=>	'device',
			'model_name'	=>	'HardwareModel',
			'id_name'		=>	'id_hard',
			'field_name'	=>	'-deleted',
			'actions'		=>	array('devicehide','deviceshow'),
			'group'			=>	'admin',
			'types_to_show'	=>	'device_app,device,device_cl',

		),

		//device page approved
		'device_app'	=>	array(

			'clean_type'	=>	'device_app',
			'model_name'	=>	'HardwareModel',
			'id_name'		=>	'id_hard',
			'field_name'	=>	'approved',
			'actions'		=>	array('deviceapprove'),
			'group'			=>	'admin',

		),

		//device page cleared
		'device_cl'	=>	array(

			'clean_type'	=>	'device_cl',
			'model_name'	=>	'HardwareModel',
			'id_name'		=>	'id_hard',
			'field_name'	=>	'cleared',
			'actions'		=>	array('deviceclear'),
			'group'			=>	'admin',

		),
	);
		
	public function __construct($model, $controller, $queryString)
	{
		parent::__construct($model, $controller, $queryString);
		
		$this->model('HistoryModel');
		$this->model('UsersModel');

	}
	
	public function hide($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'hide');
	}
	
	public function show($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'show');
	}
	
	public function block($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'block');
	}
	
	public function unblock($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'unblock');
	}
	
	public function open($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'open');
	}
	
	public function close($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'close');
	}

	public function pageblock($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'pageblock');
	}

	public function pageunblock($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'pageunblock');
	}

	public function pagehide($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'pagehide');
	}

	public function pageshow($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'pageshow');
	}

	public function devicehide($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'devicehide');
	}

	public function deviceshow($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'deviceshow');
	}

	public function deviceapprove($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'deviceapprove');
	}

	public function deviceclear($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'deviceclear');
	}

	public function issuehide($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'issuehide');
	}

	public function issueshow($lang = 'en', $token = '')
	{
		$this->generic($lang, $token, 'issueshow');
	}
	
	protected function generic($lang = 'en', $token = '', $action = 'hide')
	{
		header('Content-type: text/html; charset=UTF-8');
		
		$this->shift(2);
		
		$this->clean();
		
		$clean['token'] = sanitizeAlphanum($token);
		
		if ($this->s['registered']->status['status'] === 'logged')
		{
			if (!$this->s['registered']->checkCsrf($clean['token'])) die("wrong token");
			
			if ($this->m['UsersModel']->isBlocked($this->s['registered']->status['id_user'])) die("your account has been blocked");
			
			$clean['id_user'] = (int)$this->s['registered']->status['id_user'];
			$clean['id'] = $this->request->post('id',0,'forceInt');
			$type = $this->request->post('type','','sanitizeAll');
			$message = $this->request->post('message','');
			
			$modelName = 'error';

			if (array_key_exists($type,$this->types))
			{
				if (in_array($action,$this->types[$type]['actions']))
				{
					$clean['group'] = $this->types[$type]['group'];
					if (in_array($clean['group'],$this->s['registered']->status['groups']))
					{
						$modelName = $this->types[$type]['model_name'];
						$clean['type'] = $this->types[$type]['clean_type'];
						$clean['id_name'] = $this->types[$type]['id_name'];
						$clean['field_name'] = $this->types[$type]['field_name'];
						
						//load the right model
						$this->model($modelName);
						$model = $this->m[$modelName];

						$model->select()->where(array($clean['id_name'] => $clean['id'],$clean['field_name'] => $this->strings[$action]['check_status']));

						if (isset($this->strings[$action]['allowed_only_if']) and is_array($this->strings[$action]['allowed_only_if']))
						{
							$model->aWhere($this->strings[$action]['allowed_only_if']);
						}
						
						$count = $model->rowNumber();
						
						if ($count > 0)
						{
							if (eg_strlen($message) < 500)
							{
								//drop the - char if present
								$clean['field_name'] = str_replace('-',null,$clean['field_name']);
								
								//hide the message
								$model->values = array($clean['field_name'] => $this->strings[$action]['to_status']);

								if (isset($this->strings[$action]['method']))
								{
									call_user_func(array($model, $this->strings[$action]['method']),$clean['id']);
								}
								else
								{
									$model->pUpdate($clean['id']);
								}
								
								if ($model->queryResult)
								{
									$this->m['HistoryModel']->setFields('id:forceInt,type,message','sanitizeAll');
									$this->m['HistoryModel']->values['created_by'] = $clean['id_user'];
									$this->m['HistoryModel']->values['gr'] = $clean['group'];
									$this->m['HistoryModel']->values['action'] = $this->strings[$action]['action'];
									$this->m['HistoryModel']->updateTable('insert');
									
									echo $this->strings[$action]['exec_string'];
								}
								else
								{
									echo "error: one error occurred, please retry later";
								}
							}
							else
							{
								echo "error: the message has too many characters or wrong type";
							}
						}
						else
						{
							echo $this->strings[$action]['error_string'];
						}
					}
				}
			}
		}
	}

	public function viewall($lang = 'en', $type = 'message', $id = 0)
	{
		header('Content-type: text/html; charset=UTF-8');
		
		$this->shift(3);
		
		$this->clean();
		
		if ($this->s['registered']->status['status'] === 'logged')
		{
			if (!$this->m['UsersModel']->isBlocked($this->s['registered']->status['id_user']))
			{
				$clean['id'] = (int)$id;
				if (array_key_exists($type,$this->types))
				{
					$clean['group'] = $this->types[$type]['group'];
					if (in_array($clean['group'],$this->s['registered']->status['groups']))
					{
						$clean['type'] = $this->types[$type]['clean_type'];
						$clean['typeInWhereClause'] = "'".$clean['type']."'";
						
						if (array_key_exists('types_to_show',$this->types[$type]))
						{
							$clean['typeInWhereClause'] = "'".implode("','",explode(',',$this->types[$type]['types_to_show']))."'";
						}

						switch ($clean['type'])
						{
							case 'user':
								$data['object'] = 'user';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							case 'page':
								$data['object'] = 'wiki page';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							case 'device':
								$data['object'] = 'device page';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							case 'device_app':
								$data['object'] = 'device page';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							case 'page_del':
								$data['object'] = 'wiki page';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							case 'issue':
								$data['object'] = 'issue';
								$data['box_class'] = 'details_of_actions_inner_user';
								break;
							default:
								$data['object'] = 'message';
								$data['box_class'] = 'details_of_actions_inner';
								break;
						}
						
						$data['res'] = $this->m['HistoryModel']
										->select()
										->where(
											array
											(
												'id'=>$clean['id'],
												'type'=>"in(".$clean['typeInWhereClause'].")",
												'gr'=>$clean['group'])
											)
										->send();
// 						echo  $this->m['HistoryModel']->getQuery();
						
						$data['md_action'] = array(
							'hide'				=>	'hidden',
							'show'				=>	'restored',
							'block'				=>	'blocked',
							'unblock'			=>	'un-blocked',
							'open'				=>	'opened again',
							'close'				=>	'closed',
							'pageblock'			=>	'blocked',
							'pageunblock'		=>	'un-blocked',
							'pagehide'			=>	'hidden',
							'pageshow'			=>	'restored',
							'devicehide'		=>	'hidden',
							'deviceshow'		=>	'restored',
							'deviceapprove'		=>	'approved',
							'deviceclear'		=>	'permanently deleted',
							'issuehide'			=>	'hidden',
							'issueshow'			=>	'restored',
						);
											
						$this->append($data);
						$this->load('viewall');
					}
				}
			}
		}
	}

}