<?php

// edi_automation_hub.php
// -----------------------------------------------------------------------------
// This scrit contains a set of functions demonstrating how to drive dmShop
// using EDI automation methodology, by running a sequence of dmShop commands.
// It returns XML output.
//
// Project    > dmClubNewYear08:C37
// Copyright  > (C) Digital Mail Limited (2005-2008)
// Author     > RAK for DML
// -----------------------------------------------------------------------------

define('MOD_PHP', substr(PHP_SAPI, 0, 3) != 'cgi'); // Are we running as mod_php?
define('DOCROOT', 
	MOD_PHP && isset($_SERVER['DOCUMENT_ROOT']) ? 
		$_SERVER['DOCUMENT_ROOT'] : 
			(MOD_PHP && isset($_SERVER['SCRIPT_FILENAME']) ? 
				substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])) : 
				substr(str_repeat('../', count(explode('/', preg_replace('_/+_', '/', $_SERVER['PHP_SELF'])))-2), 0, -1))
	);
include(DOCROOT . '/dmx/dmx_options.php');
include(DOCROOT . '/dmx/core/php/dmx_library.php');

// $req holds request parameters - POSTs override GETs
$req = count($_POST) ? $_POST : count($_GET) ? $_GET : array();

// Set debugging level from parameters, overriding value specified in dmx_options.php
$dmx_options['debug_level'] = isset($req['debug']) && strtolower($req['debug']) != 'off' ? 1 : 0;

// Retrieve action, session, and dealer ID from request, if present
$edi_action    = isset($req['edi_action'])  ? $req['edi_action']  : ''; // The EDI action to perfom
$dmx_session   = isset($req['dmx_session']) ? $req['dmx_session'] : ''; // The dmShop Trolley session to use
if (isset($req['dealer_id'])) $dmx_options['dealer_id'] = $req['dealer_id']; // If the request contains a dealer ID, override the ID specified in dmx_options.php

// Get  protocol server URLS
$dmx_protocol['servers']       = dmx_get_protocol_server_urls();
$dmx_protocol['current_index'] = dmx_get_protocol_server_index();

// -----------------------------------------------------------------------------

$response = array(); // Holds nodes of the result (before conversion to XML output)
$save     = array(); // Holds values saved for later use in $response

switch (strtolower($edi_action)) {
	// Handle the incoming EDI action
	
	// -----------------------------------------------------------------------------
	
	case 'autonumsignup':
		// Check and pre-process input
		if (isset($req['pin']) && $req['pin'] != '') {
			$test = check_array_keys($req, 'tariff,email');
		} else if (isset($req['dob']) && $req['dob'] || isset($req['mmn']) && $req['mmn']) {
		 	$test = check_array_keys($req, 'tariff,email,dob,mmn');
		} else {
			$test = check_array_keys($req, 'tariff,email');
			if ($test != 'PASS') $test .= ' AND EITHER pin OR dob, mmn';
		}
		If ($test != 'PASS') {
			$output['status']     = 'FAIL'; 
			$output['edi_action'] = $edi_action; 
			$output['reason']     = 'MISSING PARAMETERS: ' . $test;
			break;
		}
		$g = isset($req['goldval']) && strpos($req['goldval'], '-') ? explode('-', $req['goldval']) : array(0, 0);
		
		// COMMAND: CreateTrolley
		$params['DealerID']  = $dmx_options['dealer_id'];
		$output = talk_to_dmshop('CreateTrolley', $params);
		if ($output['status'] == 'FAIL') break;
		$dmx_session = $output['TrolleyID'];

		// COMMAND: ChooseNumber
		unset($params);
		$params['TariffSpec'] = $req['tariff']; 
		$params['GVFrom']     = $g[0];
		$params['GVTo']       = $g[1]; 
		$params['PageSize']   = 1; 
		$output = talk_to_dmshop('ChooseNumber', $params);
		if ($output['status'] == 'FAIL') break;
		
		if (!isset($output['Num']) || !$output['Num']) {
			// No numbers were returned, so fail
			unset($output);
			$output['status']     = 'FAIL'; 
			$output['edi_action'] = $edi_action; 
			$output['command']    = 'ChooseNumber'; 
			$output['reason']     = 'No numbers were returned';
			break;
		}
		
		// Get the first number from the response
		$numbers      = explode(',', $output['Num']);
		$first_number = explode(':', $numbers[0]);
		$save['number_raw']   = $first_number[0];
		$save['number_fmt']   = $first_number[1];

		// COMMAND: AddItemToTrolley
		unset($params);
		$params['Item.Number']     = $save['number_raw'];
		$params['Item.TariffSpec'] = $output['TariffSpec'];
		$params['_Response']       = 'Extended';
		if (isset($req['service'])) $params['Item.X.FreeTrial'] = 'dm' . ucfirst($req['service']) . '_PNXLite1_Commit';
		$output = talk_to_dmshop('AddItemToTrolley', $params);
		if ($output['status'] == 'FAIL') break;
		$save['cost'] = $output['TotalInc'];
		
		// Login or Register
		unset($params);
		if (isset($req['pin'])) {
			// Email and PIN provided, so Login
			$save['pin'] = $req['pin'];
			// COMMAND: Login
			$params['DMID']     = $req['email'];
			$params['Password'] = $req['pin'];
			$output = talk_to_dmshop('Login', $params);
			if ($output['status'] == 'FAIL') break;
		} else {
			// Try to Register
			// COMMAND: Register
			$params['Email'] = $req['email'];
			$params['PIN']   = $save['pin'] = mt_rand(1000, 9999); // Generate 4 digit random PIN number
			$params['DOB']   = $req['dob'];
			$params['MMN']   = $req['mmn'];
			$params['Forename']    = isset($req['firstname'])   ? $req['firstname'] : '';
			$params['Surname']     = isset($req['lastname'])    ? $req['lastname']  : '';
			$params['PhoneHome']   = isset($req['divert_home']) ? process_number_format($req['divert_home']) : ''; // Divert (connect/voice/switchboard)
			$params['PhoneDay']    = isset($req['divert_day'])  ? process_number_format($req['divert_day'])  : ''; // Divert (voice/switchboard)
			$params['PhoneMobile'] = isset($req['divert_mob'])  ? process_number_format($req['divert_mob'])  : ''; // Divert (voice/switchboard)
			$params['SkipVerify']  = isset($req['skip_verify']) ? 'Y' : 'N';
			$output = talk_to_dmshop('Register', $params);
			if ($output['status'] == 'FAIL') break;
		}
		
		// COMMAND: ConfirmOrder
		unset($params);
		$output = talk_to_dmshop('ConfirmOrder');
		if ($output['status'] == 'FAIL') break;
		
		// All steps have succeeded, so assign response
		$response['status']     = 'OK'; 
		$response['edi_action'] = $edi_action; 
		$response['trolleyid']  = $dmx_session; 
		$response['numberraw']  = $save['number_raw']; 
		$response['numberfmt']  = $save['number_fmt']; 
		$response['currency']   = 'UKPX'; 
		$response['cost']       = $save['cost']; 
		$response['pin']        = $save['pin']; 
		break;
	
	
	// -----------------------------------------------------------------------------
	case 'ACTION2':
		// Placeholder for another EDI Action
		break;
		
	// -----------------------------------------------------------------------------
	default:
		$output['status']     = 'FAIL'; 
		$output['edi_action'] = $edi_action; 
		$output['reason']     = 'Invalid EDI Action'; 
}

// -----------------------------------------------------------------------------

if (count($response) == 0) {
	// If the response array is empty a failure has occurred, so assign the last value of $output to response, to give some failure info
	$response = $output;
}
if ($dmx_options['debug_level'] > 0) {
	// Add dmShop debugging info to response
	$response['debug'] = $dmx_debug_msg; 
}

// Create an XML document with nodes corresponding to elements of the $response array (method 1)
/* THIS IS BETTER, but PHP5's DOM module is not installed on FastHosts servers!
$dom = new DomDocument();
$dom->formatOutput = true;
$root = $dom->createElement('ediresult');
foreach($response as $key => $value) {
	$node = $dom->createElement($key);
	$node->appendChild($dom->createTextNode(utf8_encode($value)));
	$root->appendChild($node);
}
$dom->appendChild($root);
$xml = $dom->saveXml();
*/

// Create an XML document with nodes corresponding to elements of the $response array (method 2)
$xml  = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
$xml .= "<ediresult>\n";
foreach($response as $key => $value) {
	$xml .= '  <' . $key . '>' . htmlentities($value) . '</' . $key . ">\n";
}
$xml .= "</ediresult>\n";

// Output the XML document
header('Pragma: no-cache'); // for HTTP 1.0
header('Cache-Control: no-cache, must-revalidate'); // for HTTP 1.1
header('Content-type: text/xml');
echo($xml);
exit;

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

function talk_to_dmshop($command, $params = array()) {
	// $command is the dmShop command (Cmd) to run
	// $params is an array of additional parameters, corresponding to nodes in the dmShop protocol
	// Do not supply TrolleyID or Protocol, as they are obtained from globals!
	//
	dmx_add_debug_msg("<h2 class='db_main_call'>$command</h2>");
	global $dmx_protocol, $dmx_session;
	$params['Cmd'] = $command;
	if ($dmx_session) $params['TrolleyID'] = $dmx_session;
	$result = dmx_protocol_request($dmx_protocol['servers'], $params, $dmx_protocol['current_index']);
	// Check for no response from dmShop
	if ($result['status'] == false || !count($result['response'])) {
		$output['status']     = 'FAIL'; 
		$output['edi_action'] = $GLOBALS['edi_action']; 
		$output['command']    = $command; 
		$output['reason']     = 'The shopping server is unavailable'; 
		return $output;
	}
	$response = $result['response'];
	// Check for failure message from dmShop
	if (!isset($response['Cmd']) || substr($response['Cmd'], -3) == 'Nak') {
		$output['status']     = 'FAIL'; 
		$output['edi_action'] = $GLOBALS['edi_action']; 
		$output['command']    = $command; 
		$output['reason']     = isset($response['Reason']) ? $response['Reason'] : 'dmShop did not give a reason';
		return $output;
	}
	$output = $response;
	$output['status'] = 'OK';
	return $output;
}

// -----------------------------------------------------------------------------

function check_array_keys($ar, $keys) {
	// Check that required keys exist in the $ar array
	// $keys is a list of comma separated key names
	// Returns an error string containing a list of missing keys on failure, or 'PASS'
	//
	$error = '';
	$k = explode(',', $keys);
	foreach ($k as $key) {
		if (!isset($ar[$key]) || !$ar[$key]) $error .= $key . ', ';
	}
	if ($error) return substr($error, 0, count($error)-3);
	return 'PASS';
}

// -----------------------------------------------------------------------------

function process_number_format($num) {
	// Process athe format of any number before sending to dmShop
	//
	$num = trim($num);
	if (!preg_match('/^\+?[\d -]+$/', $num)) return 'WARNING: Illegal characters ' . $num;
	$num = preg_replace('/[ -]/', '', $num);
	if (substr($num, 0, 3) == '+44') $num = '0' . substr($num, 3);
	if ($num[0] == '+') $num = '00' . substr($num, 1);
	if (strlen($num) > 20) return 'WARNING: Number too long ' . $num; 
	return $num;
}

