diff --git a/INSTALL.md b/INSTALL.md index 482cd779..1da0fff4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,22 +2,52 @@ To install, simply add the library to your project. Composer is the default installation tool for this library. If you do not use Composer for your project, you can still auto-load classes by including the file **includes/classes.php** in the page or function. -Before you use any commands, you need to create a **amazon-config.php** file with your account credentials. Start by copying the template provided (*amazon-config.default.php*) and renaming the file. +Before you use any commands, you need to create an **amazon-config.php** file with your account credentials. Start by copying the template provided (*amazon-config.default.php*) and renaming the file. -Only the first section of the config file needs to be filled out. If you are operating outside of the United States, be sure to change the Amazon Service URL as well. Everything after that point is pertaining to Amazon's API. Be sure to keep these values up to date, as Amazon could change them in a new API version release. +If you are operating outside of the United States, be sure to change the Amazon Service URL to the one matching your region. -You can also link the built-in logging system to your own logging system by putting the function name in the *$logfunction* parameter. +You can also link the built-in logging system to your own system by putting the logging function's name in the *$logfunction* parameter. -In the event that PHP does not have the correct permissions to create a file in the library's main directory, you will have to create the log file as "log.txt" and give all users permission to edit it. +The default location for the built-in log file is in the library's main directory. In the event that PHP does not have the correct permissions to create a file in there, you will have to create the log file as "log.txt" and give PHP permission to edit it. -## Example Usage +## Usage +All of the technical details required by the API are handled behind the scenes, +so users can easily build code for sending requests to Amazon +without having to jump hurdles such as parameter URL formatting and token management. The general work flow for using one of the objects is this: + 1. Create an object for the task you need to perform. 2. Load it up with parameters, depending on the object, using *set____* methods. 3. Submit the request to Amazon. The methods to do this are usually named *fetch____* or *submit____* and have no parameters. 4. Reference the returned data, whether as single values or in bulk, using *get____* methods. -5. Monitor the performance of the library using built-in logging system. +5. Monitor the performance of the library using the built-in logging system. Note that if you want to act on more than one Amazon store, you will need a separate object for each store. Also note that the objects perform best when they are not treated as reusable. Otherwise, you may end up grabbing old response data if a new request fails. + +## Examples +Here is an example of a function used to get all warehouse-fulfilled orders from Amazon updated in the past 24 hours: +```php +function getAmazonOrders() { + $amz = new AmazonOrderList("myStore"); //store name matches the array key in the config file + $amz->setLimits('Modified', "- 24 hours"); + $amz->setFulfillmentChannelFilter("MFN"); //no Amazon-fulfilled orders + $amz->setOrderStatusFilter( + array("Unshipped", "PartiallyShipped", "Canceled", "Unfulfillable") + ); //no shipped or pending + $amz->setUseToken(); //Amazon sends orders 100 at a time, but we want them all + $amz->fetchOrders(); + return $amz->getList(); +} +``` +This example shows a function used to send a previously-created XML feed to Amazon to update Inventory numbers: +```php +function sendInventoryFeed($feed) { + $amz=new AmazonFeed("myStore"); //store name matches the array key in the config file + $amz->setFeedType("_POST_INVENTORY_AVAILABILITY_DATA_"); //feed types listed in documentation + $amz->setFeedContent($feed); + $amz->submitFeed(); + return $amz->getResponse(); +} +``` diff --git a/README.md b/README.md index 5d42fd1e..00e3f164 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,38 @@ phpAmazonMWS ============ -A library to connect to Amazon's MWS web services in an object-oriented manner, with a focus on intuitive usage. \ No newline at end of file +A library to connect to Amazon's Merchant Web Services (MWS) in an object-oriented manner, with a focus on intuitive usage. + +This is __NOT__ for Amazon Web Services (AWS) - Cloud Computing Services. + + +## Example Usage +Here are a couple of examples of the library in use. +All of the technical details required by the API are handled behind the scenes, +so users can easily build code for sending requests to Amazon +without having to jump hurdles such as parameter URL formatting and token management. + +Here is an example of a function used to get all warehouse-fulfilled orders from Amazon updated in the past 24 hours: +```php +function getAmazonOrders() { + $amz = new AmazonOrderList("myStore"); //store name matches the array key in the config file + $amz->setLimits('Modified', "- 24 hours"); + $amz->setFulfillmentChannelFilter("MFN"); //no Amazon-fulfilled orders + $amz->setOrderStatusFilter( + array("Unshipped", "PartiallyShipped", "Canceled", "Unfulfillable") + ); //no shipped or pending + $amz->setUseToken(); //Amazon sends orders 100 at a time, but we want them all + $amz->fetchOrders(); + return $amz->getList(); +} +``` +This example shows a function used to send a previously-created XML feed to Amazon to update Inventory numbers: +```php +function sendInventoryFeed($feed) { + $amz=new AmazonFeed("myStore"); //store name matches the array key in the config file + $amz->setFeedType("_POST_INVENTORY_AVAILABILITY_DATA_"); //feed types listed in documentation + $amz->setFeedContent($feed); + $amz->submitFeed(); + return $amz->getResponse(); +} +``` diff --git a/environment.php b/environment.php index 01dd409e..e221ff3f 100644 --- a/environment.php +++ b/environment.php @@ -30,7 +30,7 @@ $AMAZON_VERSION_FEEDS = '2009-01-01'; $AMAZON_VERSION_INBOUND = '2010-10-01'; $AMAZON_VERSION_INVENTORY = '2010-10-01'; -$AMAZON_VERSION_ORDERS = '2011-01-01'; +$AMAZON_VERSION_ORDERS = '2013-09-01'; $AMAZON_VERSION_OUTBOUND = '2010-10-01'; $AMAZON_VERSION_PRODUCTS = '2011-10-01'; $AMAZON_VERSION_REPORTS = '2009-01-01'; diff --git a/examples/feed_examples.php b/examples/feed_examples.php new file mode 100644 index 00000000..21af4a30 --- /dev/null +++ b/examples/feed_examples.php @@ -0,0 +1,72 @@ +'; + foreach ($list as $feed) { + //these are arrays + echo 'Feed ID: '.$feed['FeedSubmissionId']; + echo '
Type: '.$feed['FeedType']; + echo '
Date Sent: '.$feed['SubmittedDate']; + echo '
Status: '.$feed['FeedProcessingStatus']; + echo '

'; + } +} + +/** + * This function will retrieve a list of all items with quantity that was adjusted within the past 24 hours. + * The entire list of items is returned, with each item contained in an array. + * Note that this does not relay whether or not the feed had any errors. + * To get this information, the feed's results must be retrieved. + */ +function getAmazonFeedStatus(){ + require('../includes/classes.php'); //autoload classes, not needed if composer is being used + try { + $amz=new AmazonFeedList("myStore"); + $amz->setTimeLimits('- 24 hours'); //limit time frame for feeds to any updated since the given time + $amz->setFeedStatuses(array("_SUBMITTED_", "_IN_PROGRESS_", "_DONE_")); //exclude cancelled feeds + $amz->fetchFeedSubmissions(); //this is what actually sends the request + return $amz->getFeedList(); + } catch (Exception $ex) { + echo 'There was a problem with the Amazon library. Error: '.$ex->getMessage(); + } +} + +/** + * This function will send a provided Inventory feed to Amazon. + * Amazon's response to the feed is returned as an array. + * This function is not actively used on this example page as a safety precaution. + */ +function sendInventoryFeed($feed) { + try { + $amz=new AmazonFeed("myStore"); //store name matches the array key in the config file + $amz->setFeedType("_POST_INVENTORY_AVAILABILITY_DATA_"); //feed types listed in documentation + $amz->setFeedContent($feed); //can be either XML or CSV data; a file upload method is available as well + $amz->submitFeed(); //this is what actually sends the request + return $amz->getResponse(); + } catch (Exception $ex) { + echo 'There was a problem with the Amazon library. Error: '.$ex->getMessage(); + } +} + +/** + * This function will get the processing results of a feed previously sent to Amazon and give the data. + * In order to do this, a feed ID is required. The response is in XML. + */ +function getFeedResult($feedId) { + try { + $amz=new AmazonFeedResult("myStore", $feedId); //feed ID can be quickly set by passing it to the constructor + $amz->setFeedId($feedId); //otherwise, it must be set this way + $amz->fetchFeedResult(); + return $amz->getRawFeed(); + } catch (Exception $ex) { + echo 'There was a problem with the Amazon library. Error: '.$ex->getMessage(); + } +} + + +?> diff --git a/examples/inventory_examples.php b/examples/inventory_examples.php new file mode 100644 index 00000000..472f4828 --- /dev/null +++ b/examples/inventory_examples.php @@ -0,0 +1,37 @@ +'; + foreach ($list as $item) { + //these are arrays + echo 'Item SKU: '.$item['SellerSKU']; + echo '
Condition: '.$item['Condition']; + echo '
In Stock: '.$item['InStockSupplyQuantity']; + echo '

'; + } +} + +/** + * This function will retrieve a list of all items with quantity that was adjusted within the past 24 hours. + * The entire list of items is returned, with each item contained in an array. + */ +function getAmazonSupply(){ + require('../includes/classes.php'); //autoload classes, not needed if composer is being used + try { + $obj = new AmazonInventoryList("myStore"); //store name matches the array key in the config file + $obj->setUseToken(); //tells the object to automatically use tokens right away + $obj->setStartTime("- 24 hours"); + $obj->fetchInventoryList(); //this is what actually sends the request + return $obj->getSupply(); + } catch (Exception $ex) { + echo 'There was a problem with the Amazon library. Error: '.$ex->getMessage(); + } +} + + +?> diff --git a/examples/order_examples.php b/examples/order_examples.php new file mode 100644 index 00000000..f4329fab --- /dev/null +++ b/examples/order_examples.php @@ -0,0 +1,45 @@ +'; + foreach ($list as $order) { + //these are AmazonOrder objects + echo 'Order Number: '.$order->getAmazonOrderId(); + echo '
Purchase Date: '.$order->getPurchaseDate(); + echo '
Status: '.$order->getOrderStatus(); + echo '
Customer: '.$order->getBuyerName(); + $address=$order->getShippingAddress(); //address is an array + echo '
City: '.$address['City']; + echo '

'; + } +} + +/** + * This function will retrieve a list of all unshipped MFN orders made within the past 24 hours. + * The entire list of orders is returned, with each order contained in an AmazonOrder object. + * Note that the items in the order are not included in the data. + * To get the order's items, the "fetchItems" method must be used by the specific order object. + */ +function getAmazonOrders() { + require('../includes/classes.php'); //autoload classes, not needed if composer is being used + try { + $amz = new AmazonOrderList("myStore"); //store name matches the array key in the config file + $amz->setLimits('Modified', "- 24 hours"); //accepts either specific timestamps or relative times + $amz->setFulfillmentChannelFilter("MFN"); //no Amazon-fulfilled orders + $amz->setOrderStatusFilter( + array("Unshipped", "PartiallyShipped", "Canceled", "Unfulfillable") + ); //no shipped or pending orders + $amz->setUseToken(); //tells the object to automatically use tokens right away + $amz->fetchOrders(); //this is what actually sends the request + return $amz->getList(); + } catch (Exception $ex) { + echo 'There was a problem with the Amazon library. Error: '.$ex->getMessage(); + } +} + +?> diff --git a/includes/classes/AmazonCore.php b/includes/classes/AmazonCore.php index c558a936..0e95959f 100644 --- a/includes/classes/AmazonCore.php +++ b/includes/classes/AmazonCore.php @@ -105,6 +105,7 @@ abstract class AmazonCore{ protected $mockIndex = 0; protected $logpath; protected $env; + protected $rawResponses = array(); /** * AmazonCore constructor sets up key information used in all Amazon requests. @@ -589,9 +590,49 @@ protected function sendRequest($url,$param){ $response = $this->fetchURL($url,$param); } + $this->rawResponses[]=$response; return $response; } + /** + * Gives the latest response data received from Amazon. + * Response arrays contain the following keys: + * + * @param int $i [optional]

If set, retrieves the specific response instead of the last one. + * If the index for the response is not used, FALSE will be returned.

+ * @return array associative array of HTTP response or FALSE if not set yet + */ + public function getLastResponse($i=NULL) { + if (!isset($i)) { + $i=count($this->rawResponses)-1; + } + if ($i >= 0 && isset($this->rawResponses[$i])) { + return $this->rawResponses[$i]; + } else { + return false; + } + } + + /** + * Gives all response code received from Amazon. + * @return array list of associative arrays of HTTP response or FALSE if not set yet + * @see getLastResponse + */ + public function getRawResponses() { + if (!empty($this->rawResponses)) { + return $this->rawResponses; + } else { + return false; + } + } + /** * Sleeps for the throttle time and records to the log. */ diff --git a/includes/classes/AmazonOrder.php b/includes/classes/AmazonOrder.php index 8a9e0118..adbdf463 100644 --- a/includes/classes/AmazonOrder.php +++ b/includes/classes/AmazonOrder.php @@ -218,6 +218,18 @@ protected function parseXML($xml){ if (isset($xml->ShipServiceLevelCategory)){ $d['ShipServiceLevelCategory'] = (string)$xml->ShipServiceLevelCategory; } + if (isset($xml->EarliestShipDate)){ + $d['EarliestShipDate'] = (string)$xml->EarliestShipDate; + } + if (isset($xml->LatestShipDate)){ + $d['LatestShipDate'] = (string)$xml->LatestShipDate; + } + if (isset($xml->EarliestDeliveryDate)){ + $d['EarliestDeliveryDate'] = (string)$xml->EarliestDeliveryDate; + } + if (isset($xml->LatestDeliveryDate)){ + $d['LatestDeliveryDate'] = (string)$xml->LatestDeliveryDate; + } $this->data = $d; } @@ -579,6 +591,66 @@ public function getShipServiceLevelCategory(){ } } + /** + * Returns the timestamp of the earliest shipping date. + * + * This method will return FALSE if the timestamp has not been set yet. + * @return string|boolean timestamp, or FALSE if timestamp not set yet + */ + public function getEarliestShipDate(){ + if (isset($this->data['EarliestShipDate'])){ + return $this->data['EarliestShipDate']; + } else { + return false; + } + } + + /** + * Returns the timestamp of the latest shipping date. + * + * Note that this could be set to midnight of the day after the last date, + * so the timestamp "2013-09-025T00:00:00Z" indicates the last day is the 24th and not the 25th. + * This method will return FALSE if the timestamp has not been set yet. + * @return string|boolean timestamp, or FALSE if timestamp not set yet + */ + public function getLatestShipDate(){ + if (isset($this->data['LatestShipDate'])){ + return $this->data['LatestShipDate']; + } else { + return false; + } + } + + /** + * Returns the timestamp of the estimated earliest delivery date. + * + * This method will return FALSE if the timestamp has not been set yet. + * @return string|boolean timestamp, or FALSE if timestamp not set yet + */ + public function getEarliestDeliveryDate(){ + if (isset($this->data['EarliestDeliveryDate'])){ + return $this->data['EarliestDeliveryDate']; + } else { + return false; + } + } + + /** + * Returns the timestamp of the estimated latest delivery date. + * + * Note that this could be set to midnight of the day after the last date, + * so the timestamp "2013-09-025T00:00:00Z" indicates the last day is the 24th and not the 25th. + * This method will return FALSE if the timestamp has not been set yet. + * @return string|boolean timestamp, or FALSE if timestamp not set yet + */ + public function getLatestDeliveryDate(){ + if (isset($this->data['LatestDeliveryDate'])){ + return $this->data['LatestDeliveryDate']; + } else { + return false; + } + } + /** * Returns the ratio of shipped items to unshipped items. * diff --git a/includes/classes/AmazonOrderList.php b/includes/classes/AmazonOrderList.php index 67e65399..b4eba584 100644 --- a/includes/classes/AmazonOrderList.php +++ b/includes/classes/AmazonOrderList.php @@ -52,7 +52,7 @@ public function __construct($s, $mock = false, $m = null, $config = null){ throw new Exception('Config file does not exist!'); } - if(array_key_exists('marketplaceId', $store[$s])){ + if(isset($store[$s]) && array_key_exists('marketplaceId', $store[$s])){ $this->options['MarketplaceId.Id.1'] = $store[$s]['marketplaceId']; } else { $this->log("Marketplace ID is missing",'Urgent'); diff --git a/includes/classes/AmazonProductsCore.php b/includes/classes/AmazonProductsCore.php index beb68ac2..b8f4fc32 100644 --- a/includes/classes/AmazonProductsCore.php +++ b/includes/classes/AmazonProductsCore.php @@ -54,7 +54,7 @@ public function __construct($s, $mock = false, $m = null, $config = null){ } - if(array_key_exists('marketplaceId', $store[$s])){ + if(isset($store[$s]) && array_key_exists('marketplaceId', $store[$s])){ $this->options['MarketplaceId'] = $store[$s]['marketplaceId']; } else { $this->log("Marketplace ID is missing",'Urgent');