From 6d63303f496c1265c27d3007bae6d80cf853775d Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Wed, 4 Apr 2012 17:54:57 +0300 Subject: Lots of experimental changes --- README.md | 6 +- gsxcl | 177 ++++++++----- gsxcl2 | 55 ++++ gsxlib.php | 867 +++++++++++++++++++++++++++++++++++-------------------------- 4 files changed, 664 insertions(+), 441 deletions(-) create mode 100755 gsxcl2 diff --git a/README.md b/README.md index dfeb732..e2d27b1 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ validation (as opposed to burdening Apple's servers with totally invalid request ##Requrements## -Your PHP should have SOAP support enabled. Most distributions should (including OS X Server 10.6 or later). -For more details, consult your distribution or the [PHP documentation][2]. +Your PHP must have SOAP support. Most distributions should (including OS X Server 10.6 or later). For more details, consult your distribution or the [PHP documentation][2]. ##Usage## @@ -21,13 +20,14 @@ Best illustrated with a simple example: $info = $gsx->warrantyStatus($serialnumber); echo $info->productDescription; > MacBook Pro (15-inch 2.4/2.2GHz) + ?> If you're in the US, remember to set the fifth argument to the constructor to 'am'. ##gsxcl## -The package includes a rudimentary command line client to the GSX API called gsxcl. It can perform various functions in the library and is meant +The package includes a rudimentary command line client to the GSX API called _gsxcl_. It can perform various functions in the library and is meant mainly as a simple test tool for the library. ##License## diff --git a/gsxcl b/gsxcl index 7781f53..7bb0ee6 100755 --- a/gsxcl +++ b/gsxcl @@ -14,19 +14,22 @@ * http://sam.zoy.org/wtfpl/COPYING for more details. */ -if (FALSE) { - error_reporting(E_ALL|E_STRICT); +if (TRUE) { + error_reporting( E_ALL|E_STRICT ); } -$modes = array( 'warranty', 'parts', 'pending', 'repair', 'lookup', 'status', 'label', 'model', 'osdispatchdetail' ); -$modes_str = implode(', ', $modes); +$verbs = array( 'create', 'lookup', 'update', 'status', 'label', 'pending', 'details' ); +$nouns = array( 'repair', 'part', 'dispatch', 'order', 'return', 'warranty' ); + +$nouns_str = implode( ', ', $nouns ); +$verbs_str = implode( ', ', $verbs ); require 'gsxlib.php'; -if (count($argv) < 6) { +if( count( $argv ) < 6 ) { echo <<warrantyStatus($query); - break; - case 'parts': - $result = $gsx->partsLookup($query); - break; - case 'pending': - $result = $gsx->partsPendingReturn($query); - break; + switch( $verb ) { + case 'status': + $result = $gsx->warrantyStatus( $data ); + break; + } + + break; + + case 'part': + switch( $verb ) { + case 'lookup': + $result = $gsx->partsLookup( $data ); + break; + case 'pending': + $result = $gsx->partsPendingReturn( $data ); + break; + case 'details': + $result = $gsx->partsPendingReturn( $data ); + break; + } + + break; + case 'repair': - $result = $gsx->repairDetails($query); - break; - case 'lookup': - $result = $gsx->repairLookup($query); - break; - case 'status': - $result = $gsx->repairStatus($query); - break; - case 'comptia': - $result = $gsx->compTiaCodes(); - break; + switch( $verb ) { + case 'lookup': + $result = $gsx->repairLookup( $data ); + break; + case 'details': + $result = $gsx->partsPendingReturn( $data ); + break; + case 'status': + $result = $gsx->repairStatus( $query ); + break; + } + case 'model': $result = $gsx->productModel( $query ); break; @@ -104,55 +130,66 @@ switch ($mode) $result = $gsx->onsiteDispatchDetail( $query ); break; case 'label': - list($order, $part) = explode(':', $query); - $result = $gsx->returnLabel($order, $part); + list($order, $part) = explode( ':', $query ); + $result = $gsx->returnLabel( $order, $part ); $name = $result->returnLabelFileName; echo $result->returnLabelFileData; break; } -switch ($format) +switch( $format ) { case 'json': - echo json_encode($result); + echo json_encode( $result ); break; + case 'xml': - $xml = simplexml_load_string(''); + if( !function_exists( 'simplexml_load_string' )) { + exit( "Error: your PHP lacks SimpleXML support!\n" ); + } + + $xml = simplexml_load_string( '' ); + foreach ($result as $k => $v) { - $key = (is_numeric($k)) ? 'item' : $k; - $value = (is_object($v)) ? null : $v; - $item = $xml->addChild($key, $value); - if (is_object($v)) { - foreach ($v as $vk => $vv) { - $item->addChild($vk, $vv); + $key = (is_numeric( $k )) ? 'item' : $k; + $value = (is_object( $v )) ? null : $v; + $item = $xml->addChild( $key, $value ); + if( is_object( $v )) { + foreach( $v as $vk => $vv ) { + $item->addChild( $vk, $vv ); } } } + echo $xml->asXML(); break; + case 'csv': $i = 0; $fo = fopen('php://stdout', 'w'); - foreach ($result as $k => $v) + foreach( $result as $k => $v ) { - if (is_object($v)) + if( is_object( $v )) { $keys = array(); $vals = array(); - foreach ($v as $vk => $vv) - { + + foreach ($v as $vk => $vv) { if ($i == 0) { $keys[] = $vk; } $vals[] = $vv; } + // treat field names of first item as header row if ($i == 0) { - fputcsv($fo, $keys); + fputcsv( $fo, $keys ); } - fputcsv($fo, $vals); + + fputcsv( $fo, $vals ); + } else { $keys[] = $k; $vals[] = $v; diff --git a/gsxcl2 b/gsxcl2 new file mode 100755 index 0000000..83f1b41 --- /dev/null +++ b/gsxcl2 @@ -0,0 +1,55 @@ +#! /usr/bin/env php +getClient(); +$functions = $client->__getFunctions(); + +if($argv[8] == 'list') { + print_r($functions); + exit(); +} + +foreach($functions as $f) { + if(strstr($f, $api)) { + $valid = true; + } +} + +if(!$valid) { + exit(sprintf('Function "%s" is invalid', $api)); +} + +$params = json_decode($argv[8], TRUE); + +if($params === NULL) { + exit('Invalid params!'); +} + +$session = array('userSession' => array('userSessionId' => $gsx->getSessionId())); +$req = "{$api}Request"; + +if($api == 'CompTIACodes') { + $req = 'ComptiaCodeLookupRequest'; +} + +$request = array($req => array_merge($params, $session)); +$result = $client->$api($request); + +print_r($result); diff --git a/gsxlib.php b/gsxlib.php index 60d57e5..b9e81e8 100644 --- a/gsxlib.php +++ b/gsxlib.php @@ -3,7 +3,7 @@ * gsxlib/gsxlib.php * @package gsxlib * @author Filipp Lepalaan - * http://gsxwsut.apple.com/apidocs/html/WSReference.html?user=asp + * https://gsxwsut.apple.com/apidocs/html/WSReference.html?user=asp * @license * This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it @@ -13,413 +13,544 @@ */ class GsxLib { - private $client; - private $region; - private $session_id; - private $environment; + private $client; + private $region; + private $session_id; + private $environment; + + //IT: https://gsxws%s.apple.com/wsdl/%sAsp/gsx-%sAsp.wsdl + //PROD: https://gsxws2.apple.com/wsdl/%sAsp/gsx-%sAsp.wsdl + private $wsdl = 'https://gsxws%s.apple.com/wsdl/%sAsp/gsx-%sAsp.wsdl'; + + static $_instance; + + const timeout = 30; // session timeout in minutes + + public static function getInstance( + $account, + $username, + $password, + $environment = '', + $region = 'emea', + $tz = 'CEST') + { + if(!(self::$_instance instanceof self)) { + self::$_instance = new self( + $account, + $username, + $password, + $environment, + $region, + $tz + ); + } + + return self::$_instance; - const timeout = 30; - - function __construct($account, $username, $password, $environment = '', $region = 'emea', $tz = 'CEST') - { - if (!class_exists('SoapClient')) { - exit('Looks like your PHP lacks SOAP support'); - } - - if (!preg_match('/\d+/', $account)) { - exit('Invalid Sold-To: ' . $account); - } - - $regions = array('am', 'emea', 'apac', 'la'); - - if (!in_array($region, $regions)) { - exit('Region '.$region.' should be one of: ' . implode(', ', $regions)); - } - - $envirs = array('ut', 'it'); - - if (!empty($environment)) { - if (!in_array($environment, $envirs)) { - exit('Environment '.$environment. ' should be one of: ' . implode(', ', $envirs)); - } - } - - $wsdl = 'https://gsxws2%s.apple.com/wsdl/%sAsp/gsx-%sAsp.wsdl'; - - if( $environment == 'ut' ) { - $wsdl = 'https://gsxws2%s.apple.com/gsx-ws/services/%s/asp?wsdl'; - } - - $wsdl = sprintf( $wsdl, $environment, $region, $region ); - - $this->client = new SoapClient($wsdl, array('exceptions' => TRUE, 'trace' => 1)); - - if (!$this->client) { - exit('Failed to create SOAP client.'); } - - $a = array( - 'AuthenticateRequest' => array( - 'userId' => $username, - 'password' => $password, - 'serviceAccountNo' => $account, - 'languageCode' => 'en', - 'userTimeZone' => $tz, - ) - ); - - if (@$_SESSION['_gsxlib_session_timeout'] > time()) { - return $this->session_id = $_SESSION['_gsxlib_session_id']; + + private function __clone() {} + + private function __construct( + $account, + $username, + $password, + $environment = '', + $region = 'emea', + $tz = 'CEST' ) + { + if(!class_exists('SoapClient')) { + throw new GsxException('Looks like your PHP lacks SOAP support'); + } + + if(!preg_match('/\d+/', $account)) { + throw new GsxException('Invalid Sold-To: ' . $account); + } + + $regions = array('am', 'emea', 'apac', 'la'); + + if(!in_array($region, $regions)) + { + $error = 'Region "%s" should be one of: %s'; + $error = sprintf($error, $region, implode(', ', $regions)); + throw new GsxException($error); + } + + $envirs = array('ut', 'it'); + + if(!empty($environment)) + { + if(!in_array($environment, $envirs)) + { + $error = 'Environment "%s" should be one of: %s'; + $error = sprintf($error, $environment, implode(', ', $envirs)); + throw new GsxException($error); + } + } else { + // GSX2... + $environment = '2'; + } + + $this->wsdl = sprintf($this->wsdl, $environment, $region, $region); + + $this->client = new SoapClient( + $this->wsdl, array('exceptions' => TRUE, 'trace' => 1) + ); + + if(!$this->client) { + throw new GsxException('Failed to create SOAP client.'); + } + + if(@$_SESSION['_gsxlib_timeout'][$account] > time()) { + // return $this->session_id = $_SESSION['_gsxlib_id'][$account]; + } + + $a = array( + 'AuthenticateRequest' => array( + 'userId' => $username, + 'password' => $password, + 'serviceAccountNo' => $account, + 'languageCode' => 'en', + 'userTimeZone' => $tz, + ) + ); +syslog(LOG_ERR, print_r($a, true)); + try { + $this->session_id = $this->client + ->Authenticate($a) + ->AuthenticateResponse + ->userSessionId; + } catch(SoapFault $e) { + if(empty($environment)) $environment = 'production'; + + $error = 'Authentication with GSX failed. Does this account have access to ' + .$environment."?\n"; + throw new GsxException($error); + + } + + // there's a session going, put the credentials in there + if(session_id()) { + $_SESSION['_gsxlib_id'][$account] = $this->session_id; + $timeout = time()+(60*self::timeout); + $_SESSION['_gsxlib_timeout'][$account] = $timeout; + } + } - - try { - $this->session_id = $this->client - ->Authenticate($a) - ->AuthenticateResponse - ->userSessionId; + + function getClient() + { + return $this->client; } - catch (SoapFault $e) { - if( empty( $environment )) { - $environment = 'production'; - } - exit('Authentication with GSX failed. Does this account have access to '.$environment."?\n"); + + function setClient($client) + { + $this->client = $client; } + + /** + * Get current GSX status of repair + * @param mixed $dispatchId + */ + public function repairStatus($dispatchId) + { + $toCheck = array(); + + if(!is_array($dispatchId)) { + $dispatchId = array($dispatchId); + } + + foreach($dispatchId as $id) { + if (self::looksLike($id, 'dispatchId')) { + $toCheck[] = $id; + } + } + + if(empty($toCheck)) { + exit('No valid dispatch IDs given'); + } + + $req = array('RepairStatus' => array( + 'repairConfirmationNumbers' => $toCheck + )); + + return $this->request($req)->repairStatus; - // there's a session going, put the credentials in there - if (session_id()) { - $_SESSION['_gsxlib_session_id'] = $this->session_id; - $_SESSION['_gsxlib_session_timeout'] = time()+(60*self::timeout); } - } - - /** - * Get current GSX status of repair - * @param mixed $dispatchId - */ - public function repairStatus( $dispatchId ) - { - $toCheck = array(); - - if (!is_array($dispatchId)) { - $dispatchId = array($dispatchId); + public function fetchiOsActivation($query) + { + $like = self::looksLike($query); + + $request = array('FetchIOSActivationDetails' => array( + $like => $query + )); + + return $this->request($request); + } - foreach ($dispatchId as $id) { - if (self::looksLike($id, 'dispatchId')) { - $toCheck[] = $id; - } + public function createCarryInRepair($repairData) + { + $resp = $this->client->CreateCarryInRepair( + array('CreateCarryInRequest' => array( + 'userSession' => array('userSessionId' => $this->getSessionId()), + 'repairData' => $repairData + )) + ); + + return $resp->CreateCarryInResponse; + } - if (empty($toCheck)) { - exit('No valid dispatch IDs given'); + public function createMailInRepair($repairData) + { + } - $req = array('RepairStatus' => array( - 'repairConfirmationNumbers' => $toCheck - )); - - return $this->request($req)->repairStatus; - - } - - public function bulkReturnProforma() - { - + public function bulkReturnProforma() {} + + public function repairLookup($query) + { + $fields = array( + 'repairConfirmationNumber' => '', + 'customerEmailAddress' => '', + 'customerFirstName' => '', + 'customerLastName' => '', + 'fromDate' => '', + 'toDate' => '', + 'incompleteRepair' => 'N', + 'pendingShipment' => 'N', + 'purchaseOrderNumber' => '', + 'repairNumber' => '', + 'repairStatus' => '', + 'repairType' => 'CA', + 'serialNumber' => '', + 'shipToCode' => '', + 'soldToReferenceNumber' => '', + 'technicianFirstName' => '', + 'technicianLastName' => '', + 'unreceivedModules' => 'N', + ); + + // provide "shortcuts" for dispatch ID and SN + switch(self::looksLike($query)) { + case 'dispatchId': + $query = array('repairConfirmationNumber' => $query); + break; + case 'serialNumber': + $query = array('serialNumber' => $query); + break; + } + + $query = array_merge($fields, $query); + $req = array( 'RepairLookupRequest' => array( + 'userSession' => array('userSessionId' => $this->session_id), + 'lookupRequestData' => $query + )); + + $response = $this->client->RepairLookup($req) + ->RepairLookupResponse; + return $response->lookupResponseData; } - public function repairLookup( $query ) - { - $fields = array( - 'repairConfirmationNumber' => '', - 'customerEmailAddress' => '', - 'customerFirstName' => '', - 'customerLastName' => '', - 'fromDate' => '', - 'toDate' => '', - 'incompleteRepair' => 'N', - 'pendingShipment' => 'N', - 'purchaseOrderNumber' => '', - 'repairNumber' => '', - 'repairStatus' => '', - 'repairType' => 'CA', - 'serialNumber' => '', - 'shipToCode' => '', - 'soldToReferenceNumber' => '', - 'technicianFirstName' => '', - 'technicianLastName' => '', - 'unreceivedModules' => 'N', - ); - - $like = self::looksLike( $query ); - - switch( $like ) { - case 'dispatchId': - $query = array( 'repairConfirmationNumber' => $query ); - break; - case 'serialNumber': - $query = array( 'serialNumber' => $query ); - break; - } - - $query = array_merge( $fields, $query ); - - $req = array( 'RepairLookupRequest' => - array( 'userSession' => array( 'userSessionId' => $this->session_id ), 'lookupRequestData' => $query ) - ); + /** + * List parts pending for return + * Default to Open Carry-Ins + * @param mixed $repairData + * @return mixed + */ + public function partsPendingReturn($repairData = null) + { + $fields = array( + 'repairType' => 'CA', // default to Carry In repairs + 'repairStatus' => 'Open', // and current ones + 'purchaseOrderNumber' => '', + 'sroNumber' => '', + 'repairConfirmationNumber' => '', + 'serialNumber' => '', + 'shipToCode' => '', + 'customerFirstName' => '', + 'customerLastName' => '', + 'customerEmailAddress' => '', + 'createdFromDate' => '', + 'createdToDate' => '', + ); + + if( !is_array( $repairData )) { + $repairData = array(); + } - $response = $this->client->RepairLookup( $req )->RepairLookupResponse; + if(!empty($repairData)) { + foreach($fields as $k => $v) { + if(array_key_exists($k, $repairData)) { + $fields[$k] = $repairData[$f]; + } + } + } - return $response->lookupResponseData; + $req = array('PartsPendingReturn' => array('repairData' => $fields)); - } - - /** - * List parts pending for return - * Default to Open Carry-Ins - * @param mixed $repairData - * @return mixed - */ - public function partsPendingReturn($repairData = null) - { - $fields = array( - 'repairType' => 'CA', // default to Carry In repairs - 'repairStatus' => 'Open', // and current ones - 'purchaseOrderNumber' => '', - 'sroNumber' => '', - 'repairConfirmationNumber' => '', - 'serialNumber' => '', - 'shipToCode' => '', - 'customerFirstName' => '', - 'customerLastName' => '', - 'customerEmailAddress' => '', - 'createdFromDate' => '', - 'createdToDate' => '', - ); + return $this->request($req)->partsPendingResponse; - if (!is_array($repairData)) { - $repairData = array(); } - if (!empty($repairData)) { - foreach ($fields as $k => $v) { - if (array_key_exists($k, $repairData)) { - $fields[$k] = $repairData[$f]; + public function fetchDiagnostics($query) + { + if(!is_array($query)) { + $like = self::looksLike($query); + $query = array($like => $query); } - } + + $req = array('FetchRepairDiagnostic' => array( + 'lookupRequestData' => $query + )); + + return $this->request($req); + } - $req = array('PartsPendingReturn' => array('repairData' => $fields)); - - return $this->request($req)->partsPendingResponse; - - } - - public function compTiaCodes() - { - $result = $this->request(array('ComptiaCodeLookup' => array())); - return $result->comptiaInfo; - } - - /** - * Return details for given dispatch ID - * @param string $dispatchId - * @return object lookupResponseData - */ - public function repairDetails($dispatchId) - { - $dispatchId = trim($dispatchId); - - if (!self::looksLike($dispatchId, 'dispatchId')) { - exit('Invalid dispatch ID: ' . $dispatchId); + public function compTiaCodes() + { + try { + $result = $this->client->CompTIACodes( + array('ComptiaCodeLookupRequest' => + array('userSession' => array('userSessionId' => $this->session_id))) + ); + } catch (Exception $e) { + syslog(LOG_ERR, $e->getMessage()); + syslog(LOG_ERR, $this->client->__getLastRequest()); + syslog(LOG_ERR, $this->client->__getLastResponse()); + } + + $response = $result->ComptiaCodeLookupResponse; + return $response->comptiaInfo; } - - $req = array('RepairDetails' => array('dispatchId' => $dispatchId)); - return $this->request($req)->lookupResponseData; - } - - /** - * Get PDF label for part return - * @param string $returnOrder order number - * @param string $partNumber code of part being returned - */ - public function returnLabel($returnOrder, $partNumber) - { - if (!self::looksLike($returnOrder, 'returnOrder')) { - exit('Invalid order number: ' . $returnOrder); + /** + * Return details for given dispatch ID + * @param string $dispatchId + * @return object lookupResponseData + */ + public function repairDetails($dispatchId) + { + $dispatchId = trim($dispatchId); + + if( !self::looksLike( $dispatchId, 'dispatchId' )) { + exit( 'Invalid dispatch ID: ' . $dispatchId ); + } + + $req = array('RepairDetails' => array('dispatchId' => $dispatchId)); + return $this->request($req)->lookupResponseData; + } - - if (!self::looksLike($partNumber, 'partNumber')) { - exit('Invalid part number: ' . $partNumber); + + /** + * Get PDF label for part return + * @param string $returnOrder order number + * @param string $partNumber code of part being returned + */ + public function returnLabel($returnOrder, $partNumber) + { + if(!self::looksLike($returnOrder, 'returnOrder')) { + exit('Invalid order number: ' . $returnOrder); + } + + if(!self::looksLike($partNumber, 'partNumber')) { + exit('Invalid part number: ' . $partNumber); + } + + $req = array('ReturnLabel' => array( + 'returnOrderNumber' => $returnOrder, + 'partNumber' => $partNumber + )); + + return $this->request($req)->returnLabelData; + } - - $req = array('ReturnLabel' => array( - 'returnOrderNumber' => $returnOrder, - 'partNumber' => $partNumber - )); - - return $this->request($req)->returnLabelData; - - } - - /** - * a shortcut for looking up part information - * @param mixed $string - * @return [bool|string] - */ - public function partsLookup($string = null) - { - $string = trim($string); - $what = self::looksLike($string); - - if (!$what) { - exit('Invalid search term for part lookup: ' . $string); + + /** + * a shortcut for looking up part information + * @param mixed $query + * @return [bool|string] + */ + public function partsLookup($query = null) + { + if(is_array($query)) { + $req = array('PartsLookup' => array( + 'lookupRequestData' => $query + )); + } else { + $query = trim($query); + $what = self::looksLike($query); + + if(!$what) { + throw new GsxException('Invalid search term for part lookup: '.$query); + } + + $query = array($what => $query); + + } + + $req = array('PartsLookup' => array( + 'lookupRequestData' => $query + )); + + $result = $this->request($req)->parts; + // always return an array + return (is_array($result)) ? $result : array($result); + } - - $req = array('PartsLookup' => array( - 'lookupRequestData' => array($what => $string) - )); - - return $this->request($req)->parts; - - } - - /** - * A shortcut for checking warranty status of device - */ - public function warrantyStatus( $serialNumber ) - { - if( !$this->isValidSerialNumber( $serialNumber )) { - exit('Invalid serial number: ' . $serialNumber); + + /** + * A shortcut for checking warranty status of device + */ + public function warrantyStatus($serialNumber) + { + if(!$this->isValidSerialNumber($serialNumber)) { + exit('Invalid serial number: ' . $serialNumber); + } + + $req = array('WarrantyStatus' => array( + 'unitDetail' => array('serialNumber' => $serialNumber) + )); + + return $this->request($req)->warrantyDetailInfo; + } - - $req = array('WarrantyStatus' => array( - 'unitDetail' => array('serialNumber' => $serialNumber) - )); - - return $this->request($req)->warrantyDetailInfo; - - } - - public function productModel( $serialNumber ) - { - if( !$this->isValidSerialNumber( $serialNumber )) { - exit('Invalid serial number: ' . $serialNumber); + + public function productModel($serialNumber) + { + if(!$this->isValidSerialNumber($serialNumber)) { + exit('Invalid serial number: ' . $serialNumber); + } + + $req = array( 'FetchProductModelRequest' => array( + 'userSession' => array( + 'userSessionId' => $this->session_id + ), + 'productModelRequest' => array( + 'serialNumber' => $serialNumber + ) + )); + + $response = $this->client + ->FetchProductModel($req) + ->FetchProductModelResponse; + + return $response->productModelResponse; } - - $req = array( 'FetchProductModelRequest' => array( - 'userSession' => array( 'userSessionId' => $this->session_id ), - 'productModelRequest' => array( 'serialNumber' => $serialNumber ) - )); - - $response = $this->client->FetchProductModel( $req )->FetchProductModelResponse; - return $response->productModelResponse; - - } - - - - public function onsiteDispatchDetail( $query ) - { - if( !self::looksLike( $query, 'dispatchId' )) { - exit( "Invalid dispatch ID: $query" ); - } - - $req = array( 'OnsiteDispatchDetailRequest' => array( - 'userSession' => array( 'userSessionId' => $this->session_id ), - 'lookupRequestData' => array( - 'dispatchId' => $query, - 'dispatchSentFromDate' => '', - 'dispatchSentToDate' => '' - ) - )); - - $response = $this->client->OnsiteDispatchDetail( $req )->OnsiteDispatchDetailResponse; - - return $response->onsiteDispatchDetails; - - } - - public function isValidSerialNumber( $serialNumber ) - { - $serialNumber = trim( $serialNumber ); - // SNs should never start with an S, but they're often coded into barcodes - // and since an "old- ormat" SN + S would still qualify as a "new format" SN, - // we strip it here and not in self::looksLike - $serialNumber = ltrim($serialNumber, 'sS'); - - return self::looksLike( $serialNumber, 'serialNumber' ); - } - - /** - * return the GSX user session ID - * I still keep the property private since it should not be modified - * outside the constructor - * @return string GSX session ID - */ - public function getSessionId() - { - return $this->session_id; - } - - /** - * Do the actual SOAP request - */ - private function request( $req ) - { - $result = FALSE; - - // split the request name and data - list( $r, $p ) = each( $req ); - // add session info - $p['userSession'] = array( 'userSessionId' => $this->session_id ); - $request = array( $r.'Request' => $p ); - print_r( $request ); - try { - $result = $this->client->$r( $request ); - $resp = "{$r}Response"; - return $result->$resp; + + public function onsiteDispatchDetail($query) + { + if(!self::looksLike($query, 'dispatchId')) { + exit( "Invalid dispatch ID: $query" ); + } + + $req = array('OnsiteDispatchDetailRequest' => array( + 'userSession' => array('userSessionId' => $this->session_id), + 'lookupRequestData' => array( + 'dispatchId' => $query, + 'dispatchSentFromDate' => '', + 'dispatchSentToDate' => '' + ) + )); + + $response = $this->client->OnsiteDispatchDetail($req) + ->OnsiteDispatchDetailResponse; + + return $response->onsiteDispatchDetails; + } - catch (SoapFault $e) { - print( $this->client->__getLastRequest() ); - trigger_error( $e->getMessage() ); + + public function isValidSerialNumber($serialNumber) + { + $serialNumber = trim( $serialNumber ); + // SNs should never start with an S, but they're often coded into barcodes + // and since an "old- ormat" SN + S would still qualify as a "new format" SN, + // we strip it here and not in self::looksLike + $serialNumber = ltrim($serialNumber, 'sS'); + + return self::looksLike($serialNumber, 'serialNumber'); + } - - return $result; - - } - /** - * Try to "categorise" a string - * About identifying serial numbers - before 2010, Apple had a logical - * serial number format, with structure, that you could id quite reliably. - * unfortunately, it's no longer the case - * @param string $string string to check - */ - static function looksLike( $string, $what = null ) - { - $result = false; - - $rex = array( - 'partNumber' => '/^([a-z]{1,2})?\d{3}\-\d{4}$/i', - 'serialNumber' => '/^[a-z0-9]{11,12}$/i', - 'eeeCode' => '/^[a-z0-9]{3,4}$/i', - 'returnOrder' => '/^7\d{9}$/', - 'repairNumber' => '/^\d{12}$/', - 'dispatchId' => '/^G\d{9}$/i', - ); + /** + * return the GSX user session ID + * I still keep the property private since it should not be modified + * outside the constructor + * @return string GSX session ID + */ + public function getSessionId() + { + return $this->session_id; + } - foreach ($rex as $k => $v) { - if (preg_match($v, $string)) { - $result = $k; - } + /** + * Do the actual SOAP request + */ + public function request($req) + { + $result = FALSE; + + // split the request name and data + list($r, $p) = each($req); + + // add session info + $p['userSession'] = array('userSessionId' => $this->session_id); + $request = array($r.'Request' => $p); + + try { + $result = $this->client->$r($request); + $resp = "{$r}Response"; + return $result->$resp; + } catch(SoapFault $e) { + throw new GsxException($e->getMessage(), $this->client->__getLastRequest()); + } + + return $result; + } + + /** + * Try to "categorise" a string + * About identifying serial numbers - before 2010, Apple had a logical + * serial number format, with structure, that you could id quite reliably. + * unfortunately, it's no longer the case + * @param string $string string to check + */ + static function looksLike($string, $what = null) + { + $result = false; + $rex = array( + 'partNumber' => '/^([a-z]{1,2})?\d{3}\-\d{4}$/i', + 'serialNumber' => '/^[a-z0-9]{11,12}$/i', + 'eeeCode' => '/^[A-Z0-9]{3,4}$/', // only match ALL-CAPS! + 'returnOrder' => '/^7\d{9}$/', + 'repairNumber' => '/^\d{12}$/', + 'dispatchId' => '/^G\d{9}$/i', + 'alternateDeviceId' => '/^\d{15}$/', + 'diagnosticEventNumber' => '/^\d{23}$/' + // 12715075303192012074604 + ); + + foreach ($rex as $k => $v) { + if (preg_match($v, $string)) { + $result = $k; + } + } - return ($what) ? ($result == $what) : $result; + return ($what) ? ($result == $what) : $result; } } -?> \ No newline at end of file +class GsxException extends Exception +{ + function __construct($message, $request = null) + { + $this->request = $request; + $this->message = $message; + } +} -- cgit v1.2.3