<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjListings extends pjFront
{
	public $defaultSearch = 'Search';
	
	private $isoDatePattern = '/\d{4}-\d{2}-\d{2}/';
		
	public function pjActionIndex()
	{
		pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionListings");
	}
	
	public function pjActionListings()
	{
		$pjListingModel = $this->pjActionCriteria($_GET);
			
		$page = isset($_GET['pjPage']) && (int) $_GET['pjPage'] > 0 ? intval($_GET['pjPage']) : 1;
	
		$count = $pjListingModel->findCount()->getData();
		$row_count = (int) $this->option_arr['o_per_page'] > 0 ? intval($this->option_arr['o_per_page']) : 10;
		
		$pages = ceil($count / $row_count);
		$offset = ((int) $page - 1) * $row_count;
	
		$arr = $pjListingModel
			->select(sprintf("t1.*, t2.content AS type_title, t3.content AS country_title, t4.content AS listing_title, t5.content AS listing_description,
					(SELECT `medium_path` FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` ORDER BY `sort` ASC LIMIT 1) AS `pic`,
					(SELECT MIN(`price`) FROM `%2\$s` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `price`,
					(SELECT MAX(`price`) FROM `%2\$s` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `max_price`
				", pjGalleryModel::factory()->getTable(), pjPriceModel::factory()->getTable()))
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.type_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t3.model='pjCountry' AND t3.foreign_id=t1.country_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='title' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='description' AND t5.locale='".$this->getLocaleId()."'", 'left outer')
			->limit($row_count, $offset)->findAll()->getData();
			
		$this->set('extra_arr', pjExtraModel::factory()->where('t1.status', 'T')->findAll()->getData());
		$this->set('paginator', array('pages' => $pages, 'row_count' => $row_count, 'count' => $count));
	
		$this->set('type_arr', pjTypeModel::factory()
			->select('t1.*, t2.content AS type_title')
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->where('t1.status', 'T')->orderBy('type_title ASC')->findAll()->getData()
		);
			
		$this->set('arr', $arr);
	
		$pjMultiLangModel = pjMultiLangModel::factory();
		$meta_title = $pjMultiLangModel->reset()->select('t1.*')
			->where('t1.model','pjOption')
			->where('t1.locale', $this->getLocaleId())
			->where('t1.field', 'o_meta_title')
			->limit(0, 1)
			->findAll()->getData();
		$meta_keywords = $pjMultiLangModel->reset()->select('t1.*')
			->where('t1.model','pjOption')
			->where('t1.locale', $this->getLocaleId())
			->where('t1.field', 'o_meta_keywords')
			->limit(0, 1)
			->findAll()->getData();
		$meta_description = $pjMultiLangModel->reset()->select('t1.*')
			->where('t1.model','pjOption')
			->where('t1.locale', $this->getLocaleId())
			->where('t1.field', 'o_meta_description')
			->limit(0, 1)
			->findAll()->getData();
		
		$this->set('meta_arr', array(
			'title' => count($meta_title) == 1 ? $meta_title[0]['content'] : __('ws_properties_meta_title', true),
			'keywords' => count($meta_keywords) == 1 ? $meta_keywords[0]['content'] : __('ws_properties_meta_keywords', true),
			'description' => count($meta_description) == 1 ? $meta_description[0]['content'] : __('ws_properties_meta_description', true),
		));
	}
	
	public function pjActionSearch()
	{
		if (isset($_GET['listing_search']))
		{
			$pjListingModel = $this->pjActionCriteria($_GET);
			
			if($this->isXHR())
			{
				$this->setAjax(true);
				if($pjListingModel->findCount()->getData() > 0)
				{
					echo '200';
				}else{
					echo '100';
				}
				exit;
			}else{
				$arr = $pjListingModel
					->select(sprintf("t1.*, t2.content AS type_title, t3.content AS listing_title, t4.content AS listing_description,
						(SELECT `small_path` FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` ORDER BY `sort` ASC LIMIT 1) AS `pic`,
						(SELECT MIN(`price`) FROM `%2\$s` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `price`
					", pjGalleryModel::factory()->getTable(), pjPriceModel::factory()->getTable()))
					->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.type_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t3.model='pjListing' AND t3.foreign_id=t1.id AND t3.field='title' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='description' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
					->findAll()
					->getData();
				$this->set('arr', $arr);
			}
		}

		$draw_arr = pjDrawSearchModel::factory()->findAll()->getData();
		$draw_arr = !empty($draw_arr) ? $draw_arr[0] : array();
		$this->set('draw_arr', $draw_arr);
		
		$this->set('type_arr', pjTypeModel::factory()
			->select('t1.*, t2.content AS type_title')
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->where('t1.status', 'T')->orderBy('type_title ASC')->findAll()->getData()
		);
		
		$meta_arr = pjMultiLangModel::factory()->getMultiLang(1, 'pjOption');
					
		$this->set('meta_arr', array(
			'title' => isset($meta_arr[$this->getLocaleId()]['map_meta_title']) ? $meta_arr[$this->getLocaleId()]['map_meta_title'] : null,
			'keywords' => isset($meta_arr[$this->getLocaleId()]['map_meta_keywords']) ? $meta_arr[$this->getLocaleId()]['map_meta_keywords'] : null,
			'description' => isset($meta_arr[$this->getLocaleId()]['map_meta_description']) ? $meta_arr[$this->getLocaleId()]['map_meta_description'] : null
		));
	}

	public function pjActionSendRequest()
	{
		$this->setLayout('pjActionEmpty');
		
		$this->setAjax(true);
		
		if ($this->isXHR())
		{
			if (!isset($_POST['verification']) || empty($_POST['verification']) || !pjCaptcha::validate($_POST['verification'], $_SESSION[$this->defaultCaptcha]))
			{
				$this->set('status', 4);
			} else {
				$_SESSION[$this->defaultCaptcha] = NULL;
				unset($_SESSION[$this->defaultCaptcha]);
				
				$passCheck = true;
				
				$_POST['date_from'] = pjUtil::formatDate($_POST['date_from'], $this->option_arr['o_date_format']);
				$_POST['date_to'] = pjUtil::formatDate($_POST['date_to'], $this->option_arr['o_date_format']);
				
				if (!preg_match($this->isoDatePattern, $_POST['date_from']) || !preg_match($this->isoDatePattern, $_POST['date_to']))
				{
					$this->set('status', 5);
					$passCheck = false;
				}

				$p_from = strtotime($_POST['date_from']);
				$p_to = strtotime($_POST['date_to']);

				if ($p_from > $p_to)
				{
					$this->set('status', 6);
					$passCheck = false;
				}

				$today = strtotime(date("Y-m-d"));
				if ($p_from < $today || $p_to < $today)
				{
					$this->set('status', 8);
					$passCheck = false;
				}
				
				$numOfDays = ($p_to - $p_from) / 86400;
				$listing_arr = pjListingModel::factory()
					->select('t1.*, t2.email AS email_address, t3.content AS confirm_tokens, t4.content AS payment_tokens,
						t5.content AS confirm_subject, t6.content AS payment_subject')
					->join('pjUser', 't2.id=t1.owner_id', 'inner')
					->join('pjMultiLang', "t3.model='pjListing' AND t3.foreign_id=t1.id AND t3.field='confirm_tokens' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='payment_tokens' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='confirm_subject' AND t5.locale='".$this->getLocaleId()."'", 'left outer')
					->join('pjMultiLang', "t6.model='pjListing' AND t6.foreign_id=t1.id AND t6.field='payment_subject' AND t6.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.id', $_POST['listing_id'])
					->limit(1)
					->findAll()->getData();
				
				if (count($listing_arr) === 1)
				{
					$listing_arr = $listing_arr[0];
				}
				
				if ((int) $listing_arr['o_price_based_on'] === 1)
				{
					$numOfDays += 1;
				}
					
				if ($numOfDays < (int) $listing_arr['o_min_booking_lenght'])
				{
					$this->set('status', 9);
					$passCheck = false;
				}
				if ($listing_arr['o_max_booking_lenght'] != '' && $numOfDays > (int) $listing_arr['o_max_booking_lenght'])
				{
					$this->set('status', 10);
					$passCheck = false;
				}

				if ($passCheck)
				{
					$ReservationModel = pjReservationModel::factory();

					$where_str = "(t1.status='Confirmed')";
					if($listing_arr['o_book_pending'] == 0)
					{
						$where_str = "(t1.status='Confirmed' OR t1.status='Pending')";
					}
					$reservation_arr = $ReservationModel
						->where('t1.listing_id', $_POST['listing_id'])
						->where($where_str)
						->findAll()
						->getData();
						
					$overlap = false;
					foreach ($reservation_arr as $booking)
					{
						$b_from = strtotime($booking['date_from']);
						$b_to   = strtotime($booking['date_to']);
						if ($listing_arr['o_price_based_on'] == 1)
						{
							if (
							($b_from <= $p_from && $b_to >= $p_to) ||
							($b_from >= $p_from && $b_to >= $p_to && $b_from <= $p_to) ||
							($b_from <= $p_from && $b_to <= $p_to && $b_to >= $p_from) ||
							($b_from >= $p_from && $b_to <= $p_to)
							)
							{
								$overlap = true;
								break;
							}
						} elseif ($listing_arr['o_price_based_on'] == 2) {
							if (
							($b_from <= $p_from && $b_to >= $p_to) ||
							($b_from >= $p_from && $b_to >= $p_to && $b_from < $p_to) ||
							($b_from <= $p_from && $b_to <= $p_to && $b_to > $p_from) ||
							($b_from >= $p_from && $b_to <= $p_to)
							)
							{
								$overlap = true;
								break;
							}
						}
					}

					if (!$overlap)
					{
						$status = $listing_arr['o_default_status_if_not_paid'];
						
						$amount = $deposit = $security = $tax = 0;
						$tmp = pjAppController::pjActionGetPrices($_POST);
						
						if ($tmp['amount'] > 0)
						{
							$amount = $tmp['amount'];
							$security = $tmp['security'];
							$tax = $tmp['tax'];
							$deposit= $tmp['deposit'];
						}
						unset($tmp);
						
						$data = array();
						$data['ip'] = $_SERVER['REMOTE_ADDR'];
						$data['uuid'] = pjUtil::uuid();
						
						$reservation_id = $ReservationModel
							->reset()
							->setAttributes(array_merge($_POST, $data, compact('status', 'amount', 'deposit', 'tax', 'security')))
							->insert()
							->getInsertId();
						if ($reservation_id !== false && (int) $reservation_id > 0)
						{
							$booking_arr = $ReservationModel->reset()->find($reservation_id)->getData();

							pjAppController::pjActionConfirmSend($this->option_arr, $booking_arr, $listing_arr, 'confirm');
								
							if ((int) $listing_arr['o_disable_payments'] == 1)
							{
								$this->set('status', 1);
							} else {
								$this->set('status', 11);
							}
							
							$this->notify(3, NULL, array_merge($listing_arr, $booking_arr));
							$this->notify(4, $listing_arr['owner_id'], array_merge($listing_arr, $booking_arr));
							
						} else {
							$this->set('status', 2);
						}
					} else {
						$this->set('status', 3);
					}
				}
			}
			
			pjAppController::jsonResponse(array('code' => $this->get('status'), 'payment_method' => @$_POST['payment_method'], 'booking_id' => @$reservation_id));
		}
	}
	
	public function pjActionGetPaymentForm()
	{
		$this->setAjax(true);
		
		if ($this->isXHR())
		{
			$booking_arr = pjReservationModel::factory()
				->select('t1.*, t2.o_paypal_address, t2.o_thankyou_page, t2.o_authorize_merchant_id, t2.o_authorize_transkey, t2.o_authorize_tz, t2.o_bank_account')
				->join('pjListing', "t2.id=t1.listing_id", 'left outer')
				->find($_GET['booking_id'])
				->getData();
				
			switch ($_POST['payment_method'])
			{
				case 'paypal':
					$this->set('params', array(
						'name' => 'vrPaypal',
						'id' => 'vrPaypal',
						'business' => $booking_arr['o_paypal_address'],
						'item_name' => __('front_payment_paypal_title', true),
						'custom' => $booking_arr['uuid'],
						'amount' => $booking_arr['deposit'],
						'currency_code' => $this->option_arr['o_currency'],
						'return' => $booking_arr['o_thankyou_page'],
						'notify_url' => PJ_INSTALL_URL . 'index.php?controller=pjListings&action=pjActionConfirmPaypal',
						'target' => '_self',
						'charset' => 'utf-8'
					));
					break;
				case 'authorize':
					$this->set('params', array(
						'name' => 'vrAuthorize',
						'id' => 'vrAuthorize',
						'timezone' => $booking_arr['o_authorize_tz'],
						'transkey' => $booking_arr['o_authorize_transkey'],
						'x_login' => $booking_arr['o_authorize_merchant_id'],
						'x_description' => __('front_payment_authorize_title', true),
						'x_amount' => $booking_arr['deposit'],
						'x_invoice_num' => $booking_arr['uuid'],
						'x_receipt_link_url' => $booking_arr['o_thankyou_page'],
						'x_relay_url' => PJ_INSTALL_URL . 'index.php?controller=pjListings&action=pjActionConfirmAuthorize'
					));
					break;
			}
			
			$this->set('booking_arr', $booking_arr);
			$this->set('post', $_POST);
			$_POST = array();
		}
	}
	
	public function pjActionGetRequest()
	{
		$this->setAjax(true);
		
		if ($this->isXHR())
		{
			$arr = pjListingModel::factory()
				->select("t1.*, t2.content AS listing_terms")
				->join('pjMultiLang', "t2.model='pjListing' AND t2.foreign_id=t1.id AND t2.field='terms' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->find($_POST['listing_id'])->getData();
			
			$this->set('reservation_arr', $this->pjActionGetReservations($_POST['listing_id']));
			$this->set('calendar', $this->pjActionGetCalendar($arr['o_price_based_on']));
			$this->set('price_raw_arr', $this->pjActionGetRawPrices($_POST['listing_id']));
			$this->set('listing_id', $_POST['listing_id']);
			$this->set('arr', $arr);
			$this->set('status', $_GET['status']);
			
			if ($_GET['status'] == 1)
			{
				$_POST = array();
			}
		}
	}

	public function pjActionView()
	{
		$pjListingModel = pjListingModel::factory();
		$arr = $pjListingModel
			->select("t1.*, t2.content AS type_title, t3.content AS country_title, t4.content AS listing_title,
				t5.content AS listing_description, t6.content AS listing_terms, t7.content AS meta_title,
				t8.content AS meta_keywords, t9.content AS meta_description,
				(SELECT MIN(`price`) FROM `".pjPriceModel::factory()->getTable()."` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `price`,
				(SELECT MAX(`price`) FROM `".pjPriceModel::factory()->getTable()."` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `max_price`")
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.type_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t3.model='pjCountry' AND t3.foreign_id=t1.country_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='title' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='description' AND t5.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t6.model='pjListing' AND t6.foreign_id=t1.id AND t6.field='terms' AND t6.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t7.model='pjListing' AND t7.foreign_id=t1.id AND t7.field='meta_title' AND t7.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t8.model='pjListing' AND t8.foreign_id=t1.id AND t8.field='meta_keywords' AND t8.locale='".$this->getLocaleId()."'", 'left outer')
			->join('pjMultiLang', "t9.model='pjListing' AND t9.foreign_id=t1.id AND t9.field='meta_description' AND t9.locale='".$this->getLocaleId()."'", 'left outer')
			->where('t1.id', $_GET['id'])
			->where("(t1.status = 'T' OR (t1.status = 'E' AND t1.expire >= CURDATE()))")
			->limit(1)
			->findAll()
			->getData();

		if (count($arr) === 1)
		{
			$arr = $arr[0];
			
			$pjListingModel->reset()->setAttributes(array('id' => $arr['id']))->modify(array('views' => $arr['views'] + 1));

			$this->set('extra_arr', pjExtraModel::factory()
				->select('t1.*, t2.content AS extra_title')
				->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.status', 'T')
				->orderBy('extra_title ASC')
				->findAll()
				->getData()
			);

			$this->set('gallery_arr', pjGalleryModel::factory()->where('t1.foreign_id', $_GET['id'])->orderBy('t1.sort ASC')->findAll()->getData());
			$arr['extras'] = pjListingExtraModel::factory()->where('t1.listing_id', $_GET['id'])->findAll()->getDataPair(NULL, 'extra_id');

			$this->set('price_arr', pjPriceModel::factory()
				->where('listing_id', $_GET['id'])
				->orderBy('date_from ASC, date_to ASC')
				->findAll()
				->getData()
			);

			$this->set('reservation_arr', $this->pjActionGetReservations($_GET['id']));
			$this->set('calendar', $this->pjActionGetCalendar($arr['o_price_based_on']));
			$this->set('listing_id', $_GET['id']);

			$this->set('arr', $arr);
			$this->set('price_raw_arr', $this->pjActionGetRawPrices($_GET['id']));
			$this->set('meta_arr', array(
				'title' => !empty($arr['meta_title']) ? $arr['meta_title'] :  $arr['listing_title'],
				'keywords' => !empty($arr['meta_keywords']) ? $arr['meta_keywords'] : __('ws_details_meta_keywords', true),
				'description' => !empty($arr['meta_description']) ? $arr['meta_description'] : __('ws_details_meta_description', true)
			));
			
			if (isset($_SESSION[$this->defaultSearch]))
			{
				if (!isset($_POST['date_from']) && isset($_SESSION[$this->defaultSearch]['date_from']))
				{
					$_POST['date_from'] = pjUtil::formatDate($_SESSION[$this->defaultSearch]['date_from'], "Y-m-d", $this->option_arr['o_date_format']);
				}
				if (!isset($_POST['date_to']) && isset($_SESSION[$this->defaultSearch]['date_to']))
				{
					$_POST['date_to'] = pjUtil::formatDate($_SESSION[$this->defaultSearch]['date_to'], "Y-m-d", $this->option_arr['o_date_format']);
				}
			}
			if (isset($_POST['date_from']) && !empty($_POST['date_from']) && isset($_POST['date_to']) && !empty($_POST['date_to']))
			{
				$this->set('p_arr', pjAppController::pjActionGetPrices(array(
					'listing_id' => $_GET['id'],
					'date_from' => pjUtil::formatDate($_POST['date_from'], $this->option_arr['o_date_format']),
					'date_to' => pjUtil::formatDate($_POST['date_to'], $this->option_arr['o_date_format'])
				)));
			}

			if($_GET['controller'] == 'pjWebsite')
			{
				$this->set('feature_arr', $this->getFeaturedListings($this->option_arr, $this->getLocaleId(), true));
			}
			
			$draw_arr = pjDrawSearchModel::factory()->findAll()->getData();
			$draw_arr = !empty($draw_arr) ? $draw_arr[0] : array();
			$this->set('draw_arr', $draw_arr);
			
			$dm = new pjDependencyManager(PJ_INSTALL_PATH, PJ_THIRD_PARTY_PATH);
			$dm->load(PJ_CONFIG_PATH . 'dependencies.php')->resolve();
			
			$this->appendCss('calendar.css');
			$this->appendCss('pjQuery.fancybox.css', PJ_INSTALL_URL . $dm->getPath('pj_fancybox'), true);
		} else {

		}
	}

	public function pjActionAdd()
	{
		if ($this->option_arr['o_allow_add_property'] == 'No')
		{
			$meta_arr = pjMultiLangModel::factory()->getMultiLang(1, 'pjOption');
					
			$this->set('meta_arr', array(
				'title' => isset($meta_arr[$this->getLocaleId()]['login_meta_title']) ? $meta_arr[$this->getLocaleId()]['login_meta_title'] : null,
				'keywords' => isset($meta_arr[$this->getLocaleId()]['login_meta_keywords']) ? $meta_arr[$this->getLocaleId()]['login_meta_keywords'] : null,
				'description' => isset($meta_arr[$this->getLocaleId()]['login_meta_description']) ? $meta_arr[$this->getLocaleId()]['login_meta_description'] : null
			));
			
			if (isset($_GET['listing_register']))
			{
				set_time_limit(0);

				if (!isset($_GET['register_email']))
				{
					$err = 9901;
				}
				if (!isset($_GET['register_password']))
				{
					$err = 9902;
				}
				if (!isset($_GET['register_password_repeat']))
				{
					$err = 9903;
				}
				if (!isset($_GET['name']))
				{
					$err = 9904;
				}
				if (!isset($_GET['verification']))
				{
					$err = 9905;
				}
				if (isset($_GET['register_email']) && !pjValidation::pjActionNotEmpty($_GET['register_email']))
				{
					$err = 9906;
				}
				if (isset($_GET['register_password']) && !pjValidation::pjActionNotEmpty($_GET['register_password']))
				{
					$err = 9907;
				}
				if (isset($_GET['register_password_repeat']) && !pjValidation::pjActionNotEmpty($_GET['register_password_repeat']))
				{
					$err = 9908;
				}
				if (isset($_GET['name']) && !pjValidation::pjActionNotEmpty($_GET['name']))
				{
					$err = 9909;
				}
				if (isset($_GET['verification']) && !pjValidation::pjActionNotEmpty($_GET['verification']))
				{
					$err = 9910;
				}
				if (isset($_GET['verification']) && isset($_SESSION[$this->defaultCaptcha]) && !pjCaptcha::validate($_GET['verification'], $_SESSION[$this->defaultCaptcha]))
				{
					$err = 9911;
				}
				if (isset($_GET['register_email']) && !pjValidation::pjActionEmail($_GET['register_email']))
				{
					$err = 9912;
				}
				if (isset($_GET['register_password']) && isset($_GET['register_password_repeat']) && $_GET['register_password'] != $_GET['register_password_repeat'])
				{
					$err = 9913;
				}
				if (isset($_SESSION[$this->defaultCaptcha]))
				{
					$_SESSION[$this->defaultCaptcha] = NULL;
					unset($_SESSION[$this->defaultCaptcha]);
				}
				if (isset($err))
				{
					pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionAdd&err=$err");
				}
				
				if (isset($_SESSION[$this->defaultCaptcha]))
				{
					$_SESSION[$this->defaultCaptcha] = NULL;
					unset($_SESSION[$this->defaultCaptcha]);
				}
				
				$pjUserModel = pjUserModel::factory();
				$arr = $pjUserModel->where('t1.email', $_GET['register_email'])->findAll()->getData();
	
				if (!empty($arr) && count($arr) > 0)
				{
					pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionAdd&err=9997");
				} else {
					$data['password'] = $_GET['register_password'];
					$data['email'] = $_GET['register_email'];
					$data['role_id'] = 3;
					$data['is_active'] = $this->option_arr['o_is_active_owner'] == 'Yes' ? 'T' : 'F';
					$data['ip'] = $_SERVER['REMOTE_ADDR'];
					$data = array_merge($_GET, $data);
					
					$id = $pjUserModel->reset()->setAttributes($data)->insert()->getInsertId();
					if ($id !== false && (int) $id > 0)
					{
						$this->notify(1, NULL, array('name' => $data['name'], 'email' => $data['email']));
						
						$admin = $pjUserModel->reset()->find(1)->getData();
						
						$pjEmail = new pjEmail();
						$pjEmail
							->setTo($data['email'])
							->setFrom($this->getFromEmail($this->option_arr))
							->setSubject($this->option_arr['o_email_welcome_msg_subject']);
				
						if ($this->option_arr['o_send_email'] == 'smtp')
						{
							$pjEmail
								->setTransport('smtp')
								->setSmtpHost($this->option_arr['o_smtp_host'])
								->setSmtpPort($this->option_arr['o_smtp_port'])
								->setSmtpUser($this->option_arr['o_smtp_user'])
								->setSmtpPass($this->option_arr['o_smtp_pass'])
								->setSender($this->option_arr['o_smtp_user']);
						}
						
						$body = str_replace(
							array('{Name}', '{Password}', '{Email}'),
							array($data['name'], $data['password'], $data['email']),
							$this->option_arr['o_email_welcome_msg']
						);
		
						$pjEmail->send($body);
						
						if ($this->option_arr['o_is_active_owner'] == 'Yes')
						{
							pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionAdd&err=9999");
						} else {
							pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionAdd&err=9998");
						}
						exit;
					}
				}
			}
	
		} else {
			pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionListings");
		}
	}
	
	public function pjActionForgot()
	{
		if ($this->option_arr['o_allow_add_property'] == 'No')
		{
			if (isset($_GET['forgot_password']))
			{
				set_time_limit(0);
					
				if (!isset($_GET['email']))
				{
					$err = 9901;
				}
				if (isset($_GET['email']) && !pjValidation::pjActionNotEmpty($_GET['email']))
				{
					$err = 9902;
				}
				if (isset($err))
				{
					pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjListings&action=pjActionForgot&err=$err");
				}
				$pjUserModel = pjUserModel::factory();
				$arr = $pjUserModel->where('t1.email', $_GET['email'])->findAll()->getData();
			
				if (empty($arr) || count($arr) == 0)
				{
					pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjListings&action=pjActionForgot&err=9903");
				}else{
					$user = $arr[0];
					
					$Email = new pjEmail();
					$Email
						->setTo($user['email'])
						->setFrom($this->getFromEmail($this->option_arr))
						->setSubject($this->option_arr['o_email_password_reminder_subject']);
					
					if ($this->option_arr['o_send_email'] == 'smtp')
					{
						$Email
							->setTransport('smtp')
							->setSmtpHost($this->option_arr['o_smtp_host'])
							->setSmtpPort($this->option_arr['o_smtp_port'])
							->setSmtpUser($this->option_arr['o_smtp_user'])
							->setSmtpPass($this->option_arr['o_smtp_pass'])
							->setSender($this->option_arr['o_smtp_user']);
						;
					}
					
					$body = str_replace(
						array('{Name}', '{Password}', '{Email}'),
						array($user['name'], $user['password'], $user['email']),
						$this->option_arr['o_email_password_reminder']
					);
	
					$Email->send($body);
					pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjListings&action=pjActionForgot&err=9999");
				}
			}
		} else {
			pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=".$_GET['controller']."&action=pjActionListings");
		}
	}

	public function pjActionConfirmAuthorize()
	{
		$this->setAjax(true);
		
		if (pjObject::getPlugin('pjAuthorize') === NULL)
		{
			$this->log('Authorize.NET plugin not installed');
			exit;
		}
		$pjReservationModel = pjReservationModel::factory();
		$booking_arr = $pjReservationModel->where('t1.uuid', $_POST['x_invoice_num'])->limit(1)->findAll()->getData();
		if (!empty($booking_arr))
		{
			$booking_arr = $booking_arr[0];
			$listing_arr = pjListingModel::factory()
				->select('t1.*, t2.email AS email_address, t3.content AS confirm_tokens, t4.content AS payment_tokens,
						t5.content AS confirm_subject, t6.content AS payment_subject')
				->join('pjUser', 't2.id=t1.owner_id', 'inner')
				->join('pjMultiLang', "t3.model='pjListing' AND t3.foreign_id=t1.id AND t3.field='confirm_tokens' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='payment_tokens' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='confirm_subject' AND t5.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t6.model='pjListing' AND t6.foreign_id=t1.id AND t6.field='payment_subject' AND t6.locale='".$this->getLocaleId()."'", 'left outer')
				->find($booking_arr['listing_id'])->getData();
			$params = array(
				'transkey' => $listing_arr['o_authorize_transkey'],
				'x_login' => $listing_arr['o_authorize_merchant_id'],
				'md5_setting' => $listing_arr['o_authorize_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 && isset($response['status']) && $response['status'] === 'OK')
			{
				$map = array(1 => 'Confirmed', 2 => 'Pending', 3 => 'Cancelled');
				$this->log('Booking confirmed');
				$pjReservationModel
					->reset()
					->set('id', $booking_arr['id'])
					->modify(array('status' => $map[$listing_arr['o_default_status_if_paid']]));
				pjAppController::pjActionConfirmSend($this->option_arr, $booking_arr, $listing_arr, 'payment');
			} elseif (!$response) {
				$this->log('Authorization failed');
			} else {
				$this->log('Booking not confirmed. ' . $response['response_reason_text']);
			}
		}
		exit;
	}

	public function pjActionConfirmPaypal()
	{
		$this->setAjax(true);
		
		if (pjObject::getPlugin('pjPaypal') === NULL)
		{
			$this->log('Paypal plugin not installed');
			exit;
		}
		$pjReservationModel = pjReservationModel::factory();
		$booking_arr = $pjReservationModel->where('t1.uuid', $_POST['custom'])->limit(1)->findAll()->getData();
		$listing_arr = array();
		if (!empty($booking_arr))
		{
			$booking_arr = $booking_arr[0];

			$listing_arr = pjListingModel::factory()
				->select('t1.*, t2.email AS email_address, t3.content AS confirm_tokens, t4.content AS payment_tokens,
						t5.content AS confirm_subject, t6.content AS payment_subject')
				->join('pjUser', 't2.id=t1.owner_id', 'inner')
				->join('pjMultiLang', "t3.model='pjListing' AND t3.foreign_id=t1.id AND t3.field='confirm_tokens' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='payment_tokens' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='confirm_subject' AND t5.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t6.model='pjListing' AND t6.foreign_id=t1.id AND t6.field='payment_subject' AND t6.locale='".$this->getLocaleId()."'", 'left outer')
				->find($booking_arr['listing_id'])->getData();
		}
		$params = array(
			'txn_id' => @$booking_arr['txn_id'],
			'paypal_address' => @$listing_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 && isset($response['status']) && $response['status'] === 'OK')
		{
			$map = array(1 => 'Confirmed', 2 => 'Pending', 3 => 'Cancelled');
			$this->log('Booking confirmed');
			$pjReservationModel->reset()->set('id', $booking_arr['id'])->modify(array(
				'status' => $map[$listing_arr['o_default_status_if_paid']],
				'txn_id' => $response['transaction_id'],
				'processed_on' => ':NOW()'
			));
			pjAppController::pjActionConfirmSend($this->option_arr, $booking_arr, $listing_arr, 'payment');
		} elseif (!$response) {
			$this->log('Authorization failed');
		} else {
			$this->log('Booking not confirmed');
		}
		exit;
	}
	
	public function pjActionConfirmPayment()
	{
		$this->setAjax(true);
		
		if (pjObject::getPlugin('pjPaypal') === NULL)
		{
			$this->log('Paypal plugin not installed');
			exit;
		}
		
		list($uuid, $listing_id) = explode("-", $_POST['custom']);
		
		$pjPaymentModel = pjPaymentModel::factory();
		$pjListingModel = pjListingModel::factory();
		$listing_arr = $pjListingModel->find($listing_id)->getData();
		$payment_arr = $pjPaymentModel->where('t1.listing_id', $listing_id)->orderBy('t1.date_to DESC')->limit(1)->findAll()->getData();
		$period_arr = pjPeriodModel::factory()->findAll()->getData();
		$date_from = date("Y-m-d");
		if (count($payment_arr) === 1)
		{
			$date_from = $payment_arr[0]['date_to'];
		}
		
		$period = $price = NULL;
		foreach ($period_arr as $_period)
		{
			if ((float) $_period['price'] == (float) $_POST['mc_gross'])
			{
				$period = (int) $_period['days'];
				$price = (float) $_period['price'];
				break;
			}
		}
		list($year, $month, $day) = explode("-", $date_from);
		$date_to = date("Y-m-d", mktime(0, 0, 0, $month, $day + $period, $year));
		
		$params = array(
			'txn_id' => @$payment_arr[0]['txn_id'],
			'paypal_address' => $this->option_arr['o_paypal_address'],
			'deposit' => $price,
			'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 && isset($response['status']) && $response['status'] === 'OK')
		{
			$this->log('pjPaypal > pjActionConfirm > status == OK');
			$pjPaymentModel
				->reset()
				->setAttributes(array(
					'listing_id' => $listing_arr['id'],
					'date_from' => $date_from,
					'date_to' => $date_to,
					'txn_id' => $response['transaction_id'],
					'price' => $price
				))
				->insert();
			$current = time();
			if (!empty($listing_arr['expire']) && $listing_arr['expire'] != '0000-00-00')
			{
				$current = strtotime($listing_arr['expire']);
			}
			pjListingModel::factory()
				->set('id', $listing_arr['id'])
				->modify(array(
					'last_extend' => 'paid',
					'expire' => date("Y-m-d", $current + $period * 86400)
				));
			$this->log('Payment confirmed');
		} elseif (!$response) {
			$this->log('Authorization failed');
		} else {
			$this->log('Payment not confirmed');
		}
		exit;
	}
	
	public function pjActionFeatured()
	{
		$this->set('country_arr', pjCountryModel::factory()
			->select('t1.*, 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')
			->where('t1.status', 'T')->orderBy('country_title ASC')->findAll()->getData()
		);
		
		$this->set('type_arr', pjTypeModel::factory()
			->select('t1.*, t2.content AS type_title')
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->where('t1.status', 'T')->orderBy('type_title ASC')->findAll()->getData()
		);
		
		$params = $this->getParams();
		if (isset($params['search']) && $params['search'] === true)
		{
			$this->set('extra_arr', pjExtraModel::factory()
				->select('t1.*, t2.content AS extra_title')
				->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.status', 'T')->orderBy('extra_title ASC')->findAll()->getData()
			);
		}
			
		$this->set('arr', $this->getFeaturedListings($this->option-arr, $this->getLocaleId(), false));
	}

	public function pjActionGetAvailability()
	{
		$this->setAjax(true);
	
		$arr = pjListingModel::factory()->find($_GET['listing_id'])->getData();
	
		$this->set('calendar', $this->pjActionGetCalendar($arr['o_price_based_on']));
		$this->set('reservation_arr', $this->pjActionGetReservations($_GET['listing_id']));
		$this->set('price_raw_arr', $this->pjActionGetRawPrices($_GET['listing_id']));
	}
	
	public function pjActionGetPrice()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			$date_from = pjUtil::formatDate($_POST['date_from'], $this->option_arr['o_date_format']);
			$date_to = pjUtil::formatDate($_POST['date_to'], $this->option_arr['o_date_format']);
			
			$is_reserved = false;
			$passCheck = true;
			if(!empty($_POST['date_from']) && !empty($_POST['date_to']))
			{
				$listing_arr = pjListingModel::factory()->find($_POST['listing_id'])->getData();
				
				$numOfDays = (strtotime($date_to) - strtotime($date_from)) / 86400;
				if ((int) $listing_arr['o_price_based_on'] === 1)
				{
					$numOfDays += 1;
				}
				if ($listing_arr['o_min_booking_lenght'] != '' && $numOfDays < (int) $listing_arr['o_min_booking_lenght'])
				{
					$this->set('status', 9);
					$passCheck = false;
				}
				if ($listing_arr['o_max_booking_lenght'] != '' && $numOfDays > (int) $listing_arr['o_max_booking_lenght'])
				{
					$this->set('status', 10);
					$passCheck = false;
				}
				if($passCheck == true)
				{
					$where_str = "(t1.status='Confirmed')";
					if($listing_arr['o_book_pending'] == 0)
					{
						$where_str = "(t1.status='Confirmed' OR t1.status='Pending')";
					}	
					if($listing_arr['o_price_based_on'] == 1)
					{
						$cnt_reservations = pjReservationModel::factory()
							->where('t1.listing_id', $_POST['listing_id'])
							->where($where_str)
							->where("((`date_from` BETWEEN '$date_from' AND '$date_to') OR (`date_to` BETWEEN '$date_from' AND '$date_to') OR ('$date_from' BETWEEN `date_from` AND `date_to`) OR ('$date_to' BETWEEN `date_from` AND `date_to`))")
							->findCount()
							->getData();
						if($cnt_reservations > 0)
						{
							$is_reserved = true;
						}
					}else{
						if($date_from < $date_to)
						{	
							$cnt_reservations = pjReservationModel::factory()
								->where('t1.listing_id', $_POST['listing_id'])
								->where($where_str)
								->where("((`date_from` > '$date_from' AND `date_from` < '$date_to') OR (`date_to` > '$date_from' AND `date_to` < '$date_to') OR ('$date_from' > `date_from` AND '$date_from' < `date_to`) OR ('$date_to' > `date_from` AND '$date_to' < `date_to`) OR ('$date_from' = `date_from` AND '$date_to' = `date_to`))")
								->findCount()
								->getData();
	
							if($cnt_reservations > 0)
							{
								$is_reserved = true;
							}
						}else{
							$is_reserved = true;
						}
					}
				}
				$this->set('arr', $listing_arr);
			}
			if($is_reserved == false && $passCheck == true)
			{
				$arr = pjAppController::pjActionGetPrices(array_merge($_POST, array('date_from' => $date_from,'date_to' => $date_to)));
				$this->set('p_arr', $arr);
			}
		}
	}
	
	public function pjActionImage()
	{
		$this->setAjax(true);
		$this->setLayout('pjActionEmpty');
	
		$width = isset($_GET['width']) && (int) $_GET['width'] > 0 ? intval($_GET['width']) : 100;
		$height = isset($_GET['height']) && (int) $_GET['height'] > 0 ? intval($_GET['height']) : 100;
	
		$image = imagecreate($width, $height);
		$backgroundColor = pjUtil::html2rgb($_GET['color1']);
		$color = imagecolorallocate($image, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
		imagefill($image, 0, 0, $color);
	
		if (isset($_GET['color2']) && !empty($_GET['color2']))
		{
			if ($_GET['color1'] == $_GET['color2'])
			{
				$backgroundColor = pjUtil::html2rgb('ffffff');
				$color = imagecolorallocate($image, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
	
				$values = array(
						0, $height-2,
						$width-2, 0,
						$width, 0,
						$width, 1,
						1, $height,
						0, $height,
						0, $height-1
				);
				imagefilledpolygon($image, $values, 7, $color);
			} else {
				$backgroundColor = pjUtil::html2rgb($_GET['color2']);
				$color = imagecolorallocate($image, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
				$values = array(
						$width,  0,
						$width,  $height,
						0, $height,
						$width,  0
				);
				imagefilledpolygon($image, $values, 4, $color);
			}
		}
	
		header('Content-Type: image/jpeg');
		imagejpeg($image);
		imagedestroy($image);
		exit;
	}
	
	public function getFeaturedListings($option_arr, $locale_id, $website=false)
	{
		$pjListingModel = pjListingModel::factory()
			->where("(t1.status = 'T' OR (t1.status = 'E' AND t1.expire >= CURDATE()))")
			->where('t1.is_featured', 'T');
		
		$limit = $option_arr['o_limit_featured_results'];
		if($website == false)
		{
			switch ($option_arr['o_sort_by'])
			{
				case 'created_asc':
					$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, created ASC, listing_title ASC", false);
					break;
				case 'created_desc':
					$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, created DESC, listing_title ASC", false);
					break;
				case 'random':
					$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, RAND()", false);
					break;
				case 'popularity':
				default:
					$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, views DESC, listing_title ASC", false);
					break;
			}
		}else{
			$limit = 3;
			$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, RAND()", false);
		}
		$arr = $pjListingModel
			->select(sprintf("t1.*, t2.content AS type_title, t3.content AS country_title, t4.content AS listing_title, t5.content AS listing_description,
					(SELECT `medium_path` FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` ORDER BY `sort` ASC LIMIT 1) AS `pic`,
					(SELECT MIN(`price`) FROM `%2\$s` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `price`,
					(SELECT MAX(`price`) FROM `%2\$s` WHERE `listing_id` = `t1`.`id` LIMIT 1) AS `max_price`
				", pjGalleryModel::factory()->getTable(), pjPriceModel::factory()->getTable()))
			->join('pjMultiLang', "t2.model='pjType' AND t2.foreign_id=t1.type_id AND t2.field='name' AND t2.locale='".$locale_id."'", 'left outer')
			->join('pjMultiLang', "t3.model='pjCountry' AND t3.foreign_id=t1.country_id AND t3.field='name' AND t3.locale='".$locale_id."'", 'left outer')
			->join('pjMultiLang', "t4.model='pjListing' AND t4.foreign_id=t1.id AND t4.field='title' AND t4.locale='".$locale_id."'", 'left outer')
			->join('pjMultiLang', "t5.model='pjListing' AND t5.foreign_id=t1.id AND t5.field='description' AND t5.locale='".$locale_id."'", 'left outer')
			->limit($limit)
			->findAll()
			->getData();
	
		return $arr;
	}
		
	private function pjActionGetReservations($id)
	{
		$listing_arr = pjListingModel::factory()->find($id)->getData();
		$where_str = "(t1.status='Confirmed')";
		if($listing_arr['o_book_pending'] == 0)
		{
			$where_str = "(t1.status='Confirmed' OR t1.status='Pending')";
		}
		$reservation_arr = pjReservationModel::factory()
			->select('t1.*, t2.listing_refid')
			->join('pjListing', "t2.id=t1.listing_id AND t2.status IN ('T','E')", 'inner')
			->where('t1.listing_id', $id)
			->where($where_str)
			->orderBy('t1.date_from ASC, t1.date_to ASC')
			->findAll()
			->getData();
		
		$r_arr = array();
		$i = 0;
		$_from = $_to = $_map = array();
		foreach ($reservation_arr as $r)
		{
			$r_arr[$i]['date_from'] = strtotime($r['date_from']);
			$r_arr[$i]['date_to'] = strtotime($r['date_to']);
			$_from[] = $r_arr[$i]['date_from'];
			$_to[] = $r_arr[$i]['date_to'];
			$i++;
		}
		if (count($_from) > 0)
		{
			$min = min($_from);
			$max = max($_to);
			for ($i = $min; $i <= $max; $i += 86400)
			{
				$_map[$i] = array('start' => 0, 'in' => 0, 'end' => 0);
			}
			foreach ($reservation_arr as $r)
			{
				$from = strtotime($r['date_from']);
				$to = strtotime($r['date_to']);
				$_map[$from]['start'] += 1;
				$_map[$to]['end'] += 1;
				for ($i = $from + 86400; $i < $to; $i += 86400)
				{
					$_map[$i]['in'] += 1;
				}
			}
		}
		return array('map' => $_map, 'bookings' => $r_arr);
	}

	private function pjActionGetCalendar($priceBasedOn=1)
	{
		$months = __('months', true);
		ksort($months);
		$dayNames = __('day_names', true);
		ksort($dayNames);
		
		return pjABCalendar::factory()
			->setStartDay($this->option_arr['o_week_start'])
			->setPriceBasedOn($priceBasedOn)
			->setMonthNames(array_values($months))
			->setDayNames($dayNames);
	}

	private function pjActionGetRawPrices($listing_id)
	{
		$price_arr = pjPriceModel::factory()
			->where('t1.listing_id', $listing_id)
			->orderBy('t1.date_from ASC, t1.date_to ASC')
			->findAll()
			->getData();
		
		$pr_arr = array();
    	foreach ($price_arr as $period)
    	{
    		$price = pjUtil::formatFrontCurrencySign(number_format($period['price'], 0), $this->option_arr['o_currency']);
    		$start = strtotime($period['date_from']);
    		$end = strtotime($period['date_to']);
    		for ($i = $start; $i <= $end; $i += 86400)
    		{
    			$pr_arr[$i] = $price;
    		}
    	}
    	return $pr_arr;
	}
	
	private function pjActionCriteria($get)
	{
		$pjListingModel = pjListingModel::factory()->where("(t1.status = 'T' OR (t1.status = 'E' AND t1.expire >= CURDATE()))");
		
		if(isset($get['listing_search']))
		{
			$date_from = pjUtil::formatDate(@$get['date_from'], $this->option_arr['o_date_format']);
			$date_to = pjUtil::formatDate(@$get['date_to'], $this->option_arr['o_date_format']);
	
			$_SESSION[$this->defaultSearch] = array_merge($get, compact('date_from', 'date_to'));
			if($get['previous_action'] == 'pjActionSearch')
			{
				$pjListingModel->where('t1.address_map', '1');
			}
			if (isset($get['date_from'], $get['date_to']) && !empty($get['date_from']) && !empty($get['date_to']))
			{
				$pjListingModel->where(sprintf("t1.id NOT IN (
					SELECT `listing_id`
					FROM `%s`
					WHERE `status` = 'Confirmed'
					AND `date_from` < '%s'
					AND `date_to` > '%s'
				)", pjReservationModel::factory()->getTable(), $date_to, $date_from));
			}
			if (isset($get['type_id']) && (int) $get['type_id'] > 0)
			{
				$pjListingModel->where('t1.type_id', $get['type_id']);
			}
			if (isset($get['refid']) && !empty($get['refid']))
			{
				$refid = $pjListingModel->escapeStr($get['refid']);
				$refid = str_replace(array('%', '_'), array('\%', '\_'), trim($refid));
				$pjListingModel->where("t1.listing_refid LIKE '%" . $refid . "%'");
			}
			if (isset($get['bedrooms_from']) && (int) $get['bedrooms_from'] > 0)
			{
				$pjListingModel->where('t1.listing_bedrooms >=', $get['bedrooms_from']);
			}
			if (isset($get['bedrooms_to']) && (int) $get['bedrooms_to'] > 0)
			{
				$pjListingModel->where('t1.listing_bedrooms <=', $get['bedrooms_to']);
			}
			if (isset($get['bathrooms_from']) && (float) $get['bathrooms_from'] > 0)
			{
				$pjListingModel->where('t1.listing_bathrooms >=', $get['bathrooms_from']);
			}
			if (isset($get['bathrooms_to']) && (float) $get['bathrooms_to'] > 0)
			{
				$pjListingModel->where('t1.listing_bathrooms <=', $get['bathrooms_to']);
			}
			if (isset($get['adults_from']) && (int) $get['adults_from'] > 0)
			{
				$pjListingModel->where('t1.listing_adults >=', $get['adults_from']);
			}
			if (isset($get['adults_to']) && (int) $get['adults_to'] > 0)
			{
				$pjListingModel->where('t1.listing_adults <=', $get['adults_to']);
			}
			if (isset($get['children_from']) && (int) $get['children_from'] > 0)
			{
				$pjListingModel->where('t1.listing_children >=', $get['children_from']);
			}
			if (isset($get['children_to']) && (int) $get['children_to'] > 0)
			{
				$pjListingModel->where('t1.listing_children <=', $get['children_to']);
			}
			if (isset($get['location']) && !empty($get['location']))
			{
				$location = $pjListingModel->escapeStr($get['location']);
				$location = str_replace(array('%', '_'), array('\%', '\_'), trim($location));
				$or_str = " OR t1.country_id IN (SELECT TM.foreign_id FROM `".pjMultiLangModel::factory()->getTable()."` AS `TM` WHERE TM.model='pjCountry' AND TM.locale='".$this->getLocaleId()."' AND TM.content LIKE '%".$location."%') ";
				$pjListingModel->where("(t1.address_city LIKE '%". $location ."%' OR t1.address_state LIKE '%". $location ."%' OR t1.address_content LIKE '%". $location ."%'$or_str)");
			}
	
			if (isset($get['data']) && !empty($get['data']) && strpos($get['data'], ",") !== false && pjObject::getPlugin('pjDrawSearch') !== NULL)
			{
				preg_match_all('/(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)/', $get['data'], $m);
				$data_str = preg_replace('/\((\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)\)/', '\2 \1', $get['data']);
				$data_str .= sprintf(",%s %s", $m[2][0], $m[1][0]);
				$pjListingModel->where('t1.lat IS NOT NULL');
				$pjListingModel->where('t1.lng IS NOT NULL');
	
				$within = 'GISWithin';
				$r = $pjListingModel->prepare("SELECT VERSION() AS `version`;")->exec()->getDataIndex(0);
				if ($r !== FALSE)
				{
					$version = preg_replace('/[^\d\.]/', '', $r['version']);
					if ((version_compare($version, '5.3.3', '>=') && strpos($r['version'], 'MariaDB') !== FALSE) || version_compare($version, '5.6.1', '>='))
					{
						$within = 'ST_Within';
					}
				}
				$pjListingModel->where("$within(Point(t1.lng, t1.lat), GeomFromText('POLYGON(($data_str))'))");
			}
		}
	
		switch ($this->option_arr['o_sort_by'])
		{
			case 'created_asc':
				$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, created ASC, listing_title ASC", false);
				break;
			case 'created_desc':
				$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, created DESC, listing_title ASC", false);
				break;
			case 'random':
				$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, RAND()", false);
				break;
			case 'popularity':
			default:
				$pjListingModel->orderBy("FIELD(is_featured, 'T', 'F') ASC, views DESC, listing_title ASC", false);
				break;
		}
	
		return $pjListingModel;
	}
	
	public function pjActionCancel()
	{
		$this->setLayout('pjActionCancel');
	
		$pjReservationModel = pjReservationModel::factory();
	
		if (isset($_POST['reservation_cancel']))
		{
			$booking_arr = $pjReservationModel
				->find($_POST['id'])->getData();
			if (count($booking_arr) > 0)
			{
				$sql = "UPDATE `".$pjReservationModel->getTable()."` SET status = 'Cancelled' WHERE SHA1(CONCAT(`id`, `created`)) = '" . $_POST['hash'] . "'";
	
				$pjReservationModel->reset()->execute($sql);
	
				$arr = $pjReservationModel
					->reset()
					->find($_POST['id'])
					->getData();
				$listing_arr = pjListingModel::factory()->find($arr['listing_id'])->getData();
				pjAppController::pjActionConfirmSend($this->option_arr, $arr, $listing_arr, 'cancel');
	
				$this->notify(5, NULL, array('reservation_id' => $arr['id']));
				$this->notify(6, $arr['owner_id'], array('reservation_id' => $arr['id']));
				
				pjUtil::redirect($_SERVER['PHP_SELF'] . '?controller=pjListings&action=pjActionCancel&err=200');
			}
		}else{
			if (isset($_GET['hash']) && isset($_GET['id']))
			{
				$arr = $pjReservationModel
					->select("t1.*, t2.content as listing_title,
							AES_DECRYPT(t1.cc_num, '".PJ_SALT."') AS `cc_num`,
							AES_DECRYPT(t1.cc_exp, '".PJ_SALT."') AS `cc_exp`,
							AES_DECRYPT(t1.cc_code, '".PJ_SALT."') AS `cc_code`")
					->join('pjMultiLang', "t2.model='pjListing' AND t2.foreign_id=t1.listing_id AND t2.field='title' AND t2.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']);
						if ($_GET['hash'] != $hash)
						{
							$this->set('status', 3);
						}else{
	
							$this->set('arr', $arr);
						}
					}
				}
			}else if (!isset($_GET['err'])) {
				$this->set('status', 1);
			}
		}
	}
}
?>