QuickBooks/WebConnector/Handlers.php
public function receiveResponseXML($obj)
	{
		//$this->_driver->log('receiveResponseXML()', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
		$this->_log('receiveResponseXML()', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

		if ($this->_driver->authCheck($obj->ticket)) // Check the ticket
		{
			$user = $this->_driver->authResolve($obj->ticket);

			$hookdata = array(
				'username' => $user,
				'ticket' => $obj->ticket,
				);
			$hookerr = '';
			$this->_callHook($obj->ticket, QUICKBOOKS_HANDLERS_HOOK_RECEIVERESPONSEXML, null, null, null, null, $hookerr, null, array(), $hookdata);

			//$this->_driver->log('Incoming XML response: ' . $obj->response, $obj->ticket, QUICKBOOKS_LOG_DEBUG);
			$this->_log('Incoming XML response: ' . $obj->response, $obj->ticket, QUICKBOOKS_LOG_DEBUG);

			// Check if we got a error message...
			if (strlen($obj->message) or
				$this->_extractStatusCode($obj->response)) // or an error code
			{
				//$this->_log('Extracted code[' . $this->_extractStatusCode($obj->response) . ']', $obj->ticket, QUICKBOOKS_LOG_DEBUG);

				$action = null;
				$ident = null;
				$current = null;		// The current item we're receiving a response for

				$errnum = null;
				if ($requestID = $this->_extractRequestID($obj->response))
				{
					// This happens if a data validation error occurs
					//	(string too long, vendor name already taken, etc.)

					$errnum = $this->_extractStatusCode($obj->response);

					if ($current = $this->_driver->queueGet($user, $requestID, QUICKBOOKS_STATUS_PROCESSING))
					{
						// This is the particular item that experienced an error
						$action = $current['qb_action'];
						$ident = $current['ident'];
					}
					else
					{
						$requestID = null;
					}

					//$action = '';
					//$ident = '';
					//$this->_parseRequestID($requestID, $action, $ident);
				}
				else
				{
					// This happens if a protocol error occurs
					//	Poorly formed XML documents, missing XML node, missing line items, etc.)

					$errnum = $obj->hresult;

					// Try to guess at the request that caused an error (the last request that went out)
					if ($current = $this->_driver->queueProcessing($user))
					{
						$requestID = $current['quickbooks_queue_id'];
						$action = $current['qb_action'];
						$ident = $current['ident'];
					}
				}

				//if ($user and $action and $ident)
				if ($current)
				{
					// Fetch the request that was processed and EXPERIENCED AN ERROR!
					$extra = null;
					/*
					if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING))
					{
						if ($current['extra'])
						{
							$extra = unserialize($current['extra']);
						}
					}
					*/

					if ($current['extra'])
					{
						$extra = unserialize($current['extra']);
					}

					$errmsg = null;
					if ($obj->message)
					{
						$errmsg = $obj->message;
					}
					else if ($status = $this->_extractStatusMessage($obj->response))
					{
						$errmsg = $status;
					}

					$errerr = '';
					$continue = $this->_handleError($obj->ticket, $errnum, $errmsg, $requestID, $action, $ident, $extra, $errerr, $obj->response, array());
					//					$errnum, $errmsg, $requestID, $action, $ident, $extra, &$err, $xml, $qb_identifiers = array()

					if ($errerr)
					{
						// The error handler returned an error too...
						//$this->_driver->log('An error occured while handling quickbooks error ' . $errnum . ': ' . $errmsg . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
						$this->_log('An error occured while handling quickbooks error ' . $errnum . ': ' . $errmsg . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
					}
				}
				else	// Generic error (poorly encoded XML, XML syntax error, etc.)
				{
					$errerr = '';
					$continue = $this->_handleError($obj->ticket, $obj->hresult, $obj->message, null, null, null, null, $errerr, $obj->response, array());

					if ($errerr)
					{
						// The error handler returned an error too...
						//$this->_driver->log('An error occured while handling generic error ' . $obj->hresult . ': ' . $obj->message . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
						$this->_log('An error occured while handling generic error ' . $obj->hresult . ': ' . $obj->message . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
					}
				}

				// Calculate the percentage done
				$progress = $this->_calculateProgress($obj->ticket);

				if (!$continue)
				{
					$progress = -1;
				}

				//$this->_driver->log('Transaction error at ' . $progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
				$this->_log('Transaction error at ' . $progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
			}

			$extra = null;
			$action = null;
			$ident = null;

			$requestID = null;
			if ($requestID = $this->_extractRequestID($obj->response) and
				$current = $this->_driver->queueGet($user, $requestID, QUICKBOOKS_STATUS_PROCESSING))
			{
				//$action = current(explode('|', $requestID));
				//$ident = end(explode('|', $requestID));
				/*
				$action = '';
				$ident = '';
				$this->_parseRequestID($requestID, $action, $ident);
				*/

				$action = $current['qb_action'];
				$ident = $current['ident'];

				// Fetch the request that's being processed
				$extra = null;
				/*
				if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING))
				{
					if ($current['extra'])
					{
						$extra = unserialize($current['extra']);
					}
				}
				*/

				if ($current['extra'])
				{
					$extra = unserialize($current['extra']);
				}

				// Update the status to success (no error occured)
				//$this->_driver->queueStatus($obj->ticket, $action, $ident, QUICKBOOKS_STATUS_SUCCESS);
				$this->_driver->queueStatus($obj->ticket, $requestID, QUICKBOOKS_STATUS_SUCCESS);
			}
			else
			{
				// It's a good response... but we couldn't fetch the requestID for some reason?
				$this->_log('This appears to be a correct response, but the requestID could not be validated... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

				$progress = -1;

				return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
			}

			// Extract ListID, TxnID, etc. from the response
			$identifiers = $this->_extractIdentifiers($obj->response);

			//$this->_driver->log(var_export($identifiers, true), $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

			// Auto-map $ident unique identifier from web application to the QuickBooks ListID or TxnID
			/*
			if ($this->_config['map_application_identifiers'])
			{
				$adds = QuickBooks_Utilities::listActions('*Add*');
				$mods = QuickBooks_Utilities::listActions('*Mod*');
				$qbkey = QuickBooks_Utilities::keyForAction($action);
				$type = QuickBooks_Utilities::actionToObject($action);

				$EditSequence = '';
				if (isset($identifiers['EditSequence']))
				{
					$EditSequence = $identifiers['EditSequence'];
				}

				if (in_array($action, $adds) and isset($identifiers[$qbkey]) and $type)
				{
					// Try to map the $ident to the QuickBooks identifier
					$this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence);
				}
				else if (in_array($action, $mods) and isset($identifiers[$qbkey]) and $type)
				{
					// Try to map the $ident to the QuickBooks identifier
					$this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence);
				}
			}
			*/

			$err = null;
			//$last_action_time = $this->_driver->queueActionLast($user, $action);
			//$last_actionident_time = $this->_driver->queueActionIdentLast($user, $action, $ident);
			$last_action_time = null;
			$last_actionident_time = null;

			//if ($ident) // If they didn't pass a requestID, $ident will not be set, and we can't call this reliably
			if ($requestID)
			{
				$this->_callMappedFunction(1, $user, $requestID, $action, $ident, $extra, $err, $last_action_time, $last_actionident_time, $obj->response, $identifiers);
			}

			// Calculate the percentage done
			$progress = $this->_calculateProgress($obj->ticket);

			if ($err)
			{
				$errerr = '';
				$continue = $this->_handleError($obj->ticket, QUICKBOOKS_ERROR_HANDLER, $err, $requestID, $action, $ident, $extra, $errerr, $obj->response, $identifiers);

				if (!$continue)
				{
					$progress = -1;
				}
			}

			//$this->_driver->log($progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
			$this->_log($progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

			return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
		}

		return new QuickBooks_WebConnector_Result_ReceiveResponseXML(-1);
	}
public function receiveResponseXML($obj)
	{
		//$this->_driver->log('receiveResponseXML()', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
		$this->_log('receiveResponseXML()', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

		if ($this->_driver->authCheck($obj->ticket)) // Check the ticket
		{
			$user = $this->_driver->authResolve($obj->ticket);

			$hookdata = array(
				'username' => $user,
				'ticket' => $obj->ticket,
				);
			$hookerr = '';
			$this->_callHook($obj->ticket, QUICKBOOKS_HANDLERS_HOOK_RECEIVERESPONSEXML, null, null, null, null, $hookerr, null, array(), $hookdata);

			//$this->_driver->log('Incoming XML response: ' . $obj->response, $obj->ticket, QUICKBOOKS_LOG_DEBUG);
			$this->_log('Incoming XML response: ' . $obj->response, $obj->ticket, QUICKBOOKS_LOG_DEBUG);

			// Check if we got a error message...
			if (strlen($obj->message) or
				$this->_extractStatusCode($obj->response)) // or an error code
			{
				//$this->_log('Extracted code[' . $this->_extractStatusCode($obj->response) . ']', $obj->ticket, QUICKBOOKS_LOG_DEBUG);

				$action = null;
				$ident = null;
				$current = null;		// The current item we're receiving a response for

				$errnum = null;
				if ($requestID = $this->_extractRequestID($obj->response))
				{
					// This happens if a data validation error occurs
					//	(string too long, vendor name already taken, etc.)

					$errnum = $this->_extractStatusCode($obj->response);

					if ($current = $this->_driver->queueGet($user, $requestID, QUICKBOOKS_STATUS_PROCESSING))
					{
						// This is the particular item that experienced an error
						$action = $current['qb_action'];
						$ident = $current['ident'];
					}
					else
					{
						$requestID = null;
					}

					//$action = '';
					//$ident = '';
					//$this->_parseRequestID($requestID, $action, $ident);
				}
				else
				{
					// This happens if a protocol error occurs
					//	Poorly formed XML documents, missing XML node, missing line items, etc.)

					$errnum = $obj->hresult;

					// Try to guess at the request that caused an error (the last request that went out)
					if ($current = $this->_driver->queueProcessing($user))
					{
						$requestID = $current['quickbooks_queue_id'];
						$action = $current['qb_action'];
						$ident = $current['ident'];
					}
				}

				//if ($user and $action and $ident)
				if ($current)
				{
					// Fetch the request that was processed and EXPERIENCED AN ERROR!
					$extra = null;
					/*
					if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING))
					{
						if ($current['extra'])
						{
							$extra = unserialize($current['extra']);
						}
					}
					*/

					if ($current['extra'])
					{
						$extra = unserialize($current['extra']);
					}

					$errmsg = null;
					if ($obj->message)
					{
						$errmsg = $obj->message;
					}
					else if ($status = $this->_extractStatusMessage($obj->response))
					{
						$errmsg = $status;
					}

					$errerr = '';
					$continue = $this->_handleError($obj->ticket, $errnum, $errmsg, $requestID, $action, $ident, $extra, $errerr, $obj->response, array());
					//					$errnum, $errmsg, $requestID, $action, $ident, $extra, &$err, $xml, $qb_identifiers = array()

					if ($errerr)
					{
						// The error handler returned an error too...
						//$this->_driver->log('An error occured while handling quickbooks error ' . $errnum . ': ' . $errmsg . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
						$this->_log('An error occured while handling quickbooks error ' . $errnum . ': ' . $errmsg . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
					}
				}
				else	// Generic error (poorly encoded XML, XML syntax error, etc.)
				{
					$errerr = '';
					$continue = $this->_handleError($obj->ticket, $obj->hresult, $obj->message, null, null, null, null, $errerr, $obj->response, array());

					if ($errerr)
					{
						// The error handler returned an error too...
						//$this->_driver->log('An error occured while handling generic error ' . $obj->hresult . ': ' . $obj->message . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
						$this->_log('An error occured while handling generic error ' . $obj->hresult . ': ' . $obj->message . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL);
					}
				}

				// Calculate the percentage done
				$progress = $this->_calculateProgress($obj->ticket);

				if (!$continue)
				{
					$progress = -1;
				}

				//$this->_driver->log('Transaction error at ' . $progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
				$this->_log('Transaction error at ' . $progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
			}

			$extra = null;
			$action = null;
			$ident = null;

			$requestID = null;
			if ($requestID = $this->_extractRequestID($obj->response) and
				$current = $this->_driver->queueGet($user, $requestID, QUICKBOOKS_STATUS_PROCESSING))
			{
				//$action = current(explode('|', $requestID));
				//$ident = end(explode('|', $requestID));
				/*
				$action = '';
				$ident = '';
				$this->_parseRequestID($requestID, $action, $ident);
				*/

				$action = $current['qb_action'];
				$ident = $current['ident'];

				// Fetch the request that's being processed
				$extra = null;
				/*
				if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING))
				{
					if ($current['extra'])
					{
						$extra = unserialize($current['extra']);
					}
				}
				*/

				if ($current['extra'])
				{
					$extra = unserialize($current['extra']);
				}

				// Update the status to success (no error occured)
				//$this->_driver->queueStatus($obj->ticket, $action, $ident, QUICKBOOKS_STATUS_SUCCESS);
				$this->_driver->queueStatus($obj->ticket, $requestID, QUICKBOOKS_STATUS_SUCCESS);
			}
			else
			{
				// It's a good response... but we couldn't fetch the requestID for some reason?
				$this->_log('This appears to be a correct response, but the requestID could not be validated... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

				$progress = -1;

				return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
			}

			// Extract ListID, TxnID, etc. from the response
			$identifiers = $this->_extractIdentifiers($obj->response);

			//$this->_driver->log(var_export($identifiers, true), $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

			// Auto-map $ident unique identifier from web application to the QuickBooks ListID or TxnID
			/*
			if ($this->_config['map_application_identifiers'])
			{
				$adds = QuickBooks_Utilities::listActions('*Add*');
				$mods = QuickBooks_Utilities::listActions('*Mod*');
				$qbkey = QuickBooks_Utilities::keyForAction($action);
				$type = QuickBooks_Utilities::actionToObject($action);

				$EditSequence = '';
				if (isset($identifiers['EditSequence']))
				{
					$EditSequence = $identifiers['EditSequence'];
				}

				if (in_array($action, $adds) and isset($identifiers[$qbkey]) and $type)
				{
					// Try to map the $ident to the QuickBooks identifier
					$this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence);
				}
				else if (in_array($action, $mods) and isset($identifiers[$qbkey]) and $type)
				{
					// Try to map the $ident to the QuickBooks identifier
					$this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence);
				}
			}
			*/

			$err = null;
			//$last_action_time = $this->_driver->queueActionLast($user, $action);
			//$last_actionident_time = $this->_driver->queueActionIdentLast($user, $action, $ident);
			$last_action_time = null;
			$last_actionident_time = null;

			//if ($ident) // If they didn't pass a requestID, $ident will not be set, and we can't call this reliably
			if ($requestID)
			{
				$this->_callMappedFunction(1, $user, $requestID, $action, $ident, $extra, $err, $last_action_time, $last_actionident_time, $obj->response, $identifiers);
			}

			// Calculate the percentage done
			$progress = $this->_calculateProgress($obj->ticket);

			if ($err)
			{
				$errerr = '';
				$continue = $this->_handleError($obj->ticket, QUICKBOOKS_ERROR_HANDLER, $err, $requestID, $action, $ident, $extra, $errerr, $obj->response, $identifiers);

				if (!$continue)
				{
					$progress = -1;
				}
			}

			//$this->_driver->log($progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);
			$this->_log($progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE);

			return new QuickBooks_WebConnector_Result_ReceiveResponseXML($progress);
		}

		return new QuickBooks_WebConnector_Result_ReceiveResponseXML(-1);
	}
ReceiveResponseXML() method for the QuickBooks Web Connector - Receive and handle a resonse form QuickBooks

The stdClass object passed as a parameter will have the following members:
- ->ticket 		The QuickBooks Web Connector ticket
- ->response	An XML response message
- ->hresult		Error code
- ->message		Error message

The sole data member of the returned object should be an integer.
- The data member should be -1 if an error occured and QBWC should call ->getLastError()
- Should be an integer 0 <= x < 100 to indicate success *and* that the application should continue to call ->sendRequestXML() at least one more time (more queued items still in the queue, the integer represents the percentage complete the total batch job is)
- Should be 100 to indicate success *and* that the queue has been exhausted

The following user-defined hooks are invoked:
- QUICKBOOKS_HANDLERS_HOOK_RECEIVERESPONSEXML

@param stdClass $obj
@return QuickBooks_Result_ReceiveResponseXML