<?php

/**
* @version 2.7.14
* @package Joomla 1.7/2.5
* @subpackage DT Register
* @copyright Copyright (C) 2006 DTH Development
* @copyright contact dthdev@dthdevelopment.com
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
*/

defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed.' );

require_once( JPATH_SITE.'/components/com_dtregister/lib/class.payment.php');

class payfast extends Payment{

   var $last_error;                 // holds the last error encountered

   var $ipn_log;                    // bool: log IPN results to text file?

   var $ipn_log_file;               // filename of the IPN log

   var $ipn_response;               // holds the IPN response from payfast

   var $ipn_data = array();         // array contains the POST values for IPN

   var $fields = array();           // array holds the fields to submit to payfast

   var $bywebservice = false;

   function __construct() {

      // initialization constructor.  Called when class is created.

      parent::__construct();
         
      global $payfast_account_name,$payfast_username,$payfast_merchant_id,$payfast_merchant_key;
      $this->payfast_url = ($this->paymentmode=='test')?'https://sandbox.payfast.co.za/eng/process':'https://www.payfast.co.za/eng/process';
      
      $this->payfast_host = ($this->paymentmode=='test')?'sandbox.payfast.co.za':'www.payfast.co.za';

      $this->last_error = '';

      $this->ipn_log_file = 'ipn_log.txt';

      $this->ipn_log_file = dirname(__FILE__)."/ipnlog.txt";
	  //pr($this->ipn_log_file);

      $this->ipn_log = true;

      $this->ipn_response = '';  

      $this->add_field('merchant_id',$payfast_merchant_id );           // Return method = POST

      $this->add_field('merchant_key',$payfast_merchant_key);

   }

   function add_field($field, $value) {

      $this->fields["$field"] = $value;

   }

   function process(){

	   global $currency_code,$Itemid;

	   $mosConfig_live_site = JURI::root( false );

	   if($currency_code==""){$currency_code='USD';}

	   $session_id = $this->saveSession();

	   $this->add_field('return_url', "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=restore");

	   $this->add_field('cancel_url', "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=cancel");

	   $this->add_field('notify_url', "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=notification");
	   
	   $this->add_field('item_name',$this->description);

	    if($this->paymentmode=='test'){

		   $this->add_field('test_ipn', 1);

	    }
        $this->add_field('m_payment_id', $session_id);
	  if(isset($this->firstname) && $this->firstname !="" ){
	  	$this->add_field('name_first', $this->firstname);
	  }
	  
	   if(isset($this->lastname) && $this->lastname !="" ){
	  	$this->add_field('name_last', $this->lastname);
	  }
	  
	   if(isset($this->email) && $this->email !="" ){
	  	 $this->add_field('email_address', $this->email);
	  }
	  	
	   $this->add_field('amount', $this->cart->getAmount());

	   $this->add_field('currency_code', "$currency_code");

	   $this->submit_payfast_post();

   }

   function submit_payfast_post() {

      echo "<center><h3>".JText::_( 'DT_PAYFAST_REDIRECT_MSG')."</h3></center>\n";

      echo "<form method=\"post\" name=\"formRegister\" action=\"".$this->payfast_url."\">\n";

      foreach ($this->fields as $name => $value) {

         echo "<input type=\"hidden\" name=\"$name\" value=\"$value\">";

      }

?>

		<script language="javascript">

			function rg_direc_to_payfast(){

				document.formRegister.submit();

			}

			setTimeout("rg_direc_to_payfast()",5000);

		</script>

<?php

      echo "</form>\n";

   }

   function validate_ip() {
      $validHosts = array(
        'www.payfast.co.za',
        'sandbox.payfast.co.za',
        'w1w.payfast.co.za',
        'w2w.payfast.co.za',
        );
 
        $validIps = array();
 
        foreach( $validHosts as $pfHostname )
        {
            $ips = gethostbynamel( $pfHostname );

            if( $ips !== false )
                $validIps = array_merge( $validIps, $ips );
        }
 
    // Remove duplicates
        $validIps = array_unique( $validIps );
 
        if( !in_array( $_SERVER['REMOTE_ADDR'], $validIps ) )    {
            return false;
        } else {
           return true;
        }
   }
   
   function validate_ipn() {
      
      if(!$this->validate_ip()){
          return false;
      }
      $url_parsed=parse_url($this->payfast_url);

      $post_string = '';

      foreach ($_POST as $field=>$value) {

         $this->ipn_data["$field"] = $value;
         if( $field != 'signature' && $field != 'controller' )
         $post_string .= $field.'='.urlencode($value).'&';

      }

      //$post_string.="cmd=_notify-validate"; // append ipn command

      $fp = fsockopen("ssl://".$this->payfast_host,"443",$err_num,$err_str,30);

      if(!$fp) {

         // could not open the connection.  If loggin is on, the error message

         // will be in the log.

         $this->last_error = "fsockopen error no. $errnum: $errstr";

         $this->log_ipn_results(false);

         return false;

      } else {

         // Post the data back to payfast

         fputs($fp, "POST /eng/query/validate HTTP/1.1\r\n");

         fputs($fp, "Host: ".$this->payfast_host."\r\n");

         fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");

         fputs($fp, "Content-length: ".strlen($post_string)."\r\n");

         fputs($fp, "Connection: close\r\n\r\n");

         fputs($fp, $post_string . "\r\n\r\n");

         // loop through the response from the server and append to variable
         $res = '';
         $headerDone = false;
         while(!feof($fp)) {

            //$this->ipn_response .= fgets($fp, 1024);
            $line = fgets( $fp, 1024 );
 
            // Check if we are finished reading the header yet
            if( strcmp( $line, "\r\n" ) == 0 )
            {
                // read the header
                $headerDone = true;
            }
            // If header has been processed
            else if( $headerDone )
            {
                // Read the main response
                $this->ipn_response .= $line;
            }

         }

         fclose($fp); // close connection

      }
      
       $lines = explode( "\n", $this->ipn_response);
    
     if( strcmp( $result, 'VALID' ) == 0 ) {

         // Valid IPN transaction.

         $this->log_ipn_results(true);

       return true;

      } else {

         // Invalid IPN transaction.  Check the log for details.

         $this->last_error = 'IPN Validation Failed.';

         $this->log_ipn_results(false);

         return true;

      }

   }

   function log_ipn_results($success) {
      return;
      // if (!$this->ipn_log) return;  // is logging turned off?

      // Timestamp

      $text = '['.date('m/d/Y g:i A').'] - ';

      // Success or failure being logged?

      if ($success) $text .= "SUCCESS!\n";

      else $text .= 'FAIL: '.$this->last_error."\n";

      // Log the POST variables

      $text .= "IPN POST Vars from Payfast:\n";

      foreach ($this->ipn_data as $key=>$value) {

         $text .= "$key=$value, ";

      }

      // Log the response from the payfast server

      $text .= "\nIPN Response from Payfast Server:\n ".$this->ipn_response;

      // Write to log

      $fp=fopen($this->ipn_log_file,'a');

      fwrite($fp, $text . "\n\n");

      fclose($fp);  // close file

   }

   function dump_fields() {

      echo "<h3>payfast_class->dump_fields() Output:</h3>";

      echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">

            <tr>

               <td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>

               <td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>

            </tr>";

      ksort($this->fields);

      foreach ($this->fields as $key => $value) {

         echo "<tr><td>$key</td><td>".urldecode($value)."&nbsp;</td></tr>";

      }

      echo "</table><br>";

   }
   
   function notify(){
	   header( 'HTTP/1.0 200 OK' );
       flush();
	   
	   if($this->validate_ipn() && $_REQUEST['payment_status']=='COMPLETE'){
		   $this->transactionId = $_REQUEST['pf_payment_id'];
		   $process = DT_Session::get('Setting.process');
		   DT_Session::set($process.'.payment.transactionId',$this->transactionId);
		   		   
		   return true;
	   }else{
		   return false;
	   }
	      
   }

}