// Application includes
require_once('lib/nusoap.php');
// Files I have written for the interface.
require_once('include/admin.php');
require_once('include/psu.php');
// Included from psu.php, not important here.
if (!psu_init()) {
echo 'Prima Supply Updater failed to initialize.';
exit();
}
// Connecting to the database/loading our config.
$link = psu_db_connect();
$config = admin_load_config();
// Create the server instance and register methods with the server
$server = new soap_server;
$server->register('authenticate');
$server->register('sendRequestXML');
$server->register('receiveResponseXML');
$server->register('getLastError');
$server->register('closeConnection');
$server->register('connectionError');
// Function code: Each function logs its call and return..
function authenticate($username, $password) {
psulog('func_call authenticate: $username=' . $username . ', $password=', null, true);
// To access all the global data as need be.
global $config;
// Generate ticket: unique for each session since it's salted with time()
$retval[0] = md5(time() . $username);
// Validate user... return either nvu or a filepath.
// psu_valid_user checks against users in the database, included from psu.inc
if (($uid = psu_valid_user($username, $password)) != false) {
$retval[1] = stripslashes($config['filepath']);
psu_session_start($uid, $retval[0]);
$resmsg = 'Returned company filepath';
}
else {
$retval[1] = 'nvu';
$resmsg = 'Invalid username/password.';
}
psulog('func_return authenticate: token=' . $retval[0] . ', result=' . $resmsg, $uid, true);
return $retval;
}
function sendRequestXML($ticket, $HCPResponse, $CompanyFileName,
$qbXMLCountry, $qbXMLMajorVers, $qbXMLMinorVers) {
// This block here loads the proper user based on the ticket and grabs the company they're with
$uid = uid_from_ticket($ticket);
if ($uid != false) {
psu_session_update($ticket, 2);
$company = company_from_uid($uid);
}
psulog('func_call sendRequestXML: ticket=' . $ticket . ', company=' . $company, $uid);
// objXML is a class from the comments at PHP.net. ^_^
// qbxml is a class I wrote to create qbXML requests.
global $objXML;
global $qbxml;
if ($company < 1) return ''; // Throw an error so we don't try updating with a non-existant company.
/*
* $HCPResponse is only returned the first time, so we know there's a connection.
* We'll take this opportunity to fill our action_queue based on the selected actions!
*/
if ($HCPResponse != '') {
// The file_write function is a wrapper I made just to output the XML to an HTML file.
$output = $objXML->parse($HCPResponse);
file_write('hcpresponse.html', $output);
// This function adds new items, customers, and invoices to the queue which is then cycled through.
populate_queue($company);
}
$message = array();
$args = array();
// Somewhat hacked loop at the moment-> grabs the next action from the queue.
$again = true;
while ($again === true) {
$data = grab_next_action($company);
if ($data != false && is_array($data)) {
$message[] = $data['message'];
$args[] = $data['args'];
$again = $data['again'];
if (!isset($rqid)) $rqid = $data['rqid'];
}
$again = false;
}
// the qbXML class returns valid qbXML requests based on what was in the queue..
$retval = $qbxml->request($message, $args, $rqid);
// Using my wrapper function to make this request into an HTML file for debug.
file_write('request' . $rqid . '.html', $retval);
psulog(($retval == '') ? 'func_return sendRequestXML: (error)' : 'func_return sendRequestXML: qbXML', $uid);
return $retval;
}
function receiveResponseXML($ticket, $response, $hresult, $message) {
$psu_sd = psu_load_session($ticket);
if ($psu_sd != false) {
psu_session_update($ticket, 3);
$uid = $psu_sd['user_id'];
$company = company_from_uid($uid);
}
if ($hresult != '')
psulog('func_call receiveResponseXML: ticket=' . $ticket . ', ERROR=' . $hresult . ', ' . $message, $uid);
else
psulog('func_call receiveResponseXML: ticket=' . $ticket . ", response: qbXML", $uid);
global $objXML;
// Parse the response.
if ($response != '') {
$output = $objXML->parse($response);
file_write('responsexml.html', $output);
}
// Code to handle responses.
if (isset($output[0]['children'][0]['children'])) {
// This takes us to the level of the XML where responses are.
$response = $output[0]['children'][0]['children'];
// Cycle through the responses for each request sent.
foreach($response as $action) {
// This is a function call to keep track of how many actions a session performs.
$counter = increment_action_count($ticket);
$aid = $action['attrs']['REQUESTID'];
// Do some error checking, log the results if need be.
switch ($action['attrs']['STATUSCODE']) {
case 3100:
$msg = "Attempted to import an item with a duplicate fullname.\n"
. $action['attrs']['STATUSMESSAGE'];
break;
case 3231:
$msg = "The request was not processed due to a previous qbXML error.\n"
. $action['attrs']['STATUSMESSAGE'];
break;
default:
$msg = "Error " . $action['attrs']['STATUSCODE'] . ": "
. $action['attrs']['STATUSMESSAGE'];
break;
}
// Did it go through just fine?
if ($action['attrs']['STATUSCODE'] == 0) {
// Update the action_state.
update_action($aid, 3, true);
switch ($action['name']) {
// I truncated this for now just to show an example of what I do with responses
case 'CUSTOMERADDRS':
$custname = $action['children'][0]['children'][0]['tagData'];
$loc = strrpos($custname, '-');
// Grab the customer's id number from the response..
$custid = substr($custname, $loc + 1);
// Drop it into the imported table
break;
// Here is also where I handle things like saving settings. Or for a TemplateQuery
// I would write the returned available templates to the database for later usage.
}
}
else {
update_action($aid, 4, true, $msg);
psu_session_set_error($ticket, $msg);
}
}
}
// Calculate how many actions remain in the queue so I can return the correct % complete
$left = actions_remaining($company);
$total = $counter + $left;
if ($total > 0)
$retval = intval((($counter / $total) * 80) + 20);
else
$retval = 100;
if ($retval <= 0)
psulog('func_return receiveResponseXML: (error)', $uid);
else
psulog('func_return receiveResponseXML: ' . $retval . '% complete', $uid);
return $retval;
}
// Called when sendRequestXML returns an empty string or receiveResponseXML returns a negative value.
function getLastError($ticket) {
$uid = uid_from_ticket($ticket);
if ($uid != false)
psu_session_update($ticket, 4);
psulog('func_call getLastError: ticket=' . $ticket, $uid);
$retval = 'An error occurred... I know that for sure.'; // Return the appropriate error message.
psulog('func_return getLastError: ' . $retval, $uid, true);
return $retval;
}
function closeConnection($ticket) {
// Close out the session in the database.
$uid = uid_from_ticket($ticket);
psu_session_end($ticket);
psulog('func_call closeConnection: ticket=' . $ticket, $uid, true);
// Return a final message describing our status here.
$retval = 'Ticket ' . $ticket . ' closed, ' . actions_performed($ticket) . ' actions performed.';
psulog('func_return closeConnection: ' . $retval, $uid, true);
return $retval;
}
function connectionError($ticket, $hresult, $message) {
$uid = uid_from_ticket($ticket);
if ($uid != false)
psu_session_update($ticket, 6);
psulog('func_call connectionError: ticket=' . $ticket . ', ERROR=' . $hresult . ', ' . $message, $uid, true);
$retval = 'done'; // Done indicates we can't go on, whereas we could try returning the company file path.
psulog('func_return connectionError: Check to make sure your filepath is set properly', $uid);
return $retval;
}
// Use the request to (try to) invoke the NuSOAP service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
unset($server);
psu_close();