<?php

/**
 * 2CheckOut Class
 *
 * Integrate the 2CheckOut payment gateway in your site using this easy
 * to use library. Just see the example code to know how you should
 * proceed. Btw, this library does not support the recurring payment
 * system. If you need that, drop me a note and I will send to you.
 *
 * @package     Payment Gateway
 * @category    Library
 * @author      Md Emran Hasan <phpfour@gmail.com>
 * @link        http://www.phpfour.com
 */

include_once ('PaymentGateway.php');

class TwoCo extends PaymentGateway
{
    /**
     * Secret word to be used for IPN verification
     *
     * @var string
     */
    public $secret;

    /**
     * Initialize the 2CheckOut gateway
     *
     * @param none
     * @return void
     */
    public function __construct()
    {
        parent::__construct();

        // Some default values of the class
        $this->gatewayUrl = 'https://www.2checkout.com/checkout/purchase';
        $this->ipnLogFile = '2co.ipn_results.log';
    }

    /**
     * Enables the test mode
     *
     * @param none
     * @return none
     */
    public function enableTestMode($mode = TRUE)
    {
        $this->testMode = $mode;
        $this->addField('demo', 'Y');
    }

//    public function enableTestMode()
//    {
//        $this->testMode = TRUE;
//        $this->addField('demo', 'Y');
//    }

    /**
     * Set the secret word
     *
     * @param string the scret word
     * @return void
     */
    public function setSecret($word)
    {
        if (!empty($word))
        {
            $this->secret = $word;
        }
    }

    /**
     * Validate the IPN notification
     *
     * @param none
     * @return boolean
     */
    public function validateIpn()
    {
        foreach ($_POST as $field=>$value)
        {
            $this->ipnData["$field"] = $value;
        }

        $vendorNumber   = ($this->ipnData["vendor_number"] != '') ? $this->ipnData["vendor_number"] : $this->ipnData["sid"];
        $orderNumber    = $this->ipnData["order_number"];
        $orderTotal     = $this->ipnData["total"];

        // If demo mode, the order number must be forced to 1
        if($this->demo == "Y" || $this->ipnData['demo'] == 'Y')
        {
            $orderNumber = "1";
        }

        // Calculate md5 hash as 2co formula: md5(secret_word + vendor_number + order_number + total)
        $key = strtoupper(md5($this->secret . $vendorNumber . $orderNumber . $orderTotal));

        // verify if the key is accurate
        if($this->ipnData["key"] == $key || $this->ipnData["x_MD5_Hash"] == $key)
        {
            $this->logResults(true);
            return true;
        }
        else
        {
            $this->lastError = "Verification failed: MD5 does not match!";
            $this->logResults(false);
            return false;
        }
    }

    function convertInternalLink($body)
	{
		global $mainframe;
		$patterns = array();
		$replacements = array();
		$i = 0;
		$href_exp = "/href=\"(.*?)\"/";
		$link_exp = "[^http:\/\/www\.|^www\.|^http:\/\/|^skype:|^callto:|^callto:|^mailto:|^#|^https:\/\/]";
		preg_match_all($href_exp, $body, $out, PREG_SET_ORDER);
		foreach ($out as $val)
		{
			$links = preg_match($link_exp, $val[1], $match, PREG_OFFSET_CAPTURE);
			if(!$links)
			{
				$link_exp3 = "[^..\/]";
				$links3 = preg_match($link_exp3, $val[1], $match3, PREG_OFFSET_CAPTURE);
				if($links3)
				{
					/*$val[1] = str_replace('../', '', $val[1]);*/
					$patterns[$i] = 'href="'. $val[1] . '"';
					$replacements[$i] = 'href="'. JURI::root().$val[1] . '"';
					$body=str_replace($patterns[$i],$replacements[$i],$body);
					$i++;
				}
				else
				{
					$patterns[$i] = 'href="'. $val[1] . '"';
					$replacements[$i] = 'href="'. JURI::root().$val[1] . '"';
					$body=str_replace($patterns[$i],$replacements[$i],$body);
					$i++;
				}
			}
			$link_exp1 = "[^http:\/\/www\.|^www\.|^http:\/\/]";
			$links1 = preg_match($link_exp1, $val[1], $match1, PREG_OFFSET_CAPTURE);
			if($links1)
			{
				$link_exp2 = "[^www\.]";
				$links2 = preg_match($link_exp2, $val[1], $match2, PREG_OFFSET_CAPTURE);
				if($links2)
				{
				$patterns[$i] = 'href="'. $val[1] . '"';
				$replacements[$i] = "href=http://".$val[1];
				$body	= str_replace($patterns[$i],$replacements[$i],$body);
				$i++;
				}
			}
		}

		return $body;
	}

	function getImagetag( $message )
	{
		$img_tag_count 	= substr_count($message, '<img');
		$regex 			= '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';

		if($img_tag_count > 0) {
			preg_match_all ( $regex, $message, $matches1,PREG_SET_ORDER );

			foreach ($matches1 as $val) {
				$imageurl[] = $val[2];
			}

			$matches = array_unique($imageurl);

			foreach ($matches as $val) {
				$image 					= '';
				$img_path_check_http 	= '';
				$img_path_check_www 	= '';
				$image_new				= '';
				$image 					= trim ( $val );
				$img_path_check_http 	= substr_count($image, 'http');
				$img_path_check_www 	= substr_count($image, 'www');
				if($img_path_check_http == '0' && $img_path_check_www == '0') {
					$image_new 			= JURI::root().$image;
					$message 			= str_replace($image, $image_new, $message);
				}
			}
		}

		return $message;
	}

	function UTF8entities($content="")
	{
            $contents = TwoCo::unicode_string_to_array($content);
            $swap = "";
            $iCount = count($contents);
            for ($o=0;$o<$iCount;$o++) {
                $contents[$o] = TwoCo::unicode_entity_replace($contents[$o]);
                $swap .= $contents[$o];
            }
            return mb_convert_encoding($swap,"UTF-8"); //not really necessary, but why not.
    }

    function unicode_string_to_array( $string )
    {
            $strlen = mb_strlen($string);
            while ($strlen) {
                $array[] = mb_substr( $string, 0, 1, "UTF-8" );
                $string = mb_substr( $string, 1, $strlen, "UTF-8" );
                $strlen = mb_strlen( $string );
            }
            return $array;
    }
    function unicode_entity_replace($c)
    {
            $h = ord($c{0});
            if ($h <= 0x7F) {
                return $c;
            } else if ($h < 0xC2) {
                return $c;
            }

            if ($h <= 0xDF) {
                $h = ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            } else if ($h <= 0xEF) {
                $h = ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            } else if ($h <= 0xF4) {
                $h = ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12 | (ord($c{2}) & 0x3F) << 6 | (ord($c{3}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            }
     }
}