<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjFront extends pjAppController
{	
	public $defaultCaptcha = 'pjTBS_Captcha';
	
	public $defaultLocale = 'pjTBS_LocaleId';
	
	public $defaultFrontUser = 'pjTBS_User';
	
	public $defaultLangMenu = 'pjTBS_LangMenu';
	
	public $defaultStore = 'pjTBS_Store';
	
	public $defaultForm = 'pjTBS_Form';
	
	public $event_arr = array();
	
	public function __construct()
	{
		$this->setLayout('pjActionFront');
		
		self::allowCORS();
	}
	
	public function _get($key)
	{
		if ($this->_is($key))
		{
			return $_SESSION[$this->defaultStore][$key];
		}
		return false;
	}
	
	public function _is($key)
	{
		return isset($_SESSION[$this->defaultStore]) && isset($_SESSION[$this->defaultStore][$key]);
	}
	
	public function _set($key, $value)
	{
		$_SESSION[$this->defaultStore][$key] = $value;
		return $this;
	}
	
	public function _unset($key)
	{
		if ($this->_is($key))
		{
			unset($_SESSION[$this->defaultStore][$key]);
		}
	}
	
	public function afterFilter()
	{		
		if (!isset($_GET['hide']) || (isset($_GET['hide']) && (int) $_GET['hide'] !== 1) &&
			in_array($_GET['action'], array('pjActionCheckout', 'pjActionPreview')))
		{
			$locale_arr = pjLocaleModel::factory()->select('t1.*, t2.file, t2.title')
				->join('pjLocaleLanguage', 't2.iso=t1.language_iso', 'left')
				->where('t2.file IS NOT NULL')
				->orderBy('t1.sort ASC')->findAll()->getData();
			
			$this->set('locale_arr', $locale_arr);
		}
	}
	
	public function beforeFilter()
	{
		$OptionModel = pjOptionModel::factory();
		$this->option_arr = $OptionModel->getPairs($this->getForeignId());
		$this->set('option_arr', $this->option_arr);
		$this->setTime();

		if (!isset($_SESSION[$this->defaultLocale]))
		{
			$locale_arr = pjLocaleModel::factory()->where('is_default', 1)->limit(1)->findAll()->getData();
			if (count($locale_arr) === 1)
			{
				$this->setLocaleId($locale_arr[0]['id']);
			}
		}
		
		$this->loadSetFields();
		
		if(isset($_GET['id']) && (int) $_GET['id'] > 0)
		{
			$event_arr = pjEventModel::factory()->find($_GET['id'])->getData();
			$this->event_arr = $event_arr;
			$this->set('event_arr', $event_arr);
		}
	}
	
	public function beforeRender()
	{
		if (isset($_GET['iframe']))
		{
			$this->setLayout('pjActionIframe');
		}
	}
	
	public function pjActionLocale()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if (isset($_GET['locale_id']))
			{
				$this->pjActionSetLocale($_GET['locale_id']);
				
				$this->loadSetFields(true);
				
				$day_names = __('day_names', true);
				ksort($day_names, SORT_NUMERIC);
				
				$months = __('months', true);
				ksort($months, SORT_NUMERIC);
				
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Locale have been changed.', 'opts' => array(
					'day_names' => array_values($day_names),
					'month_names' => array_values($months)
				)));
			}
		}
		exit;
	}
	private function pjActionSetLocale($locale)
	{
		if ((int) $locale > 0)
		{
			$_SESSION[$this->defaultLocale] = (int) $locale;
		}
		return $this;
	}
	
	public function pjActionGetLocale()
	{
		return isset($_SESSION[$this->defaultLocale]) && (int) $_SESSION[$this->defaultLocale] > 0 ? (int) $_SESSION[$this->defaultLocale] : FALSE;
	}
	
	public function pjActionCaptcha()
	{
	    $this->setAjax(true);
	    header("Cache-Control: max-age=3600, private");
	    $Captcha = new pjCaptcha(PJ_WEB_PATH . 'obj/Anorexia.ttf', $this->defaultCaptcha, 6);
	    $Captcha->setImage(PJ_IMG_PATH . 'button.png')->init(isset($_GET['rand']) ? $_GET['rand'] : null);
	    exit;
	}

	public function pjActionCheckCaptcha()
	{
		$this->setAjax(true);
		if (!isset($_GET['captcha']) || empty($_GET['captcha']) || strtoupper($_GET['captcha']) != $_SESSION[$this->defaultCaptcha]){
			echo 'false';
		}else{
			echo 'true';
		}
		exit;
	}
	
	public function pjActionLoadCss()
	{
		$dm = new pjDependencyManager(PJ_THIRD_PARTY_PATH);
		$dm->load(PJ_CONFIG_PATH . 'dependencies.php')->resolve();
	
		$theme = $this->option_arr['o_theme'];
		$fonts = $this->option_arr['o_theme'];
		if(isset($_GET['theme']) && in_array($_GET['theme'], array('theme1', 'theme2', 'theme3', 'theme4', 'theme5', 'theme6', 'theme7', 'theme8', 'theme9', 'theme10')))
		{
			$theme = $_GET['theme'];
			$fonts = $_GET['theme'];
		}
		$arr = array(
				array('file' => "$fonts.css", 'path' => PJ_CSS_PATH . "fonts/"),
				array('file' => 'style.css', 'path' => PJ_CSS_PATH),
				array('file' => "$theme.css", 'path' => PJ_CSS_PATH . "themes/",
				array('file' => 'transitions.css', 'path' => PJ_CSS_PATH))
		);
		$event_id = 0;
		if(isset($_GET['id']) && (int) $_GET['id'] > 0)
		{
			$event_id = $_GET['id'];
		}
		header("Content-Type: text/css; charset=utf-8");
		foreach ($arr as $item)
		{
			ob_start();
			@readfile($item['path'] . $item['file']);
			$string = ob_get_contents();
			ob_end_clean();
				
			if ($string !== FALSE)
			{
				echo str_replace(
						array('../fonts/glyphicons', "pjWrapper"),
						array(
								PJ_INSTALL_URL . PJ_FRAMEWORK_LIBS_PATH . 'pj/fonts/glyphicons',
								"pjWrapperEventTicketing_" . $event_id
						),
						$string
				) . "\n";
			}
		}
		exit;
	}
	
	public function pjActionLoad()
	{
		ob_start();
		header("Content-Type: text/javascript; charset=utf-8");
	}
	
	public function pjActionTickets()
	{
		$this->setAjax(true);
	
		if($this->isXHR())
		{
			if(isset($this->event_arr))
			{
				$event_id = $this->event_arr['id'];
				
				$ticket_arr = pjTicketModel::factory()
					->select(sprintf("t1.*, t2.content as title, t3.content as description, 
								(SELECT COUNT(`TBT`.ticket_id) FROM `%1\$s` AS `TBT` WHERE `TBT`.ticket_id=t1.id AND `TBT`.booking_id IN (SELECT `TB`.id FROM `%2\$s` AS `TB` WHERE `TB`.event_id='%3\$s' AND (`TB`.status='confirmed' OR `TB`.status='pending') ) ) AS cnt_booked,
								IF(NOW() < t1.sale_start, 1, 0) AS hide_selector", 
							pjBookingTicketModel::factory()->getTable(), pjBookingModel::factory()->getTable(), $event_id) )
					->join('pjMultiLang', "t2.model='pjTicket' AND t2.foreign_id=t1.id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t3.foreign_id = t1.id AND t3.model = 'pjTicket' AND t3.locale = '".$this->getLocaleId()."' AND t3.field = 'description'", 'left')
					->where('event_id', $event_id)
					->orderBy('sale_start ASC')
					->findAll()
					->getData();
				
				$cnt_codes = pjCodeModel::factory()->where('t1.event_id', $event_id)->findCount()->getData();
				
				if($this->_is('seats'))
				{
					$this->_unset('seats');
				}
				
				$this->set('ticket_arr', $ticket_arr);
				$this->set('cnt_codes', $cnt_codes);
				$this->set('status', 'OK');
			}else{
				$this->set('status', 'ERR');
			}
		}
	}
	public function pjActionSeats()
	{
		$this->setAjax(true);
	
		if($this->isXHR())
		{
			if (isset($_SESSION[$this->defaultStore]) &&
					count($_SESSION[$this->defaultStore]) > 0 &&
					isset($_SESSION[$this->defaultStore]['tickets']) &&
					count($_SESSION[$this->defaultStore]['tickets']) > 0)
			{
				if(isset($this->event_arr))
				{
					$event_id = $this->event_arr['id'];
		
					$ticket_id_arr = array();
					$focus_ticket_id = NULL;
					foreach($_SESSION[$this->defaultStore]['tickets']['ticket_id'] as $ticket_id => $qty)
					{
						if($qty > 0)
						{
							$ticket_id_arr[] = $ticket_id;
						}
					}
					
					$ticket_arr = pjTicketModel::factory()
						->select(sprintf("t1.*, t2.content as title") )
						->join('pjMultiLang', "t2.model='pjTicket' AND t2.foreign_id=t1.id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('event_id', $event_id)
						->whereIn('t1.id', $ticket_id_arr)
						->orderBy('sale_start ASC')
						->findAll()
						->getData();
					
					if(!empty($ticket_arr))
					{
						$focus_ticket_id = $ticket_arr[0]['id'];
					}
					
					$seat_arr = pjSeatTicketModel::factory()
						->select("t1.*, t2.*, (SELECT COUNT(TBS.seat_id) FROM `".pjBookingTicketModel::factory()->getTable()."` AS `TBS` WHERE TBS.seat_id=t1.seat_id AND TBS.booking_id IN(SELECT TB.id FROM `".pjBookingModel::factory()->getTable()."` AS `TB` WHERE `TB`.event_id=".$event_id." AND (TB.status='confirmed' OR TB.status='pending'))) AS booked_seats")
						->join("pjSeat", "t1.seat_id=t2.id", 'left')
						->where('t2.event_id', $event_id)
						->where("t1.ticket_id", $focus_ticket_id)
						->findAll()
						->getData();
					
					$seat_selected_id_arr = array();
					if(isset($_POST['seat_id']) && is_array($_POST['seat_id']) && count($_POST['seat_id']))
					{
						$seat_selected_id_arr = $_POST['seat_id'];
					}
					
					$this->set('ticket_arr', $ticket_arr);
					$this->set('ticket_id_arr', $ticket_id_arr);
					$this->set('focus_ticket_id', $focus_ticket_id);
					$this->set('seat_arr', $seat_arr);
					$this->set('seat_selected_id_arr', $seat_selected_id_arr);
						
					$this->set('status', 'OK');
				}else{
					$this->set('status', 'ERR');
				}
			}else{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => ''));
				exit;
			}
		}
	}
	public function pjActionCheckout()
	{
		$this->setAjax(true);
	
		if($this->isXHR())
		{
			if (isset($_SESSION[$this->defaultStore]) &&
					count($_SESSION[$this->defaultStore]) > 0 &&
					isset($_SESSION[$this->defaultStore]['tickets']) &&
					count($_SESSION[$this->defaultStore]['tickets']) > 0)
			{
				if(isset($this->event_arr))
				{
					if(isset($_POST['ets_checkout']))
					{
						$_SESSION[$this->defaultForm] = $_POST;
					
						pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200));
					}else{
						$event_id = $this->event_arr['id'];
						
						$price_arr = $this->calcPrice($event_id, $_SESSION[$this->defaultStore], $this->option_arr, $this->getLocaleId());
							
						$country_arr = pjCountryModel::factory()
							->select('t1.id, t2.content AS country_title')
							->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
							->orderBy('`country_title` ASC')
							->findAll()
							->getData();
						
						$_terms_conditions = pjMultiLangModel::factory()->select('t1.*')
							->where('t1.model','pjOption')
							->where('t1.locale', $this->getLocaleId())
							->where('t1.field', 'o_terms')
							->limit(0, 1)
							->findAll()->getData();
						$terms_conditions = '';
						if(!empty($_terms_conditions))
						{
							$terms_conditions = $_terms_conditions[0]['content'];
						}
							
						$this->set('price_arr', $price_arr);
						$this->set('terms_conditions', $terms_conditions);
						$this->set('country_arr', $country_arr);
						
						$this->set('status', 'OK');
					}
				}else{
					$this->set('status', 'ERR');
				}
			}else{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => ''));
				exit;
			}
		}
	}
	public function pjActionPreview()
	{
		$this->setAjax(true);
	
		if($this->isXHR())
		{
			if (isset($_SESSION[$this->defaultStore]) &&
					count($_SESSION[$this->defaultStore]) > 0 &&
					isset($_SESSION[$this->defaultStore]['tickets']) &&
					count($_SESSION[$this->defaultStore]['tickets']) > 0)
			{
				if(isset($this->event_arr))
				{
					$event_id = $this->event_arr['id'];
	
					$price_arr = $this->calcPrice($event_id, $_SESSION[$this->defaultStore], $this->option_arr, $this->getLocaleId());
						
					if(isset($_SESSION[$this->defaultForm]['c_country']) && (int) $_SESSION[$this->defaultForm]['c_country'] > 0)
					{	
						$country_arr = pjCountryModel::factory()
							->select('t1.id, t2.content AS country_title')
							->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
							->find($_SESSION[$this->defaultForm]['c_country'])
							->getData();
						$this->set('country_arr', $country_arr);
					}

					$this->set('price_arr', $price_arr);
					
					$this->set('status', 'OK');
				}else{
					$this->set('status', 'ERR');
				}
			}else{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => ''));
				exit;
			}
		}
	}
	public function pjActionComplete()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			$this->set('status', 'OK');
			
			if (isset($_GET['booking_uuid']) && !empty($_GET['booking_uuid']))
			{
				$booking_uuid = $_GET['booking_uuid'];
			} elseif (isset($_GET['_escaped_fragment_'])) {
				preg_match('/\/Booking\/([A-Z]{2}\d{10})/', $_GET['_escaped_fragment_'], $matches);
				if (isset($matches[1]))
				{
					$booking_uuid = $matches[1];
				}
			}
			$booking_arr = pjBookingModel::factory()
				->select(sprintf("t1.*, t2.content as title") )
				->join('pjMultiLang', "t2.model='pjEvent' AND t2.foreign_id=t1.event_id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.uuid', $booking_uuid)
				->findAll()
				->limit(1)
				->getData();
			
			if (!empty($booking_arr))
			{
				$invoice_arr = pjInvoiceModel::factory()->where('t1.order_id', $booking_uuid)->findAll()->limit(1)->getData();
				if (!empty($invoice_arr))
				{
					$invoice_arr = $invoice_arr[0];
					$booking_arr = $booking_arr[0];
					switch ($booking_arr['payment_method'])
					{
						case 'paypal':
							$this->set('params', array(
								'name' => 'etsPaypal',
								'id' => 'etsPaypal',
								'business' => $this->option_arr['o_paypal_address'],
								'client_id' => $this->option_arr['o_paypal_client_id'],
								'client_secret' => $this->option_arr['o_paypal_client_secret'],
								'item_name' => pjSanitize::html($booking_arr['title']),
								'custom' => $invoice_arr['uuid'],
								'amount' => $invoice_arr['paid_deposit'],
								'currency_code' => $this->option_arr['o_currency'],
								'return' => $this->option_arr['o_thankyou_page'],
								'failure_url' => $this->option_arr['o_paypal_cancel_url'],
								'notify_url' => PJ_INSTALL_URL . 'index.php?controller=pjFront&action=pjActionConfirmPaypal',
								'target' => '_self',
								'charset' => 'utf-8'
							));
							break;
						case 'authorize':
							$this->set('params', array(
								'name' => 'etsAuthorize',
								'id' => 'etsAuthorize',
								'target' => '_self',
								'timezone' => $this->option_arr['o_authorize_timezone'],
								'transkey' => $this->option_arr['o_authorize_transkey'],
								'x_login' => $this->option_arr['o_authorize_merchant_id'],
								'x_description' => pjSanitize::html($booking_arr['title']),
								'x_amount' => $invoice_arr['paid_deposit'],
								'x_invoice_num' => $invoice_arr['uuid'],
								'x_receipt_link_url' => $this->option_arr['o_thankyou_page'],
								'x_relay_url' => PJ_INSTALL_URL . 'index.php?controller=pjFront&action=pjActionConfirmAuthorize'
							));
							break;
					}
					$this->set('invoice_arr', $invoice_arr);
					$this->set('booking_arr', $booking_arr);
				}
			}
		}
	}
	
	public function pjActionSaveBooking()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if (!isset($_POST['ets_preview']) || !isset($_SESSION[$this->defaultForm]) || empty($_SESSION[$this->defaultForm]) || !isset($_SESSION[$this->defaultStore]) || empty($_SESSION[$this->defaultStore]))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 109));
			}
			if ((int) $this->option_arr['o_bf_include_captcha'] === 3 && (!isset($_SESSION[$this->defaultForm]['captcha']) ||
					!pjCaptcha::validate($_SESSION[$this->defaultForm]['captcha'], $_SESSION[$this->defaultCaptcha]) ))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 110));
			}
				
			$STORE = @$_SESSION[$this->defaultStore];
			$FORM = @$_SESSION[$this->defaultForm];
				
			$data = array();

			$event_id = $this->event_arr['id'];
			$price_arr = $this->calcPrice($event_id, $_SESSION[$this->defaultStore], $this->option_arr, $this->getLocaleId());
			
			$check_arr = $this->finalCheck($event_id, $price_arr, 'front', 0);
			
			if($check_arr['status'] == 'ERR')
			{
				$front_check_msg = __('front_check_msg', true);
				if( $check_arr['code'] == '100')
				{
					if($this->_is('tickets'))
					{
						$this->_unset('tickets');
					}
				}
				if( $check_arr['code'] == '101')
				{
					if($this->_is('seats'))
					{
						$this->_unset('seats');
					}
				}
				pjAppController::jsonResponse(array('code' => 'ERR', 'code' => $check_arr['code'], 'text' => $front_check_msg[$check_arr['code']]));
			}
			
			$uuid = pjUtil::uuid();
			$data['uuid'] = $uuid;
			$data['event_id'] = $event_id;
			$data['discount_code'] = isset($STORE['discount_code']) ? $STORE['discount_code'] : ":NULL";
			$data['ip'] = pjUtil::getClientIp();
			$data['status'] = $this->option_arr['o_booking_status'];
			$data['created'] = date('Y-m-d H:i:s');
			$payment = ':NULL';
			
			if(isset($FORM['payment_method']))
			{
				$payment = $FORM['payment_method'];
				if($payment != 'creditcard')
				{
					$FORM['cc_exp_month'] = "";
					$FORM['cc_exp_year'] = "";
				}
			}
			
			$pjBookingModel = pjBookingModel::factory();
			$id = $pjBookingModel->setAttributes(array_merge($FORM, $data))->insert()->getInsertId();
			if ($id !== false && (int) $id > 0)
			{
				if(isset($price_arr['ticket_arr']))
				{
					
					$pjBookingTicketModel = pjBookingTicketModel::factory();
					foreach($price_arr['ticket_arr'] as $k => $ticket)
					{
						$bt_data = array();
						$bt_data['booking_id'] = $id;
						$bt_data['ticket_id'] = $ticket['id'];
						$bt_data['donation'] = isset($ticket['donation']) && (float) $ticket['donation'] > 0 ? (float) $ticket['donation'] : ":NULL";
						$bt_data['unit_price'] = isset($ticket['unit_price']) && (float) $ticket['unit_price'] > 0 ? (float) $ticket['unit_price'] : ":NULL";
						
						if(isset($price_arr['seat_arr']) && isset($price_arr['seat_arr'][$ticket['id']]))
						{
							foreach($price_arr['seat_arr'][$ticket['id']] as $key => $seat)
							{
								$bt_data['seat_id'] = $seat['seat_id'];
								$bt_data['attendee_name'] = isset($FORM['attendee'][$ticket['id']][$key + 1]) ? $FORM['attendee'][$ticket['id']][$key + 1] : $FORM['c_name'];
								$bt_data['ticket_code'] = $uuid . '-' . $ticket['id'] . '-' . ($key + 1);
								$bt_data['is_used'] = "F";
								$pjBookingTicketModel->reset()->setAttributes($bt_data)->insert();
						
							}
						}else{
							for($i = 1; $i <= (int) $ticket['qty']; $i++)
							{
								$bt_data['seat_id'] = ":NULL";
								$bt_data['attendee_name'] = isset($FORM['attendee'][$ticket['id']][$i]) ? $FORM['attendee'][$ticket['id']][$i] : $FORM['c_name'];
								$bt_data['ticket_code'] = $uuid . '-' . $ticket['id'] . '-' . $i;
								$bt_data['is_used'] = "F";
								$pjBookingTicketModel->reset()->setAttributes($bt_data)->insert();
							}
						}
					}
				}
				
				$arr = $this->pjActionGetBookingDetails($id);
				
				$pdata = array();
				$pdata['booking_id'] = $id;
				$pdata['payment_method'] = $payment;
				$pdata['payment_type'] = 'online';
				$pdata['amount'] = $arr['deposit'];
				$pdata['status'] = 'notpaid';
				pjBookingPaymentModel::factory()->setAttributes($pdata)->insert();
	
				$this->pjActionGenerateInvoice($arr);
				$this->buildPdfTickets($arr);
				
				pjFront::pjActionConfirmSend($this->option_arr, $arr, PJ_SALT, 'confirm');
	
				unset($_SESSION[$this->defaultStore]);
				unset($_SESSION[$this->defaultForm]);
				
				$json = array('code' => 200, 'text' => '', 'booking_id' => $id, 'booking_uuid' => $arr['uuid'], 'payment' => $payment);
				pjAppController::jsonResponse($json);
			}else {
				pjAppController::jsonResponse(array('code' => 'ERR', 'code' => 119));
			}
		}
	}
	public function pjActionJoin()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			$response = array();
			if(isset($_POST['event_id']) && (int) $_POST['event_id'] > 0 && isset($_POST['ticket_id']) && (int) $_POST['ticket_id'] > 0)
			{
				$_POST['created'] = date('Y-m-d H:i:s');
				$id = pjWaitlistModel::factory()->setAttributes($_POST)->insert()->getInsertId();
				if ($id !== false && (int) $id > 0)
				{
					$response['code'] = 200;
					$response['text'] = __('front_joint_successful', true);
				}else{
					$response['code'] = 100;
					$response['text'] = __('front_joint_not_successful', true);
				}
			}else{
				$response['code'] = 100;
				$response['text'] = __('front_joint_missing_params', true);
			}
			pjAppController::jsonResponse($response);
		}
		exit;
	}
	public function pjActionApplyCode()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if(isset($_GET['discount_code']) && $_GET['discount_code'] != '')
			{
				$pjCodeModel = pjCodeModel::factory();
	
				$arr = pjCodeModel::factory()->checkCode($_GET['id'], $_GET['discount_code'], $this->option_arr);
	
				if($arr['status'] == 'OK')
				{
					$this->_set('discount_code', $_GET['discount_code']);
					$this->_set('discount_data', $arr);
					$arr['text'] = __('front_code_applied', true);
				}else{
					if($this->_is('discount_code'))
					{
						$this->_unset('discount_code');
					}
					$arr['text'] = __('front_invalid_code', true);
				}
				pjAppController::jsonResponse($arr);
			}else{
				pjAppController::jsonResponse(array('status' => 'ERR'));
			}
		}
		exit;
	}
	public function pjActionRemoveCode()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if($this->_is('discount_code'))
			{
				$this->_unset('discount_code');
			}
			if($this->_is('discount_data'))
			{
				$this->_unset('discount_data');
			}
			pjAppController::jsonResponse(array('status' => 'OK'));
		}
		exit;
	}
	public function pjActionSaveTickets()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if($this->_is('tickets'))
			{
				$this->_unset('tickets');
			}
			unset($_POST['discount_code']);
			$this->_set('tickets', $_POST);
			pjAppController::jsonResponse(array('status' => 'OK'));
		}
		exit;
	}
	public function pjActionSaveSeats()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if($this->_is('seats'))
			{
				$this->_unset('seats');
			}
			$this->_set('seats', $_POST);
			pjAppController::jsonResponse(array('status' => 'OK'));
		}
		exit;
	}
	public function pjActionGetSeats()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			if(isset($_GET['id']) && (int) $_GET['id'] > 0 && isset($_GET['ticket_id']) && (int) $_GET['ticket_id'] > 0)
			{
				$seat_arr = pjSeatTicketModel::factory()
					->select("t1.*, t2.*, (SELECT COUNT(TBS.seat_id) FROM `".pjBookingTicketModel::factory()->getTable()."` AS `TBS` WHERE TBS.seat_id=t1.seat_id AND TBS.booking_id IN(SELECT TB.id FROM `".pjBookingModel::factory()->getTable()."` AS `TB` WHERE `TB`.event_id=".$_GET['id']." AND (TB.status='confirmed' OR TB.status='pending'))) AS booked_seats")
					->join("pjSeat", "t1.seat_id=t2.id", 'left')
					->where('t2.event_id', $_GET['id'])
					->where("t1.ticket_id", $_GET['ticket_id'])
					->findAll()
					->getData();
	
				$seat_selected_id_arr = array();
				if(isset($_POST['seat_id']) && is_array($_POST['seat_id']) && count($_POST['seat_id']))
				{
					$seat_selected_id_arr = $_POST['seat_id'];
				}
				$seat_selected_arr = isset($seat_selected_id_arr[$_GET['ticket_id']]) && !empty($seat_selected_id_arr[$_GET['ticket_id']]) ? pjSeatModel::factory()->whereIn('t1.id', $seat_selected_id_arr[$_GET['ticket_id']])->findAll()->getDataPair('id', 'name'): array();
				
				$selected_ticket_arr = pjTicketModel::factory()->select('t1.*, t2.content as ticket')->join('pjMultiLang', "t2.model='pjTicket' AND t2.foreign_id=t1.id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')->find($_GET['ticket_id'])->getData();
				
				$this->set('seat_arr', $seat_arr);
				$this->set('seat_selected_arr', $seat_selected_arr);
				$this->set('selected_ticket_arr', $selected_ticket_arr);
				$this->set('seat_selected_id_arr', $seat_selected_id_arr);
			}
		}
	}
	
	public function pjActionCancel()
	{
		$this->setLayout('pjActionCancel');
	
		$pjBookingModel = pjBookingModel::factory();
	
		if (isset($_POST['booking_cancel']))
		{
			$booking_arr = $pjBookingModel->find($_POST['id'])->getData();
			if (count($booking_arr) > 0)
			{
				$sql = "UPDATE `".$pjBookingModel->getTable()."` SET status = 'cancelled' WHERE SHA1(CONCAT(`id`, `created`, '".PJ_SALT."')) = '" . $_POST['hash'] . "'";
	
				$pjBookingModel->reset()->execute($sql);
	
				$arr = $this->pjActionGetBookingDetails($_POST['id']);
				
				pjFront::pjActionConfirmSend($this->option_arr, $arr, PJ_SALT, 'cancel');
	
				pjUtil::redirect($_SERVER['PHP_SELF'] . '?controller=pjFront&action=pjActionCancel&err=200');
			}
		}else{
			if (isset($_GET['hash']) && isset($_GET['id']))
			{
				$arr = $pjBookingModel
					->reset()
					->select(sprintf("t1.*, AES_DECRYPT(t1.cc_type, '%1\$s') AS `cc_type`,	
						AES_DECRYPT(t1.cc_num, '%1\$s') AS `cc_num`,
						AES_DECRYPT(t1.cc_exp_month, '%1\$s') AS `cc_exp_month`,
						AES_DECRYPT(t1.cc_exp_year, '%1\$s') AS `cc_exp_year`,
						AES_DECRYPT(t1.cc_code, '%1\$s') AS `cc_code`, t2.content as event_title, t3.content as country_title", PJ_SALT))
					->join('pjMultiLang', "t2.model='pjEvent' AND t2.foreign_id=t1.event_id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t3.model='pjCountry' AND t3.foreign_id=t1.c_country AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
					->find($_GET['id'])
					->getData();
				if (count($arr) == 0)
				{
					$this->set('status', 2);
				}else{
					if ($arr['status'] == 'cancelled')
					{
						$this->set('status', 4);
					}else{
						$hash = sha1($arr['id'] . $arr['created'] . PJ_SALT);
						if ($_GET['hash'] != $hash)
						{
							$this->set('status', 3);
						}else{
	
							$this->set('arr', $arr);
						}
					}
				}
			}else if (!isset($_GET['err'])) {
				$this->set('status', 1);
			}
		}
	}
	
	public function pjActionConfirmAuthorize()
	{
		header('HTTP/1.1 200 OK');

		$this->setAjax(true);
	
		if (pjObject::getPlugin('pjAuthorize') === NULL)
		{
			$this->log('Authorize.NET plugin not installed');
			exit;
		}
		if (!isset($_POST['x_invoice_num']))
		{
			$this->log('Missing arguments');
			exit;
		}
		$pjInvoiceModel = pjInvoiceModel::factory();
		$pjBookingModel = pjBookingModel::factory();
	
		$invoice_arr = $pjInvoiceModel
			->where('t1.uuid', $_POST['x_invoice_num'])
			->limit(1)
			->findAll()
			->getData();
		if (!empty($invoice_arr))
		{
			$invoice_arr = $invoice_arr[0];
			
			$booking_arr = $pjBookingModel->where('t1.uuid', $invoice_arr['order_id'])->limit(1)->findAll()->getData();
			if (!empty($booking_arr))
			{
				$booking_arr = $booking_arr[0];
				
				$params = array(
						'transkey' => $this->option_arr['o_authorize_transkey'],
						'x_login' => $this->option_arr['o_authorize_merchant_id'],
						'md5_setting' => $this->option_arr['o_authorize_md5_hash'],
						'key' => md5($this->option_arr['private_key'] . PJ_SALT)
				);
					
				$response = $this->requestAction(array('controller' => 'pjAuthorize', 'action' => 'pjActionConfirm', 'params' => $params), array('return'));
				if ($response !== FALSE && $response['status'] === 'OK')
				{
					$pjBookingModel->reset()
						->set('id', $booking_arr['id'])
						->modify(array('status' => $this->option_arr['o_payment_status'], 'processed_on' => ':NOW()'));
		
					pjBookingPaymentModel::factory()
						->setAttributes(array('booking_id' => $booking_arr['id'], 'payment_type' => 'online'))
						->modifyAll(array('status' => 'paid'));
	
					$pjInvoiceModel
						->reset()
						->set('id', $invoice_arr['id'])
						->modify(array('status' => 'paid', 'modified' => ':NOW()'));
					
					$arr = $this->pjActionGetBookingDetails($booking_arr['id']);	
						
					pjFront::pjActionConfirmSend($this->option_arr, $arr, PJ_SALT, 'payment');
		
				} elseif (!$response) {
					$this->log('Authorization failed');
				} else {
					$this->log('Booking not confirmed. ' . $response['response_reason_text']);
				}
				?>
				<script type="text/javascript">window.location.href="<?php echo $this->option_arr['o_thankyou_page']; ?>";</script>
				<?php
				return;
			}else{
				$this->log('No such booking');
				pjUtil::redirect($this->option_arr['o_thankyou_page']);
			}
		}else{
			$this->log('No such booking');
			pjUtil::redirect($this->option_arr['o_thankyou_page']);
		}
	}
	
	public function pjActionConfirmPaypal()
	{
		$this->setAjax(true);
	
		if (pjObject::getPlugin('pjPaypal') === NULL)
		{
			$this->log('Paypal plugin not installed');
			pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Paypal plugin not installed'));
		}
		$input = file_get_contents('php://input');
		$post = json_decode($input, true);
		if ($post) {
		    $_REQUEST = array_merge($_REQUEST, $post);
		}
		
		$pjInvoiceModel = pjInvoiceModel::factory();
		$pjBookingModel = pjBookingModel::factory();
	
		$invoice_arr = $pjInvoiceModel
		->where('t1.uuid', $_REQUEST['custom'])
		->limit(1)
		->findAll()
		->getData();
		
		if (!empty($invoice_arr))
		{
			$invoice_arr = $invoice_arr[0];
			
			$booking_arr = $pjBookingModel->where('t1.uuid', $invoice_arr['order_id'])->limit(1)->findAll()->getData();
			if (!empty($booking_arr))
			{
				$booking_arr = $booking_arr[0];
				$params = array(
				    'request'		=> $_REQUEST,
				    'cancel_hash'	=> sha1($booking_arr['uuid'].strtotime($booking_arr['created']).PJ_SALT),
				    'txn_id' => @$booking_arr['txn_id'],
				    'paypal_address' => $this->option_arr['o_paypal_address'],
				    'deposit' => @$booking_arr['deposit'],
				    'currency' => $this->option_arr['o_currency'],
				    'key' => md5($this->option_arr['private_key'] . PJ_SALT)
				);
				$response = $this->requestAction(array('controller' => 'pjPaypal', 'action' => 'pjActionConfirm', 'params' => $params), array('return'));
				
				if ($response !== FALSE && $response['status'] === 'OK')
				{
					$this->log('Booking confirmed');
					$pjBookingModel->reset()->set('id', $booking_arr['id'])->modify(array(
					    'status' => $this->option_arr['o_payment_status'],
					    'txn_id' => $response['transaction_id'],
					    'processed_on' => ':NOW()'
					));
					
					pjBookingPaymentModel::factory()->where('booking_id', $booking_arr['id'])->where('payment_type', 'online')->limit(1)->modifyAll(array('status' => 'paid'));
				
					$pjInvoiceModel->reset()->set('id', $invoice_arr['id'])->modify(array('status' => 'paid', 'modified' => ':NOW()'));
					
					$arr = $this->pjActionGetBookingDetails($booking_arr['id']);
						
					pjFront::pjActionConfirmSend($this->option_arr, $arr, PJ_SALT, 'payment');
					
					pjAppController::jsonResponse(array('status' => 'OK', 'text' => 'Booking confirmed'));
				} elseif (!$response) {
					$this->log('Authorization failed');
					pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Authorization failed'));
				} else {
					$this->log('Booking not confirmed');
					pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Booking not confirmed'));
				}
			}else{
				$this->log('No such booking');
				pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'No such booking'));
			}
		}else{
			$this->log('Booking not confirmed');
			pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Booking not confirmed'));
		}
	}
	
	public function pjActionConfirmSend($option_arr, $arr, $salt, $opt)
	{
		$Email = new pjEmail();
		if ($option_arr['o_send_email'] == 'smtp')
		{
			$Email
				->setTransport('smtp')
				->setSmtpHost($option_arr['o_smtp_host'])
				->setSmtpPort($option_arr['o_smtp_port'])
				->setSmtpUser($option_arr['o_smtp_user'])
				->setSmtpPass($option_arr['o_smtp_pass'])
				->setSender($option_arr['o_smtp_user'])
			;
		}
		$Email->setContentType('text/html');
	
		$admin_email = $this->getAdminEmail();
		$admin_phone = $this->getAdminPhone();
		$from_email = $admin_email;
	
		$locale_id = $this->getLocaleId();
	
		$tokens = pjAppController::getTokens($option_arr, $arr, PJ_SALT, $locale_id);
	
		$pjMultiLangModel = pjMultiLangModel::factory();
	
		if ($option_arr['o_email_payment'] == 1 && $opt == 'payment')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_payment_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_payment_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
	
				$Email
					->setTo($arr['c_email'])
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
		if ($option_arr['o_admin_email_payment'] == 1 && $opt == 'payment')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_payment_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_payment_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
	
				$Email
					->setTo($admin_email)
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
		if(!empty($arr['c_phone']) && $opt == 'payment')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_sms_payment_message')
				->limit(0, 1)
				->findAll()->getData();
			if (count($lang_message) === 1 && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
				if($message != '')
				{
					$params = array(
							'text' => $message,
							'type' => 'unicode',
							'key' => md5($option_arr['private_key'] . PJ_SALT)
					);
					$params['number'] = $arr['c_phone'];
					$this->requestAction(array('controller' => 'pjSms', 'action' => 'pjActionSend', 'params' => $params), array('return'));
				}
			}
		}
		if(!empty($admin_phone) && $opt == 'payment')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_sms_payment_message')
				->limit(0, 1)
				->findAll()->getData();
			if (count($lang_message) === 1 && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
				if($message != '')
				{
					$params = array(
							'text' => $message,
							'type' => 'unicode',
							'key' => md5($option_arr['private_key'] . PJ_SALT)
					);
					$params['number'] = $admin_phone;
					$this->requestAction(array('controller' => 'pjSms', 'action' => 'pjActionSend', 'params' => $params), array('return'));
				}
			}
		}
		
		if ($option_arr['o_email_confirmation'] == 1 && $opt == 'confirm')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_confirmation_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_confirmation_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
					
				$Email
					->setTo($arr['c_email'])
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
		if ($option_arr['o_admin_email_confirmation'] == 1 && $opt == 'confirm')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_confirmation_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_confirmation_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
				$Email
					->setTo($admin_email)
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
		if(!empty($arr['c_phone']) && $opt == 'confirm')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_sms_confirmation_message')
				->limit(0, 1)
				->findAll()->getData();
			if (count($lang_message) === 1 && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
				if($message != '')
				{
					$params = array(
							'text' => $message,
							'type' => 'unicode',
							'key' => md5($option_arr['private_key'] . PJ_SALT)
					);
					$params['number'] = $arr['c_phone'];
					$this->requestAction(array('controller' => 'pjSms', 'action' => 'pjActionSend', 'params' => $params), array('return'));
				}
			}
		}
		if(!empty($admin_phone) && $opt == 'confirm')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_sms_confirmation_message')
				->limit(0, 1)
				->findAll()->getData();
			if (count($lang_message) === 1 && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
				if($message != '')
				{
					$params = array(
							'text' => $message,
							'type' => 'unicode',
							'key' => md5($option_arr['private_key'] . PJ_SALT)
					);
					$params['number'] = $admin_phone;
					$this->requestAction(array('controller' => 'pjSms', 'action' => 'pjActionSend', 'params' => $params), array('return'));
				}
			}
		}
	
		if ($option_arr['o_email_cancel'] == 1 && $opt == 'cancel')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_cancel_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_email_cancel_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
	
				$Email
					->setTo($arr['c_email'])
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
		if ($option_arr['o_admin_email_cancel'] == 1 && $opt == 'cancel')
		{
			$lang_message = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_cancel_message')
				->limit(0, 1)
				->findAll()->getData();
			$lang_subject = $pjMultiLangModel->reset()->select('t1.*')
				->where('t1.model','pjOption')
				->where('t1.locale', $locale_id)
				->where('t1.field', 'o_admin_email_cancel_subject')
				->limit(0, 1)
				->findAll()->getData();
	
			if (count($lang_message) === 1 && count($lang_subject) === 1 && !empty($lang_subject[0]['content']) && !empty($lang_message[0]['content']))
			{
				$message = str_replace($tokens['search'], $tokens['replace'], $lang_message[0]['content']);
	
				$Email
					->setTo($admin_email)
					->setFrom($from_email)
					->setSubject($lang_subject[0]['content'])
					->send($message);
			}
		}
	}
	
	public function isXHR()
	{
		return parent::isXHR() || isset($_SERVER['HTTP_ORIGIN']);
	}
	
	static protected function allowCORS()
	{
		$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
		header('P3P: CP="ALL DSP COR CUR ADM TAI OUR IND COM NAV INT"');
		header("Access-Control-Allow-Origin: $origin");
		header("Access-Control-Allow-Credentials: true");
		header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
		header("Access-Control-Allow-Headers: Origin, X-Requested-With");
	}
}
?>