<?php
/**
 * Класс оплаты заказов Минимагазина через IntellectMoney
 * @author chayn1k [3DaVinci]
 */

class dv_imoney {

	protected $db, $UI_CONFIG;
	protected $MODULE_FOLDER, $MODULE_PATH, $ADMIN_TEMPLATE;
	protected $settings;
	protected $TMPL;

	protected $orderId = null; 			// номер платежа (до 150 символов)


	public function __construct() {
		$nc_core = nc_Core::get_object();

		// global variables to internal
		$this->db = &$nc_core->db;
		$this->MODULE_FOLDER = $nc_core->MODULE_FOLDER;
		$this->MODULE_PATH = str_replace($nc_core->DOCUMENT_ROOT, "", $nc_core->MODULE_FOLDER)."3dvimoney/";
		$this->TMPL = new dv_imoney_templates($this->MODULE_PATH);

		// Приводим параметры в удобоваримую форму
		$this->settings = $nc_core->get_settings('','3dvimoney');
		$this->settings['currency'] = $this->settings['currency'] ? 'TST' : 'RUR';
		if ($this->settings['preference'])
			$this->settings['preference'] = unserialize($this->settings['preference']);
		if ($this->settings['dv_status'])
			$this->settings['dv_status'] = unserialize($this->settings['dv_status']);
		if (empty($this->settings['success_url']))
			$this->settings['success_url'] = 'http://'.$nc_core->HTTP_HOST;
		if (empty($this->settings['fail_url']))
			$this->settings['fail_url']	= 'http://'.$nc_core->HTTP_HOST;

	}

	public function __get($name) {
		if ($name == 'settings' ) {
			return $this->settings;
		}
		if ($name == 'TMPL' ) {
			return $this->TMPL;
		}
	}

	static public function get_object () {
		return new self;
	}


	/**
	 * Функция возвращает html-код формы для оплаты заказа
	 * @param int цена товара
	 * @param string "button" | "form"
	 * @return string html
	 */
	public function show_pay_button($orderId, $view = 'button') {
		if ($orderId === null){
			return false;
		}
		$orderId = intval($orderId);
		$this->orderId = $orderId;
		$eshopId = $this->settings['shop_id'];
		$recipientCurrency = $this->settings['currency'];
		$successUrl = $this->settings['success_url'];
		$failUrl = $this->settings['fail_url'];

		if(!empty($this->settings['preference'])){
			$preference = implode(',', $this->settings['preference']);
		}

		$order = $this->get_order_info($this->orderId);
		if(!$order){
			return DV_IMONEY_ORDER_NOT_EXIST;
		}

		$serviceName = DV_IMONEY_PAYMENT_PREFIX_ORDER_NAME.$order['Message_ID'];
		$recipientAmount = $order['FinalCost'];
		$userName = $order['Name'];
		$userEmail = $order['Email'];

		$hash = $this->generate_sign( array(
			'eshopId' => $eshopId,
			'orderId' => $orderId,
			'serviceName' => $serviceName,
			'recipientAmount' => $recipientAmount,
			'recipientCurrency' => $recipientCurrency
		), nc_Core::get_object()->NC_CHARSET);

		$type = 'text';
		$template = $this->settings['pay_'.$view.'_alternate'] ?
			$this->settings['pay_'.$view.'_alternate'] :
			$this->TMPL->templates['pay_'.$view];

		eval("\$result = \"".$template."\";");
		return $result;
	}


	/**
	 * Устанавливает статус заказа.
	 * @param int ID заказа
	 * @param int ID статуса в сис. таблице MinishopStatus
	 * @return bool результат выполнения запроса
	 */
	public function set_order_status($orderId, $statusId){
		$sql = "UPDATE `Message".nc_minishop::get_object()->order_class_id()."`
			SET `Status` = '".intval($statusId)."'
			WHERE `Message_ID` = '".intval($orderId)."' ";
		return nc_Core::get_object()->db->query($sql);
	}

	/**
	 * Возвращает статус заказа в Минимагазине
	 * соответствующий статусу ответа от IntellectMoney
	 * @param int ID статуса IntellectMoney
	 * @return int ID статуса из таблицы MinishopStatus
	 */
	public function get_shop_status($statusId){
		return $this->settings['dv_status'][intval($statusId)];
	}

	/**
	 * Возвращает информацию по заказу
	 * @param int ID заказа
	 * @return array массив данных заказа
	 */
	public function get_order_info($orderId = null) {
		if ($orderId === null && $this->orderId !== null){
			$orderId = $this->orderId;
		}
		return nc_Core::get_object()->db->get_row(
			"SELECT *
			FROM `Message".nc_minishop::get_object()->order_class_id()."`
			WHERE `Message_ID` = '".intval($orderId)."' ", ARRAY_A );
	}


	/**
	 * Возвращает отфильтрованый массив данных
	 * ответа от сервера IntellectMoney
	 * @return array
	 */
	public function get_response_vars(){
		$params_key = array('eshopId', 'eshopAccount', 'orderId',  'serviceName', 'paymentStatus',
					'recipientAmount', 'recipientCurrency', 'hash', 'userName', 'userEmail',
					'paymentData', 'secretKey');

		foreach ( $params_key as $v ) {
			$params[$v] = nc_Core::get_object()->input->fetch_get_post($v);
		}
		return $params;
	}


	/**
	 * Обработчик результатов платежа
	 * @param int ID заказа
	 * @return int status ID or false;
	 */
	public function handler($orderId){
		$orderId = intval($orderId);
		$response = $this->get_response_vars();
		$order = $this->get_order_info();

		$eshopId = $this->settings['shop_id'];
		$recipientCurrency = $this->settings['currency'];

		//$this->log('settings_array', $this->settings);

		if ($response['hash'] != $this->generate_hash($response)){
			return false;
		}

		$statusId = $this->get_shop_status($response['paymentStatus']);
		if ( !empty($statusId) ) {
			$this->set_order_status($orderId, $statusId);
		}

		return $statusId;
	}

	/**
	 * Возвращает url для оплаты заказа
	 * @param array параметры которые будут передаваться в url
	 * @return string url
	 */
	public function get_pay_link ($params) {
		return $this->settings['handl_url']."?payment=".self::pay_link_encode($params);
	}

	/**
	 * Возвращает шаблон для письма с сылкой оплаты
	 * @param int ID заказа
	 * @param string url оплаты
	 * @return array шаблон письма
	 */
	public function get_mail ($orderId, $payUrl) {
		$order = $this->get_order_info($orderId);

		$macro = array(
			'SHOP_NAME' => $this->settings['shop_name'],
			'SITE_URL' => $_SERVER['HTTP_HOST'],
			'PAYMENT_URL' => $payUrl,
			'FINAL_COST' => $order['FinalCost'],
			'USER_NAME' => $order['Name'],
			'ORDER_NOTE' => $order['Note'],
			'ORDER_NUM' => $orderId
		);

		// шаблоны писем
		$subject = $this->settings['mail_subject'];
		$body = $this->settings['mail_body'];
		$ishtml = $this->settings['mail_ishtml'];

		// замена макропеременных
		foreach ( $macro as $k => $v ) {
			$subject = str_replace ('%'.$k, $v, $subject);
			$body = str_replace ('%'.$k, $v, $body);
		}

		return array('subject' => $subject, 'body' => $body, 'html' => $is_hrml );
	}



	/**
	 * Функция генерации цифровой подписи товара
	 * @param array массив с ключами
	 * @param string кодировка
	 * @return string хэш
	 */
	public function generate_sign($params, $charset = 'windows-1251') {
		$charset = mb_strtolower($charset);
		$hash_string = ''.
			$params['eshopId'].'::'.
			$params['orderId'].'::'.
			$params['serviceName'].'::'.
			$params['recipientAmount'].'::'.
			$params['recipientCurrency'].'::'.
			$this->settings['secret_key'];

		if ($charset != 'windows-1251' ){
			$hash_string = iconv ($charset, 'windows-1251//IGNORE', $hash_string);
		}
		return mb_strtolower(md5($hash_string));
	}

	/**
	 * Функция генерации хэша товара
	 * @param array массив с ключами
	 * @return string хэш
	 */
	public function generate_hash($params) {
		$hash_string = "".
				$params['eshopId']."::".
				$params['orderId']."::".
				$params['serviceName']."::".
				$params['eshopAccount']."::".
				$params['recipientAmount']."::".
				$params['recipientCurrency']."::".
				$params['paymentStatus']."::".
				$params['userName']."::".
				$params['userEmail']."::".
				$params['paymentData']."::".
				$this->settings['secret_key'];

		return mb_strtolower(md5($hash_string));
	}

	/**
	 * Кодирует параметры для ссылки оплаты
	 * @param array параметры ссылки для кодирования
	 * @return string строка параметр для ссылки на оплату.
	 */
	public static function pay_link_encode($params){
		return base64_encode(serialize($params));
	}

	/**
	 * Декодирует данные запроса из ссылки
	 * @param string строка запроса
	 * @return array массив данных
	 */
	public static function pay_link_decode($params){
		return unserialize(base64_decode($params));
	}



	public function log($desc, $val){
		$text .= "/**************************************************************\\\n";
		$text .= "$desc: ";
		if (is_array($val)) {
			$text .= print_r($val, true);
		} else {
			$text .= $val;
		}
		$text .= "\n";
		$text .= "\n/**************************************************************\\\n\n";

		$f = fopen($this->MODULE_PATH.'imoney.log','a+');
		fwrite($f,$text);
		fclose($f);
	}

	public function  __destruct() {
		//
	}

}




