<?php

/******************************************************************************
 *  
 *  PROJECT: Flynax Classifieds Software
 *  VERSION: 4.5.2
 *  LICENSE: FL4HLD2A8696 - http://www.flynax.com/license-agreement.html
 *  PRODUCT: Real Estate Classifieds
 *  DOMAIN: savingrack.com
 *  FILE: RLPAYMENT.CLASS.PHP
 *  
 *  The software is a commercial product delivered under single, non-exclusive,
 *  non-transferable license for one domain or IP address. Therefore distribution,
 *  sale or transfer of the file in whole or in part without permission of Flynax
 *  respective owners is considered to be illegal and breach of Flynax License End
 *  User Agreement.
 *  
 *  You are not allowed to remove this information from the file without permission
 *  of Flynax respective owners.
 *  
 *  Flynax Classifieds Software 2017 | All copyrights reserved.
 *  
 *  http://www.flynax.com/
 ******************************************************************************/

class rlPayment extends reefless
{
	const POST_URL = 'post';
	
	const CHECKOUT_URL = 'checkout';

	const SUCCESS_URL = 'success';

	const FAIL_URL = 'fail';

	/**
	* @var array $payment_data
	*/
	protected $payment_data;
	
	/**
	* recurring mod of current payment
	* 
	* @var $recurring
	*/
	protected $recurring;

	/**
	* @var string $transaction_id_local 
	**/
	protected $transaction_id;

	/**
	* @var bool $gateways_page  	
	*/
	public $gateways_page = false;

	/**
	* @var array $required_option 
	*/
	protected $required_option = array('service', 'total', 'item_id', 'account_id');
	
	/**
	* @var $gateway_info
	*/
	public $gateway_info;
	
	/**
	* @var $notify_url
	*/
	protected $notify_url;
	
	/**
	* @var $bread_crumbs
	*/
	protected $bread_crumbs;
	
	/**
	* @var $gateways
	*/
	public $gateways;
	
	/**
	* checkout referer
	* 
	* @var $referer
	*/
	protected $referer;
	
	/**
	* @var $is_form
	*/
	protected $is_form;
	
	/**
	* payment form
	* 
	* @var $form
	*/
	protected $form;

	/**
	* Constructor
	*/
	public function __construct()
	{
		// set payment form
		$this->setForm('blocks' . RL_DS . 'credit_card_payment.tpl');

		if (!isset($GLOBALS['rlActions'])) {
			$this->loadClass('Actions');
		}
		if (!empty($_SESSION['complete_payment'])) {
			$this->payment_data = $_SESSION['complete_payment'];
			// set redirect mode
			if (isset($_SESSION['complete_payment']['redirect'])) {
				$this->gateways_page = (bool)$_SESSION['complete_payment']['redirect'];
			}
			if ($_SESSION['complete_payment']['referer']) {
				$this->referer = $_SESSION['complete_payment']['referer'];
			}
		}
		if (isset($_SESSION['transaction_id'])) {
			$this->transaction_id = $_SESSION['transaction_id'];
		}
		if (isset($this->payment_data['gateway'])) {
			$this->setGateway($this->payment_data['gateway']);
		}
		if (count($_SESSION['payment_service_breadcumbs'])) {
			$this->bread_crumbs = $_SESSION['payment_service_breadcumbs'];
		}
		if ($_SESSION['complete_payment']['recurring']) {
			$this->enableRecurring();
		}

		// set callback URL
		$url = RL_URL_HOME;
		if ($_SERVER['HTTPS'] == 'on') {
			$url = str_replace('http://', 'https://', $url)	;
		}
		$url .= $GLOBALS['config']['mod_rewrite'] ? $GLOBALS['pages']['payment'] . '/'. self::POST_URL .'.html' : '?page=' . $GLOBALS['pages']['payment'] . '&rlVareables=' . self::POST_URL;
		$this->setNotifyURL($url);
		
		// get gateways
		$this->getGatewaysAll();
	}

	/**
	* initialize payment process
	* 
	* @param mixed $errors
	* @return null
	*/
	public function init(&$errors)
	{
		foreach ($this->required_option as $key => $value) {
			if (!isset($this->payment_data[$value])) {
				$errors[] = str_replace('{option}', $GLOBALS['lang']['payment_option_' . $value], $GLOBALS['lang']['required_payment_option_error']);
			}
		}

		if (count($this->gateways) <= 0) {
			$errors[] = $GLOBALS['lang']['not_available_payment_gateways'];
		}
		if (!$errors) {
			$this->clearTransactionID();
			$this->createTransaction();
			
			$GLOBALS['rlHook']->load('phpAfterCreatePaymentTxn');

			if ($this->isRedirect()) {
				$redirect_url = SEO_BASE;
				$redirect_url .= $GLOBALS['config']['mod_rewrite'] ? $GLOBALS['pages']['payment'] .'/'. self::CHECKOUT_URL .'.html' : '?page='. $GLOBALS['pages']['payment'] . '&rlVareables=' . self::CHECKOUT_URL;
				
				$this->redirect(false, $redirect_url);
				exit;
			}
		}
	}

	/**
	* get payment an option
	* 
	* @param string $key
	* @return string
	*/
	public function getOption($key)
	{
		if (isset($this->payment_data[$key])) {
			return $this->payment_data[$key];
		}
	}
  	
  	/**
  	* set payment option
  	* 
  	* @param string $key
  	* @param string $value
  	*/
	public function setOption($key, $value)
	{
		if ($key && $value) {
			$this->payment_data[$key] = $_SESSION['complete_payment'][$key] = $value;
		}
	}
	
	/**
	* check option
	* 
	* @param string $key
	* @return boolean
	*/
	public function hasOption($key)
	{
		if (isset($this->payment_data[$key])) {
			return true;
		}
		
		return false;
	}

	/**
	* clear current payment request
	* 
	*/
	public function clear()
	{
		$this->payment_data = false;
		$this->bread_crumbs = array();
		$this->recurring = false;
		$this->gateways_page = false;
		unset($_SESSION['complete_payment'], $_SESSION['payment_service_breadcumbs']);
	}
	
	/**
	* clear value of transaction ID
	* 
	*/
	public function clearTransactionID()
	{
		if ($this->getTransactionID()) {
			$transaction = $this->getTransaction();

			if ($transaction['Status'] == 'paid' || $transaction['Item_ID'] != $this->getOption('item_id')) {
				unset($_SESSION['transaction_id']);
				$this->transaction_id = '';	
			}
		}
	}
   	
   	/**
   	* create transaction
   	* 
   	* @return boolean
   	*/
	public function createTransaction()
	{
		if (!$this->isPrepare(false)) {
			return false;
		}
		if (!$this->getTransactionID()) {
			if ($transaction = $this->isExistsTransaction()) {
				$this->transaction_id = $_SESSION['transaction_id'] = (int)$transaction['ID'];
				return true;
			}
			$insert = array(
					'Service' => $this->getOption('service'),
					'Account_ID' => $this->getOption('account_id'),
					'Item_ID' => $this->getOption('item_id'),
					'Plan_ID' => $this->getOption('plan_id'),
					'Total' => $this->getOption('total'),
					'Date' => 'NOW()',
					'Item_name' => $this->getOption('item_name'),
					'Plan_key' => $this->getOption('plan_key') ? $this->getOption('plan_key') : ''
				);

			if ($this->hasOption('gateway')) {
				$insert['gateway'] = $this->getOption('gateway');
			}
			if ($GLOBALS['rlActions']->insertOne($insert, 'transactions')) {
				$this->transaction_id = $_SESSION['transaction_id'] = $this->insertID();
				return true;
			}
		} else {
			$update = array(
					'fields' => array(
							'Plan_ID' => $this->getOption('plan_id'),
							'Total' => $this->getOption('total'),
							'Plan_key' => $this->getOption('plan_key') ? $this->getOption('plan_key') : '',
							'Item_name' => $this->getOption('item_name')
						),
					'where' => array('ID' => $this->getTransactionID())
				);	
			if ($GLOBALS['rlActions']->updateOne($update, 'transactions')) {
				return true;
			}
		}

		return false;
	}
	
	/**
	* check if exists transaction
	* 
	*/
	public function isExistsTransaction()
	{
		$sql = "SELECT * FROM `" . RL_DBPREFIX . "transactions` WHERE `Service` = '".$this->getOption('service')."' AND `Item_ID` = '".$this->getOption('item_id')."' AND `Status` = 'unpaid' LIMIT 1";
		$transaction = $this->getRow($sql);
		
		if ($transaction) {
			return $transaction;
		}
		return false;
	}

	/**
	* update transaction status and set up transaction ID of gateway
	* 
	* @param integer $id
	* @param string $txn_id
	* @param string $status
	* @return data
	*/
	public function updateTransaction($id, $txn_id, $status, $total = false)
	{
		if (!$id) {
			return false;
		}               
		$sql = "UPDATE `" . RL_DBPREFIX . "transactions` SET `Total` = '{$total}', `Status` = '{$status}' ".($txn_id ? ", `Txn_ID` = '{$txn_id}' " : "")." WHERE `ID` = '{$id}' LIMIT 1";
		return $this->query($sql);
	}
   	
   	/**
   	* get current transaction ID
   	* 
   	* @return integer
   	*/
	public function getTransactionID()
	{
		if ($this->transaction_id) {
			return $this->transaction_id;
		}

		return false;
	}

	/**
	* set transaction ID
	* 
	* @param mixed $transaction_id
	*/
	public function setTransactionID($transaction_id = false)
	{
		if ($transaction_id) {
			$this->transaction_id = $transaction_id;
		}
	}

	/**
	* get gateway
	* 
	* @return string
	*/
	public function getGateway()
	{
		return $this->payment_data['gateway'];
	}

	/**
	* set gateway
	* 
	* @param mixed $gateway
	*/
	public function setGateway($gateway)
	{
		$this->payment_data['gateway'] = $_SESSION['complete_payment']['gateway'] = $gateway;
		$this->setGatewayToTransaction();
	}
	
	/**
	* add gateway to transaction
	* 
	*/
	public function setGatewayToTransaction()
	{
		$sql = "UPDATE `" . RL_DBPREFIX . "transactions` SET `Gateway` = '" . $this->getGateway() . "' WHERE `ID` = '" . $this->getTransactionID() . "' LIMIT 1";
		return $this->query($sql);
	}
	
	/**
	* get gateway details
	* 
	* @return data
	*/
	public function getGatewayDetails()
	{
		if ($this->getGateway()) {
			$sql = "SELECT * FROM `".RL_DBPREFIX."payment_gateways` WHERE `Key` = '{$this->getGateway()}' LIMIT 1";
			$this->gateway_info = $this->getRow($sql);

			return $this->gateway_info;
		}
		
		return null;
	}
	
	/**
	* the method checks if the query is ready
	* 
	* @return boolean
	*/
	public function isPrepare($post = true)
	{
		if ($post) {
			if ($this->payment_data && ($_POST['form'] == 'checkout' || $_POST['step'] == 'checkout')) {
				return true;
			}
		} else {
			if ($this->payment_data) {
				return true;
			}	
		}
		return false;
	}
	
	/**
	* build item data
	* 
	* @return data
	*/
	public function buildItemData($include_urls = true)
	{
		if ($this->isPrepare(false)) {
			$crypted_price = crypt(sprintf("%.2f", $this->getOption('total')), $GLOBALS['config']['paypal_secret_word']);
            $params = '';
			if ($this->getOption('params')) {
				$params = $this->getOption('params');

				if (is_array($params)) {
					$params = implode(',', $params);
				}
			}
			$data = $this->getOption('plan_id') .'|' . 
					$this->getOption('item_id') . '|' . 
					$this->getOption('account_id') . '|' . 
					$crypted_price . '|' . 
					$this->getOption('callback_class') . '|' . 
					$this->getOption('callback_method') . '|' . 
					($include_urls ? ($this->getOption('cancel_url') ? $this->getOption('cancel_url') : $this->getDefaultFailURL()) : '') . '|' . 
					($include_urls ? ($this->getOption('success_url') ? $this->getOption('success_url') : $this->getDefaultSuccessURL()) : '') . '|' . 
					RL_LANG_CODE . '|' .
					$this->getOption('plugin') . '|' . 
					$this->getTransactionID() . '|' .
					($this->isRecurring() ? $this->getOption('subscription_id') : $this->isRecurring()) . '|' .
					$params;

			$data = base64_encode($data);
			$this->setOption('item_details', $data);

			return $data;
		}
		
		return false;
	}
	
	/**
	* get callback URL (payment notification URL)
	* 
	* @return string
	*/
	public function getNotifyURL()
	{
		return $this->notify_url;
	}
	
	/**
	* set callback URL
	* 
	* @param mixed $url
	*/
	public function setNotifyURL($url)
	{
		$this->notify_url = $url;
	}
	
	/**
	* get default fail URL
	* 
	* @return String
	*/
	public function getDefaultFailURL()
	{
		$fail_url =SEO_BASE;
		$file_url .= $GLOBALS['config']['mod_rewrite'] ? $GLOBALS['pages']['payment'] .'/'. self::FAIL_URL .'.html' : '?page='. $GLOBALS['pages']['pre_payment'] . '&rlVareables=' . self::FAIL_URL;
		
		return $fail_url;
	}
	
	/**
	* get default success URL
	* 
	* @return String
	*/
	public function getDefaultSuccessURL()
	{
		$success_url = SEO_BASE;
		$success_url .= $GLOBALS['config']['mod_rewrite'] ? $GLOBALS['pages']['payment'] . '/' . self::SUCCESS_URL . '.html' : '?page=' . $GLOBALS['pages']['pre_payment'] . '&rlVareables=' . self::SUCCESS_URL;
		
		return $success_url;
	}

	/**
	* get payment gateways
	* 
	* @param array $aParams
	*/
	public function gateways($aParams = array())
	{
		$sql = "SELECT * FROM `" . RL_DBPREFIX . "payment_gateways` ";
		$sql .= "WHERE `Status` = 'active' ";

		if ($aParams['recurring'] || $GLOBALS['rlPayment']->isRecurring()) {
			$sql .= "AND `Recurring` = '1' ";
		}

		$GLOBALS['rlHook']->load('phpGetPaymentGatewaysWhere', $sql);

		$sql .= "ORDER BY `Position` ASC";
		$gateways = $GLOBALS['rlDb']->getAll($sql);
		$content = '';

		$GLOBALS['rlHook']->load('phpGetPaymentGateways', $gateways);

		$pre_payment_url = SEO_BASE;
		$pre_payment_url .= $GLOBALS['config']['mod_rewrite'] ? $GLOBALS['pages']['payment'] . '/' . self::CHECKOUT_URL . '.html' : '?page='. $GLOBALS['pages']['payment'] . '&rlVareables=' . self::CHECKOUT_URL;

		if ($GLOBALS['rlPayment']->isRedirect() && $gateways) {
			$content .= '<form id="form-checkout" method="post" action="'.$pre_payment_url.'">';
		}
		if ($gateways) { 	
			$gateways = $GLOBALS['rlLang']->replaceLangKeys($gateways, 'payment_gateways', array('name'));
			$GLOBALS['rlSmarty']->assign('name', $GLOBALS['lang']['payment_gateways']);

			$content .= $GLOBALS['rlSmarty'] -> fetch('blocks' . RL_DS . 'fieldset_header.tpl', null, null, false);
			$content .= '<ul id="payment_gateways">';
			foreach ($gateways as $key => $gateway) {
				$GLOBALS['rlHook']->load('phpGetPaymentGatewaysItem', $gateway, $content);
				if (!isset($gateway['ready'])) {
					$checked = $_POST['gateway'] == $gateway['Key'] || (!$_POST['gateway'] && $gateway['Default']) ? 'checked="checked"' : '';
					$content .= '<li'.($checked ? ' class="active"' : '').'>';

					if ($gateway['Plugin']) {
						$content .= '<img alt="'.$gateway['name'].'" title="'.$gateway['name'].'" src="'.RL_PLUGINS_URL.$gateway['Key'].'/static/'.$gateway['Key'].'.png" />';
						$content .= '<p><input '.$checked.' type="radio" name="gateway" value="'.$gateway['Key'].'" /></p>';
					} else {
						$content .= '<img alt="'.$gateway['name'].'" title="'.$gateway['name'].'" src="'.RL_LIBS_URL.'payment/'.$gateway['Key'].'/'.$gateway['Key'].'.png" />';
						$content .= '<p><input '.$checked.' type="radio" name="gateway" value="'.$gateway['Key'].'" /></p>';
					}
				}
				$content .= '</li>';
				$checked = '';
			}

			$content .= '</ul>';
			$content .= $GLOBALS['rlSmarty']->fetch('blocks' . RL_DS . 'fieldset_footer.tpl', null, null, false);

			$content .= '<script type="text/javascript">flynax.paymentGateway();</script>';
		} else {
			$content .= '<div class="text-notice">'.$GLOBALS['lang']['no_payment_gateways'].'</div>';
		}
		$GLOBALS['rlHook']->load('phpGetPaymentGatewaysAfter', $content);

		if ($GLOBALS['rlPayment']->isForm()) {
			$content .= $GLOBALS['rlSmarty']->fetch($GLOBALS['rlPayment']->getForm(), null, null, false);
		}

		if ($GLOBALS['rlPayment']->isRedirect() && $gateways) {
			$content .= '<div class="form-buttons no-top-padding">';
			$content .= '<input id="btn-checkout" type="submit" value="'.$GLOBALS['lang']['checkout'].'" />';
			if ($GLOBALS['rlPayment']->isForm() && $GLOBALS['rlPayment']->getGateway()) {
				$content .= '<a class="close red margin" href="'.$GLOBALS['rlPayment']->getReferer().'">'.$GLOBALS['lang']['cancel'].'</a>';	
			}
			$content .= '</div>';
			$content .= '</form>';
		}

		return $content;
	}
	
	/**
	* generate transaction ID
	* 
	* @param mixed $txn_tpl
	* @return string
	*/
	public function generateTransactionID($txn_tpl = 'FLTXN-********')
	{
		$txn_length = substr_count($txn_tpl, '*');

		$number = $this->getLastNumberTransaction();
		$number++;
		$number_length = strlen($number);
		$txn_length = $txn_length - $number_length;
		
		if ($txn_length > 0) {
			$txn_stars = str_repeat('0', $txn_length);
		}

		$mask = str_replace("*", "", $txn_tpl);
		$txn = $mask.$txn_stars.$number;

		return $txn;
	}
	
	/**
	* get last number transaction
	* 
	*/
	protected function getLastNumberTransaction()
	{
		$sql = "SELECT `Txn_ID` FROM `".RL_DBPREFIX."transactions` ORDER BY `Date` DESC LIMIT 1";
		$transaction = $this->getRow($sql);
		$number = 0;
		
		if ($transaction) {
			$number = explode("-", $transaction['Txn_ID']);
			$number = preg_replace('/\D/', '', $number[1]);
			$number = (int)$number;
		}
		
		return $number;
	}

	/**
	* check if define transaction ID
	* 
	* @param string $transaction_id
	* @return bool
	*/
	public function isTransactionExists($transaction_id = false)
	{
		if (!$transaction_id) {
			return false;
		}

		$transaction_id_db = $this -> getOne( "Txn_ID", "`Txn_ID` = '{$transaction_id}'", 'transactions');
		
		if ($transaction_id == $transaction_id_db) {
			return true;
		}
		
		return false;
	}
	
	/**
	* get transaction details
	* 
	* @param mixed $transaction_id
	* @return data
	*/
	public function getTransaction($transaction_id = false)
	{
		$transaction_id = $transaction_id ? $transaction_id : $this->getTransactionID();

		if ($transaction_id) {
			$sql = "SELECT * FROM `".RL_DBPREFIX."transactions` WHERE `ID` = '".$transaction_id."' LIMIT 1";
			$transaction_info = $this->getRow($sql);

			if ($transaction_info) {
				return $transaction_info;
			}
		}
		
		return false;
	}
	
	/**
	* set redirect to gateways page
	* 
	* @param bool $mod
	*/
	public function setRedirect($mod = true)
	{
		$this->gateways_page = $_SESSION['complete_payment']['redirect'] = (bool)$mod;
	}
	
	/**
	* check redirect status
	* 
	* @return bool
	*/
	public function isRedirect()
	{
		return $this->gateways_page;		
	}
	
	/**
	* send payment notification email
	* 
	* @param string $transaction_id 
	* 
	*/
	public function sendNotificationAfterPayment($transaction_id = false)
	{
		if (!$transaction_id) {
			return;
		}
        $this->loadClass('Mail');
		$transaction_info = $this->getTransaction($transaction_id);

		if ($transaction_info) {
			// total
			$total = $GLOBALS['config']['system_currency_position'] == 'before' ? $GLOBALS['config']['system_currency'] . $transaction_info['Total'] : $transaction_info['Total'] . ' ' . $GLOBALS['config']['system_currency'];

			// send user notification
			$account_info = $this->fetch(array('Username', 'First_name', 'Last_name', 'Mail'), array('ID' => $transaction_info['Account_ID']), null, 1, 'accounts', 'row');
			$account_name = $account_info['First_name'] || $account_info['Last_name'] ? $account_info['First_name'] .' '. $account_info['Last_name'] : $account_info['Username'];
			
			$search = array('{name}', '{gateway}', '{txn}', '{item}', '{price}', '{date}');
			$replace = array($account_name, $GLOBALS['lang']['payment_gateways+name+' . $transaction_info['Gateway']], $transaction_info['Txn_ID'], $transaction_info['Item_name'], $total, date(str_replace(array('b', '%'), array('M', ''), RL_DATE_FORMAT)));
			
			$mail_tpl = $GLOBALS['rlMail']->getEmailTemplate('payment_accepted');
			
			$mail_tpl['body'] = str_replace($search, $replace, $mail_tpl['body']);
			$GLOBALS['rlMail']->send($mail_tpl, $account_info['Mail']);
			
			// send admin notification
			$mail_tpl = $GLOBALS['rlMail']->getEmailTemplate('admin_listing_paid');
			$search = array('{id}', '{name}', '{gateway}', '{txn}', '{item}', '{price}', '{date}');
			$replace = array(
                $transaction_info['Item_ID'], 
                $account_name, 
                $GLOBALS['lang']['payment_gateways+name+' . $transaction_info['Gateway']], 
                $transaction_info['Txn_ID'], 
                $transaction_info['Item_name'], 
                $total, 
                date(str_replace(array('b', '%'), array('M', ''), RL_DATE_FORMAT))
            );

			$mail_tpl['body'] = str_replace( $search, $replace, $mail_tpl['body'] );
			$GLOBALS['rlMail']->send($mail_tpl, $GLOBALS['config']['notifications_email']);
		}
		
		unset($transaction_info, $mail_tpl);
	}

	/**
	* complete payment process; update transaction
	* 
	* @param mixed $data - array
	* @param mixed $callback_class
	* @param mixed $callback_method
	* @param mixed $plugin
	*/
	public function complete($data = false, $callback_class, $callback_method, $plugin = false)
	{
		if (!$callback_class && !$callback_method) {
			return;
		}

		try {
			// check if not exists additional options
			if (!isset($data['params'])) {
				$data['params'] = null;
			}
			$this->loadClass(str_replace('rl', '', $callback_class), null, $plugin);
			$GLOBALS[$callback_class]->{$callback_method}((int)$data['item_id'], (int)$data['plan_id'], (int)$data['account_id'], $data['params']);

			$GLOBALS['rlHook']->load('postPaymentComplete', $data);

			$this->updateTransaction($data['txn_id'], $data['txn_gateway'], 'paid', $data['total']);
			$this->sendNotificationAfterPayment($data['txn_id']);
		} catch (Exception $e) {
			$GLOBALS['rlDebug']->logger(get_class($e)." thrown within the exception handler. Message: ".$e->getMessage()." on line ".$e->getLine());
		}
	}
	
	/**
	* set bread crumb option
	* 
	* @param array $item
	*/
	public function setBreadCrumbs($item)
	{
		$exists = false;
		foreach($this->bread_crumbs as $bcKey => $bcValue) {
			if ($item['path'] == $bcValue['path']) {
				$exists = true;
				break;
			}
		}
		if(is_array($item) && !$exists) {
			$this->bread_crumbs[] = $_SESSION['payment_service_breadcumbs'][] = $item;
		}
	}
	
	/**
	* get bread crumbs option
	* 
	* @return array
	*/
	public function getBreadCrumbs()
	{
		return $this->bread_crumbs;
	}
	
	/**
	* enable recurring mod 
	* 
	* @param boolean $status
	*/
	public function enableRecurring()
	{
		$this->recurring = $_SESSION['complete_payment']['recurring'] = true;
	}

	/**
	* disable recurring mod 
	* 
	* @param boolean $status
	*/
	public function disableRecurring()
	{
		unset($_SESSION['complete_payment']['recurring']);
		$this->recurring = false;
	}
	
	/**
	* check if set up recurring mod
	* 
	* @return boolean
	*/
	public function isRecurring()
	{
		return $this->recurring;
	}
	
	/**
	* get all payment gateways
	* 
	* @return array
	* 
	*/
	public function getGatewaysAll()
	{
		if (!$this->gateways) {
			$sql = "SELECT * FROM `" . RL_DBPREFIX . "payment_gateways` WHERE `Status` = 'active'";
			$gateways = $this->getAll($sql);
			
			if($gateways) {
				foreach($gateways as $gKey => $gValue) {
					$this->gateways[$gValue['Key']] = $gValue;
				}
			}
		}

		return $this->gateways;
	}
	
	/**
	* whether there payment gateways with activated recurring option
	* @return boolean
	* 
	*/
	public function hasRecurringGateways()
	{
		$response = false;

		foreach($this->gateways as $gKey => $gValue) {
			if ($gValue['Recurring']) {
				$response = true;
				break;
			}
		}
		
		return $response;
	}

	/**
	* run payment process 
	* 
	* @param array $errors
	* @param boolean $exit
	*/
	public function checkout(&$errors, $exit = false)
	{
		$this->loadClass('PaymentFactory');

		if ($_POST['gateway'] || $this->getGateway()) {
			
			$GLOBALS['rlHook']->load('preCheckoutPayment');
			
			$gateway = $_POST['gateway'] ? $_POST['gateway'] : $this->getGateway();

			if ($_POST['gateway'] || !$this->getGateway()) {
				$this->setGateway($gateway);
			}
			$gateway_info = $this->getGatewayDetails();
			$rlGateway = $GLOBALS['rlPaymentFactory']->create($gateway, $gateway_info['Plugin']);

			if (method_exists($rlGateway, 'isConfigured')) {
				if (!$rlGateway->isConfigured()) {
					$errors[] = str_replace('{gateway}', $gateway_info['name'], $GLOBALS['lang']['gateway_not_configured']);	
				}
			}
			if (!$errors) {
				$rlGateway->call();
				if (method_exists($rlGateway, 'getErrors')) {
                    if ($rlGateway->getErrors()) {
					    $errors = array_merge((array)$errors, (array)$rlGateway->getErrors());
                    }
					return;
				}				
				if ($exit) {
					exit;
				}
			}
		} else {
			if ($_POST && !$_POST['gateway'] && !$this->getGateway())	{
				$errors[] = $GLOBALS['lang']['notice_payment_gateway_does_not_chose'];
			}
		}
	} 
	
	/**
	* check if display form
	* 
	*/
	public function isForm()
	{
		return $this->is_form;	
	}
	
	/**
	* enable credit card and  billing details form
	* 
	*/
	public function enableForm()
	{
		$this->is_form = true;
	}
	
	/**
	* disable credit card and  billing details form
	* 
	*/
	public function disableForm()
	{
		$this->is_form = false;
	}
	
	/**
	* reset payment gateways
	* 
	*/
	public function reset()
	{
		$this->setGateway(null);
		$this->disableForm();
		// unset braed crumbs item
		foreach($this->bread_crumbs as $bcKey => $bcValue) {
			if ($bcValue['path'] == $GLOBALS['pages']['payment'] . '/' . self::CHECKOUT_URL) {
				unset($this->bread_crumbs[$bcKey], $_SESSION['payment_service_breadcumbs'][$bcKey]);
			}
		}
	}
	
	/**
	* set http referer
	* 
	* @param mixed $referer
	*/
	public function setReferer($referer = false)
	{
		$this->referer = $_SESSION['complete_payment']['referer'] = $referer;	
	}
	
	/**
	* get http referer
	* 
	*/
	public function getReferer()
	{
		return $this->referer;
	}
	
	/**
	* set payment form
	* 
	* @param string $name (tpl file)
	*/
	public function setForm($name)
	{
		$this->form = $name;
	}
	
	/**
	* get payment form (name tpl file)
	* 
	* @return string
	*/
	public function getForm()
	{
		return $this->form;
	}
}