<?php namespace Listener;


use PaypalIPN;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require('logging.php');
require('licensing.php');
require('pricing.php');
require('paypal_ipn.php');
require('PHPMailer/Exception.php');
require('PHPMailer/PHPMailer.php');
require('PHPMailer/SMTP.php');


PaymentLogging($_POST["custom"] . ",notify,id:" . $_GET["id"]);


// Set this to true to exclusively use the sandbox endpoint during testing:
$enable_sandbox = false;
$test_text = "";
if ($_POST["test_ipn"] == 1)
{
    $test_text = "***Test*** ";
    $enable_sandbox = true;
}


// For validation of submitted values
$my_item_name = "Software Registration Test";
$my_currency = "AUD";
$my_quantity = $_POST["quantity"];
if (empty($my_quantity))
  $my_quantity = 1;
$my_unit_price = UnitPriceForQuantity($my_quantity, $enable_sandbox);
$my_price = $my_quantity *  $my_unit_price;

// All the email addresses that are attached to paypal that could be receiving payments:
$my_email_addresses = array(        "billing@subflexion.com",
                            "sandbox-billing@subflexion.com",
                                 "sb-billing@subflexion.com",
                                    "jryland@gmail.com");


// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);

//Server settings
$mail->SMTPDebug  = SMTP::DEBUG_SERVER;                     // Enable verbose debug output
$mail->Mailer     = 'smtp';                                 // Send using SMTP
// $mail->Host       = 'mail.subflexion.com';                  // Set the SMTP server to send through
$mail->Host       = 'smtp.dreamhost.com';                   // Set the SMTP server to send through
$mail->SMTPAuth   = true;                                   // Enable SMTP authentication
$mail->Username   = 'billing@subflexion.com';               // SMTP username
$mail->Password   = 'mfQHCsqq';                             // SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;         // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
$mail->Port       = 587; // 465; // 587;                                    // TCP port to connect to

// Addresses to use when sending email
$mail->setFrom('billing@subflexion.com',    'Billing');
$mail->addReplyTo('support@subflexion.com', 'Support');
$mail->addCC('accounts@subflexion.com',     'Accounts');


// Set this to true to send a confirmation email:
$send_confirmation_email = true;
// $confirmation_email_address = "Billing <billing@subflexion.com>";
$confirmation_email_address = "jryland@xiaofrog.com";
$from_email_address = "Billing <billing@subflexion.com>";
$copy_to_email = "Accounts <accounts@subflexion.com>";

// Set this to true to save a log file:
$save_log_file = true;
$website_svn = "/home/subflexion_public/WickedDocs/Website/";
$log_file_dir = $website_svn . "logs";
$licenses_dir = $website_svn . "licenses";



// Do verification check that the IPN was from PayPal
$ipn = new PaypalIPN();
$ipn->usePHPCerts();
if ($enable_sandbox)
{
  $ipn->useSandbox();
}
$verified = $ipn->verifyIPN();



// Check the receiver email to see if it matches your list of paypal email addresses
$receiver_email_found = false;
foreach ($my_email_addresses as $a) {
    if (strtolower($_POST["receiver_email"]) == strtolower($a)) {
        $receiver_email_found = true;
        break;
    }
}

// Combine the post data together in one string
$data_text = "";
foreach ($_POST as $key => $value) {
    $data_text .= $key . " = " . $value . "\r\n";
}
$data_text .= "my_item_name = " . $my_item_name . "\r\n";
$data_text .= "my_currency = " . $my_currency . "\r\n";
$data_text .= "my_quantity = " . $my_quantity . "\r\n";
$data_text .= "my_unit_price = " . $my_unit_price . "\r\n";
$data_text .= "my_price = " . $my_price . "\r\n";



date_default_timezone_set("Australia/Brisbane");
list($year, $month, $day, $hour, $minute, $second, $timezone) = explode(":", date("Y:m:d:H:i:s:T"));
$date = $year . "-" . $month . "-" . $day;
$timestamp = $date . " " . $hour . ":" . $minute . ":" . $second . " " . $timezone;
$dated_log_file_dir = $log_file_dir . "/" . $year . "/" . $month;


$success = false;
$paypal_ipn_status = "PAYPAL VERIFICATION FAILED";
if ($verified) {
    $paypal_ipn_status = "RECEIVER EMAIL MISMATCH";
    if ($receiver_email_found) {

        // Process IPN
        // A list of variables are available here:
        // https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/
      
        // Here is some information on how to configure sendmail:
        // http://php.net/manual/en/function.mail.php#118210

        $paypal_ipn_status = "TRANSACTION DETAILS MISMATCH";
        if ( $_POST["item_name"]      == $my_item_name &&
             $_POST["mc_gross"]       == $my_price     &&
             $_POST["mc_currency"]    == $my_currency  &&
             $_POST["payment_status"] == "Completed"   )
        {
            // This is an example for sending an automated email to the customer when they purchases an item for a specific amount:
            $paypal_ipn_status = "Completed Successfully";
            $success = true;

            // Generate a license
            $license_data = make_license_from_ipn($website_svn . 'private-key.pem');

            // Save the generated license
            $license_file = $licenses_dir . "/1.0.0/" . $_POST["txn_id"] . ".lic";
            file_put_contents($license_file, $license_data, FILE_APPEND);

            $email_to = $_POST["first_name"] . " " . $_POST["last_name"] . " <" . $_POST["payer_email"] . ">";

            $email_subject = $test_text . "Completed order for: " . $_POST["item_name"];

            // email body content
            $htmlContent = "<h1>Product Registered</h1>
               <h2>Thank you for registering " . $_POST["item_name"] . '.</h2><p>
               Your <b>license</b> is attached.<p>
               To install it, download the attachement and copy it to
                 <pre>$HOME/.config/WickedDocs/license.txt</pre>
               More details on installing the license can be found in the <a href="https://www.subflexion.com/WickedDocs/documentation.html">online documentation</a>.<p>
               The <a href="https://www.subflexion.com/WickedDocs/faq.html">FAQ</a> may also cover some other common issues.<p>
               If you still have any problems, feel free to entered them in to the <a href="https://www.subflexion.com/WickedDocs/support.html">Support Page</a>
               or email "Support &lt;support@subflexion.com&gt;".<p>
               Thank you<p>
               Subflexion Support<p>';


            // TODO: replace this email sending code with using PHPMailer
            try
            {
              $mail->addAddress($_POST["payer_email"], $_POST["first_name"] . " " . $_POST["last_name"]);  // Add recipient
              $mail->addAttachment($license_file, 'license.txt');                                          // Add attachment
              $mail->isHTML(true);                                                                         // Set email format to HTML
              $mail->Subject = 'PHPMail - ' . $email_subject;
              $mail->Body    = $htmlContent;
              $mail->AltBody = ''; // This is the body in plain text for non-HTML mail clients
              $mail->send();
              $paypal_ipn_status .= " - Email sent";
            }
            catch (Exception $e)
            {
              $paypal_ipn_status .= " - Email error - " . $mail->ErrorInfo;
            }


            // header for sender info
            $headers = "Cc: " . $copy_to_email . "\r\n" .
                       "From: " . $from_email_address . "\r\n";

            // boundary 
            $semi_rand = md5(time()); 
            $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 
            
            // headers for attachment 
            $headers .= "MIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; 
            
            // multipart boundary 
            $email_body = "--{$mime_boundary}\n" .
                          "Content-Type: text/html; charset=\"UTF-8\"\n" .
                          "Content-Transfer-Encoding: 7bit\n\n" .
                          $htmlContent .
                          "\n\n" .
                          "--{$mime_boundary}\n" .
                          "Content-Type: application/octet-stream; name=\"license.txt\"\n" . 
                          "Content-Description: license.txt\n" .
                          "Content-Disposition: attachment;\n" . " filename=\"license.txt\"; size=".strlen($license_data).";\n" . 
                          "Content-Transfer-Encoding: base64\n\n" .
                          chunk_split(base64_encode($license_data)) .
                          "\n\n" .
                          "--{$mime_boundary}\n";

            // send email
            @mail($email_to, $email_subject, $email_body, $headers);
        }
    }
}
elseif ($enable_sandbox && $_POST["test_ipn"] != 1)
{
  $paypal_ipn_status = "VERIFICATION FAILED - RECEIVED FROM LIVE WHILE SANDBOXED\n";
}
elseif (!$enable_sandbox && $_POST["test_ipn"] == 1)
{
  $paypal_ipn_status = "VERIFICATION FAILED - RECEIVED FROM SANDBOX WHILE LIVE\n";
}




// TODO: refactor in to re-usable function
// params:
//         bool    save_log_file       (in-out)
//         string  log_file_dir        (in)
//         string  dated_log_file_dir  (in)
if ($save_log_file)
{
    // Create log file directory
    if (!is_dir($dated_log_file_dir)) {
        if (!file_exists($dated_log_file_dir)) {
            mkdir($dated_log_file_dir, 0777, true);
            if (!is_dir($dated_log_file_dir)) {
                $save_log_file = false;
            }
        } else {
            $save_log_file = false;
        }
    }
    // Restrict web access to files in the log file directory
    $htaccess_body = "RewriteEngine On" . "\r\n" . "RewriteRule .* - [L,R=404]";
    if ($save_log_file && (!is_file($log_file_dir . "/.htaccess") || file_get_contents($log_file_dir . "/.htaccess") !== $htaccess_body)) {
        if (!is_dir($log_file_dir . "/.htaccess")) {
            file_put_contents($log_file_dir . "/.htaccess", $htaccess_body);
            if (!is_file($log_file_dir . "/.htaccess") || file_get_contents($log_file_dir . "/.htaccess") !== $htaccess_body) {
                $save_log_file = false;
            }
        } else {
            $save_log_file = false;
        }
    }
}




// What to save in log file and email to confirmation address
$contents = "paypal_ipn_status = " . $paypal_ipn_status . "\r\n" . "paypal_ipn_date = " . $timestamp . "\r\n" . $data_text . "\r\n";

if ($save_log_file)
{
  // Save data to text file
  $filename = $dated_log_file_dir . "/" . $test_text . "paypal_ipn_" . $date . ".txt";
  file_put_contents($filename, $contents, FILE_APPEND);
}

if ($send_confirmation_email || !$success)
{
  // Send confirmation email
  $subject = $test_text . "PayPal IPN : " . $paypal_ipn_status;
  $headers = "From: " . $from_email_address;

  // TODO: Use PHPMailer instead
  mail($confirmation_email_address, $subject, $contents, $headers);
}

PaymentLogging($_POST["custom"] . ",notify_status," . $paypal_ipn_status);

// Reply with an empty 200 response to indicate to paypal the IPN was received correctly
header("HTTP/1.1 200 OK");

?>

