From 408ffed131ec9dc8a2b6d077af87b01c532031ab Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Mon, 16 Feb 2015 17:50:58 -0800 Subject: [PATCH 01/18] BIG-15160: updates to public api client - remove single merged file (bigcommerce.php) and supporting build script (/bin) - add convenience method getConnection() to client - fix issues with curl connections that were causing timeouts when making multiple requests with the same connection --- bin/package | 15 --------------- src/Bigcommerce/Api/Client.php | 21 ++++++++++++++++++++- src/Bigcommerce/Api/Connection.php | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 17 deletions(-) delete mode 100755 bin/package diff --git a/bin/package b/bin/package deleted file mode 100755 index 66685312..00000000 --- a/bin/package +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env php -masterfile = 'src/Bigcommerce/Api.php'; -$pkg->outfile = 'bigcommerce.php'; -$pkg->mergeScripts = true; -$pkg->comments = false; -$pkg->run(); - -// clean up statement/parser error from the JuggleCode output -file_put_contents('bigcommerce.php', str_replace('};', '}', file_get_contents('bigcommerce.php'))); - diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 98b506af..f669b739 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -73,6 +73,15 @@ public static function useXml() self::connection()->useXml(); } + /** + * Return JSON objects from the API instead of XML Strings. + * This is the default behavior. + */ + public static function useJson() + { + self::connection()->useXml(false); + } + /** * Switch SSL certificate verification on requests. */ @@ -133,8 +142,18 @@ private static function connection() * @param Connection $connection The connection to use */ public static function setConnection(Connection $connection = null) + { + self::$connection = $connection; + } + + /** + * Convenience method to return instance of the connection + * + * @return Connection + */ + public static function getConnection() { - self::$connection = $connection; + return self::connection(); } /** diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 3b0025b3..5cc793ff 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -98,7 +98,8 @@ public function __construct() * Controls whether requests and responses should be treated * as XML. Defaults to false (using JSON). */ - public function useXml($option=true) { + public function useXml($option=true) + { $this->useXml = $option; } @@ -297,6 +298,8 @@ public function get($url, $query=false) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_PUT, false); curl_setopt($this->curl, CURLOPT_HTTPGET, true); curl_exec($this->curl); @@ -319,6 +322,8 @@ public function post($url, $body) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($this->curl, CURLOPT_URL, $url); curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); curl_exec($this->curl); @@ -364,9 +369,14 @@ public function put($url, $body) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_POST, false); curl_setopt($this->curl, CURLOPT_PUT, true); curl_exec($this->curl); + fclose($handle); + curl_setopt($this->curl, CURLOPT_INFILE, STDIN); + return $this->handleResponse(); } @@ -377,6 +387,9 @@ public function delete($url) { $this->initializeRequest(); + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_POST, false); curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($this->curl, CURLOPT_URL, $url); curl_exec($this->curl); From 713a73c2c40482527c2ab34f153e36839901c6aa Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Mon, 16 Feb 2015 18:08:26 -0800 Subject: [PATCH 02/18] BIG-15160: standardize spacing --- src/Bigcommerce/Api/Client.php | 1810 ++++++++--------- src/Bigcommerce/Api/ClientError.php | 11 +- src/Bigcommerce/Api/Connection.php | 921 +++++---- src/Bigcommerce/Api/Error.php | 18 +- src/Bigcommerce/Api/Filter.php | 83 +- src/Bigcommerce/Api/Resource.php | 201 +- src/Bigcommerce/Api/Resources/Brand.php | 38 +- src/Bigcommerce/Api/Resources/Category.php | 42 +- src/Bigcommerce/Api/Resources/Coupon.php | 32 +- src/Bigcommerce/Api/Resources/Customer.php | 56 +- src/Bigcommerce/Api/Resources/Option.php | 12 +- src/Bigcommerce/Api/Resources/OptionSet.php | 48 +- .../Api/Resources/OptionSetOption.php | 52 +- src/Bigcommerce/Api/Resources/OptionValue.php | 60 +- src/Bigcommerce/Api/Resources/Order.php | 65 +- src/Bigcommerce/Api/Resources/Product.php | 208 +- .../Api/Resources/ProductCustomField.php | 50 +- .../Api/Resources/ProductImage.php | 48 +- .../Api/Resources/ProductOption.php | 11 +- src/Bigcommerce/Api/Resources/Rule.php | 64 +- .../Api/Resources/RuleCondition.php | 43 +- src/Bigcommerce/Api/Resources/Shipment.php | 32 +- src/Bigcommerce/Api/Resources/Sku.php | 62 +- src/Bigcommerce/Api/Resources/SkuOption.php | 65 +- 24 files changed, 1992 insertions(+), 2040 deletions(-) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index f669b739..6848df05 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -9,919 +9,905 @@ */ class Client { - static private $store_url; - static private $username; - static private $api_key; - static private $connection; - static private $resource; - static private $path_prefix = '/api/v2'; - - /** - * Full URL path to the configured store API. - * - * @var string - */ - static public $api_path; - - /** - * Configure the API client with the required credentials. - * - * Requires a settings array to be passed in with the following keys: - * - * - store_url - * - username - * - api_key - * - * @param array $settings - */ - public static function configure($settings) - { - if (!isset($settings['store_url'])) { - throw new Exception("'store_url' must be provided"); - } - - if (!isset($settings['username'])) { - throw new Exception("'username' must be provided"); - } - - if (!isset($settings['api_key'])) { - throw new Exception("'api_key' must be provided"); - } - - self::$username = $settings['username']; - self::$api_key = $settings['api_key']; - self::$store_url = rtrim($settings['store_url'], '/'); - self::$api_path = self::$store_url . self::$path_prefix; - self::$connection = false; - } - - /** - * Configure the API client to throw exceptions when HTTP errors occur. - * - * Note that network faults will always cause an exception to be thrown. - */ - public static function failOnError($option=true) - { - self::connection()->failOnError($option); - } - - /** - * Return XML strings from the API instead of building objects. - */ - public static function useXml() - { - self::connection()->useXml(); - } - - /** - * Return JSON objects from the API instead of XML Strings. - * This is the default behavior. - */ - public static function useJson() - { - self::connection()->useXml(false); - } - - /** - * Switch SSL certificate verification on requests. - */ - public static function verifyPeer($option=false) - { - self::connection()->verifyPeer($option); - } - - /** - * Set which cipher to use during SSL requests. - */ - public static function setCipher($cipher='rsa_rc4_128_sha') - { - self::connection()->setCipher($cipher); - } - - /** - * Connect to the internet through a proxy server. - * - * @param string $host host server - * @param string $port port - */ - public static function useProxy($host, $port=false) - { - self::connection()->useProxy($host, $port); - } - - /** - * Get error message returned from the last API request if - * failOnError is false (default). - * - * @return string - */ - public static function getLastError() - { - return self::connection()->getLastError(); - } - - /** - * Get an instance of the HTTP connection object. Initializes - * the connection if it is not already active. - * - * @return Connection - */ - private static function connection() - { - if (!self::$connection) { - self::$connection = new Connection(); - self::$connection->authenticate(self::$username, self::$api_key); - } - - return self::$connection; - } - - /** - * Set the HTTP connection object. DANGER: This can screw up your Client! - * - * @param Connection $connection The connection to use - */ - public static function setConnection(Connection $connection = null) - { - self::$connection = $connection; - } - - /** - * Convenience method to return instance of the connection - * - * @return Connection - */ - public static function getConnection() - { - return self::connection(); - } - - /** - * Get a collection result from the specified endpoint. - * - * @param string $path api endpoint - * @param string $resource resource class to map individual items - * @param array $fields additional key=>value properties to apply to the object - * @return mixed array|string mapped collection or XML string if useXml is true - */ - public static function getCollection($path, $resource='Resource') - { - $response = self::connection()->get(self::$api_path . $path); - - return self::mapCollection($resource, $response); - } - - /** - * Get a resource entity from the specified endpoint. - * - * @param string $path api endpoint - * @param string $resource resource class to map individual items - * @return mixed Resource|string resource object or XML string if useXml is true - */ - public static function getResource($path, $resource='Resource') - { - $response = self::connection()->get(self::$api_path . $path); - - return self::mapResource($resource, $response); - } - - /** - * Get a count value from the specified endpoint. - * - * @param string $path api endpoint - * @return mixed int|string count value or XML string if useXml is true - */ - public static function getCount($path) - { - $response = self::connection()->get(self::$api_path . $path); - - if ($response == false || is_string($response)) return $response; - - return $response->count; - } - - /** - * Send a post request to create a resource on the specified collection. - * - * @param string $path api endpoint - * @param mixed $object object or XML string to create - */ - public static function createResource($path, $object) - { - if (is_array($object)) $object = (object)$object; - - return self::connection()->post(self::$api_path . $path, $object); - } - - /** - * Send a put request to update the specified resource. - * - * @param string $path api endpoint - * @param mixed $object object or XML string to update - */ - public static function updateResource($path, $object) - { - if (is_array($object)) $object = (object)$object; - - return self::connection()->put(self::$api_path . $path, $object); - } - - /** - * Send a delete request to remove the specified resource. - * - * @param string $path api endpoint - */ - public static function deleteResource($path) - { - return self::connection()->delete(self::$api_path . $path); - } - - /** - * Internal method to wrap items in a collection to resource classes. - * - * @param string $resource name of the resource class - * @param array $object object collection - * @return array - */ - private static function mapCollection($resource, $object) - { - if ($object == false || is_string($object)) return $object; - - $baseResource = __NAMESPACE__ . '\\' . $resource; - self::$resource = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; - - return array_map(array('self', 'mapCollectionObject'), $object); - } - - /** - * Callback for mapping collection objects resource classes. - * - * @param stdClass $object - * @return Resource - */ - private static function mapCollectionObject($object) - { - $class = self::$resource; - - return new $class($object); - } - - /** - * Map a single object to a resource class. - * - * @param string $resource name of the resource class - * @param stdClass $object - * @return Resource - */ - private static function mapResource($resource, $object) - { - if ($object == false || is_string($object)) return $object; - - $baseResource = __NAMESPACE__ . '\\' . $resource; - $class = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; - - return new $class($object); - } - - /** - * Map object representing a count to an integer value. - * - * @param stdClass $object - * @return int - */ - private static function mapCount($object) - { - if ($object == false || is_string($object)) return $object; - - return $object->count; - } - - /** - * Pings the time endpoint to test the connection to a store. - * - * @return DateTime - */ - public static function getTime() - { - $response = self::connection()->get(self::$api_path . '/time'); - - if ($response == false || is_string($response)) return $response; - - return new \DateTime("@{$response->time}"); - } - - /** - * Returns the default collection of products. - * - * @param array $filter - * @return mixed array|string list of products or XML string if useXml is true - */ - public static function getProducts($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/products' . $filter->toQuery(), 'Product'); - } - - /** - * Gets collection of images for a product. - * - * @param int $id product id - * @return mixed array|string list of products or XML string if useXml is true - */ - public static function getProductImages($id) - { - return self::getCollection('/products/' . $id . '/images/', 'ProductImage'); - } - - /** - * Gets collection of custom fields for a product. - * - * @param int $id product ID - * @return mixed array|string list of products or XML string if useXml is true - */ - public static function getProductCustomFields($id) - { - return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField'); - } - - /** - * Returns a single custom field by given id - * @param int $product_id product id - * @param int $id custom field id - * @return ProductCustomField|bool Returns ProductCustomField if exists, false if not exists - */ - public static function getProductCustomField($product_id, $id) - { - return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField'); - } - - /** - * Create a new custom field for a given product. - * - * @param int $product_id product id - * @param int $id custom field id - * @param mixed $object fields to create - * @return Object Object with `id`, `product_id`, `name` and `text` keys - */ - public static function createProductCustomField($product_id, $object) - { - return self::createResource('/products/' . $product_id . '/customfields', $object); - } - - /** - * Update the given custom field. - * - * @param int $product_id product id - * @param int $id custom field id - * @param mixed $object custom field to update - */ - public static function updateProductCustomField($product_id, $id, $object) - { - return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object); - } - - /** - * Delete the given custom field. - * - * @param int $product_id product id - * @param int $id custom field id - */ - public static function deleteProductCustomField($product_id, $id) - { - return self::deleteResource('/products/' . $product_id . '/customfields/' . $id); - } - - /** - * Returns the total number of products in the collection. - * - * @param array $filter - * @return mixed int|string number of products or XML string if useXml is true - */ - public static function getProductsCount($filter=false) - { - $filter = Filter::create($filter); - return self::getCount('/products/count' . $filter->toQuery()); - } - - /** - * Returns a single product resource by the given id. - * - * @param int $id product id - * @return Product|string - */ - public static function getProduct($id) - { - return self::getResource('/products/' . $id, 'Product'); - } - - /** - * Create a new product. - * - * @param mixed $object fields to create - */ - public static function createProduct($object) - { - return self::createResource('/products', $object); - } - - /** - * Update the given product. - * - * @param int $id product id - * @param mixed $object fields to update - */ - public static function updateProduct($id, $object) - { - return self::updateResource('/products/' . $id, $object); - } - - /** - * Delete the given product. - * - * @param int $id product id - */ - public static function deleteProduct($id) - { - return self::deleteResource('/products/' . $id); - } - - /** - * Return the collection of options. - * - * @param array $filter - * @return array - */ - public static function getOptions($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/options' . $filter->toQuery(), 'Option'); - } - - /** create options **/ - public static function createOptions($object) - { - return self::createResource('/options', $object); - } - - - /** - * Return the number of options in the collection - * - * @return int - */ - public static function getOptionsCount() - { - return self::getCount('/options/count'); - } - - /** - * Return a single option by given id. - * - * @param int $id option id - * @return Option - */ - public static function getOption($id) - { - return self::getResource('/options/' . $id, 'Option'); - } - - - - /** - * Delete the given option. - * - * @param int $id option id - */ - public static function deleteOption($id) - { - return self::deleteResource('/options/' . $id); - } - - /** - * Return a single value for an option. - * - * @param int $option_id option id - * @param int $id value id - * @return OptionValue - */ - public static function getOptionValue($option_id, $id) - { - return self::getResource('/options/' . $option_id . '/values/' . $id, 'OptionValue'); - } - - /** - * Return the collection of all option values. - * - * @param mixed $filter - * @return array - */ - public static function getOptionValues($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/options/values' . $filter->toQuery(), 'OptionValue'); - } - - /** - * The collection of categories. - * - * @param mixed $filter - * @return array - */ - public static function getCategories($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/categories' . $filter->toQuery(), 'Category'); - } - - /** - * The number of categories in the collection. - * - * @param mixed $filter - * @return int - */ - public static function getCategoriesCount($filter=false) - { - $filter = Filter::create($filter); - return self::getCount('/categories/count' . $filter->toQuery()); - } - - /** - * A single category by given id. - * - * @param int $id category id - * @return Category - */ - public static function getCategory($id) - { - return self::getResource('/categories/' . $id, 'Category'); - } - - /** - * Create a new category from the given data. - * - * @param mixed $object - */ - public static function createCategory($object) - { - return self::createResource('/categories', $object); - } - - /** - * Update the given category. - * - * @param int $id category id - * @param mixed $object - */ - public static function updateCategory($id, $object) - { - return self::updateResource('/categories/' . $id, $object); - } - - /** - * Delete the given category. - * - * @param int $id category id - */ - public static function deleteCategory($id) - { - return self::deleteResource('/categories/' . $id); - } - - /** - * The collection of brands. - * - * @param mixed $filter - * @return array - */ - public static function getBrands($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/brands' . $filter->toQuery(), 'Brand'); - } - - /** - * The total number of brands in the collection. - * - * @param mixed $filter - * @return int - */ - public static function getBrandsCount($filter=false) - { - $filter = Filter::create($filter); - return self::getCount('/brands/count' . $filter->toQuery()); - } - - /** - * A single brand by given id. - * - * @param int $id brand id - * @return Brand - */ - public static function getBrand($id) - { - return self::getResource('/brands/' . $id, 'Brand'); - } - - /** - * Create a new brand from the given data. - * - * @param mixed $object - */ - public static function createBrand($object) - { - return self::createResource('/brands', $object); - } - - /** - * Update the given brand. - * - * @param int $id brand id - * @param mixed $object - */ - public static function updateBrand($id, $object) - { - return self::updateResource('/brands/' . $id, $object); - } - - /** - * Delete the given brand. - * - * @param int $id brand id - */ - public static function deleteBrand($id) - { - return self::deleteResource('/brands/' . $id); - } - - /** - * The collection of orders. - * - * @param mixed $filter - * @return array - */ - public static function getOrders($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/orders' . $filter->toQuery(), 'Order'); - } - - /** - * The number of orders in the collection. - * - * @return int - */ - public static function getOrdersCount() - { - return self::getCount('/orders/count'); - } - - /** - * A single order. - * - * @param int $id order id - * @return Order - */ - public static function getOrder($id) - { - return self::getResource('/orders/' . $id, 'Order'); - } - - /** - * Delete the given order (unlike in the Control Panel, this will permanently - * delete the order). - * - * @param int $id order id - */ - public static function deleteOrder($id) - { - return self::deleteResource('/orders/' . $id); - } - - /** - * Create an order - **/ - - public static function createOrder($object) - { - return self::createResource('/orders', $object); - } - - /** - * The list of customers. - * - * @param mixed $filter - * @return array - */ - public static function getCustomers($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/customers' . $filter->toQuery(), 'Customer'); - } - - /** - * The total number of customers in the collection. - * - * @param mixed $filter - * @return int - */ - public static function getCustomersCount($filter=false) - { - $filter = Filter::create($filter); - return self::getCount('/customers/count' . $filter->toQuery()); - } - - /** - * Bulk delete customers. - * - * @param mixed $filter - * @return array - */ - public static function deleteCustomers($filter=false) - { - $filter = Filter::create($filter); - return self::deleteResource('/customers' . $filter->toQuery()); - } - - /** - * A single customer by given id. - * - * @param int $id customer id - * @return Customer - */ - public static function getCustomer($id) - { - return self::getResource('/customers/' . $id, 'Customer'); - } - - /** - * Create a new customer from the given data. - * - * @param mixed $object - */ - public static function createCustomer($object) - { - return self::createResource('/customers', $object); - } - - /** - * Update the given customer. - * - * @param int $id customer id - * @param mixed $object - */ - public static function updateCustomer($id, $object) - { - return self::updateResource('/customers/' . $id, $object); - } - - /** - * Delete the given customer. - * - * @param int $id customer id - */ - public static function deleteCustomer($id) - { - return self::deleteResource('/customers/' . $id); - } - - /** - * A list of addresses belonging to the given customer. - * - * @param int $id customer id - * @return array - */ - public static function getCustomerAddresses($id) - { - return self::getCollection('/customers/' . $id . '/addresses', 'Address'); - } - - /** - * Returns the collection of option sets. - * - * @param array $filter - * @return array - */ - public static function getOptionSets($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/optionsets' . $filter->toQuery(), 'OptionSet'); - } - - /** create optionsets **/ - public static function createOptionsets($object) - { - return self::createResource('/optionsets', $object); - } - - /** connect optionsets options **/ - public static function createOptionsets_Options($object, $id) - { - return self::createResource('/optionsets/'.$id.'/options', $object); - } - - - /** - * Returns the total number of option sets in the collection. - * - * @return int - */ - public static function getOptionSetsCount() - { - return self::getCount('/optionsets/count'); - } - - /** - * A single option set by given id. - * - * @param int $id option set id - * @return OptionSet - */ - public static function getOptionSet($id) - { - return self::getResource('/optionsets/' . $id, 'OptionSet'); - } - - /** - * Status codes used to represent the state of an order. - * - * @return array - */ - public static function getOrderStatuses() - { - return self::getCollection('/orderstatuses', 'OrderStatus'); - } - - /* product skus */ - public static function getSkus($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/products/skus' . $filter->toQuery(), 'Sku'); - } - - public static function createSku($object) - { - return self::createResource('/product/skus', $object); - } - - public static function updateSku($id, $object) - { - return self::updateResource('/product/skus/' . $id, $object); - } - - - /* coupons */ - public static function getCoupons($filter=false) - { - $filter = Filter::create($filter); - return self::getCollection('/coupons' . $filter->toQuery(), 'Coupon'); - } - - public static function createCoupon($object) - { - return self::createResource('/coupons', $object); - } - - public static function updateCoupon($id, $object) - { - return self::updateResource('/coupons/' . $id, $object); - } - - /** - * The request logs with usage history statistics. - */ - public static function getRequestLogs() - { - return self::getCollection('/requestlogs', 'RequestLog'); - } - - public static function getStore() - { - $response = self::connection()->get(self::$api_path . '/store'); - return $response; - } - - /** - * The number of requests remaining at the current time. Based on the - * last request that was fetched within the current script. If no - * requests have been made, pings the time endpoint to get the value. - * - * @return int - */ - public static function getRequestsRemaining() - { - $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); - - if (!$limit) { - $result = self::getTime(); - - if (!$result) return false; - - $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); - } - - return intval($limit); - } + static private $store_url; + static private $username; + static private $api_key; + static private $connection; + static private $resource; + static private $path_prefix = '/api/v2'; + /** + * Full URL path to the configured store API. + * + * @var string + */ + static public $api_path; + + /** + * Configure the API client with the required credentials. + * + * Requires a settings array to be passed in with the following keys: + * + * - store_url + * - username + * - api_key + * + * @param array $settings + */ + public static function configure($settings) + { + if (!isset($settings['store_url'])) { + throw new Exception("'store_url' must be provided"); + } + + if (!isset($settings['username'])) { + throw new Exception("'username' must be provided"); + } + + if (!isset($settings['api_key'])) { + throw new Exception("'api_key' must be provided"); + } + + self::$username = $settings['username']; + self::$api_key = $settings['api_key']; + self::$store_url = rtrim($settings['store_url'], '/'); + self::$api_path = self::$store_url . self::$path_prefix; + self::$connection = false; + } + + /** + * Configure the API client to throw exceptions when HTTP errors occur. + * + * Note that network faults will always cause an exception to be thrown. + */ + public static function failOnError($option = true) + { + self::connection()->failOnError($option); + } + + /** + * Return XML strings from the API instead of building objects. + */ + public static function useXml() + { + self::connection()->useXml(); + } + + /** + * Return JSON objects from the API instead of XML Strings. + * This is the default behavior. + */ + public static function useJson() + { + self::connection()->useXml(false); + } + + /** + * Switch SSL certificate verification on requests. + */ + public static function verifyPeer($option = false) + { + self::connection()->verifyPeer($option); + } + + /** + * Set which cipher to use during SSL requests. + */ + public static function setCipher($cipher = 'rsa_rc4_128_sha') + { + self::connection()->setCipher($cipher); + } + + /** + * Connect to the internet through a proxy server. + * + * @param string $host host server + * @param string $port port + */ + public static function useProxy($host, $port = false) + { + self::connection()->useProxy($host, $port); + } + + /** + * Get error message returned from the last API request if + * failOnError is false (default). + * + * @return string + */ + public static function getLastError() + { + return self::connection()->getLastError(); + } + + /** + * Get an instance of the HTTP connection object. Initializes + * the connection if it is not already active. + * + * @return Connection + */ + private static function connection() + { + if (!self::$connection) { + self::$connection = new Connection(); + self::$connection->authenticate(self::$username, self::$api_key); + } + + return self::$connection; + } + + /** + * Convenience method to return instance of the connection + * + * @return Connection + */ + public static function getConnection() + { + return self::connection(); + } + /** + * Get a collection result from the specified endpoint. + * + * @param string $path api endpoint + * @param string $resource resource class to map individual items + * @param array $fields additional key=>value properties to apply to the object + * @return mixed array|string mapped collection or XML string if useXml is true + */ + public static function getCollection($path, $resource = 'Resource') + { + $response = self::connection()->get(self::$api_path . $path); + + return self::mapCollection($resource, $response); + } + + /** + * Get a resource entity from the specified endpoint. + * + * @param string $path api endpoint + * @param string $resource resource class to map individual items + * @return mixed Resource|string resource object or XML string if useXml is true + */ + public static function getResource($path, $resource = 'Resource') + { + $response = self::connection()->get(self::$api_path . $path); + + return self::mapResource($resource, $response); + } + + /** + * Get a count value from the specified endpoint. + * + * @param string $path api endpoint + * @return mixed int|string count value or XML string if useXml is true + */ + public static function getCount($path) + { + $response = self::connection()->get(self::$api_path . $path); + + if ($response == false || is_string($response)) return $response; + + return $response->count; + } + + /** + * Send a post request to create a resource on the specified collection. + * + * @param string $path api endpoint + * @param mixed $object object or XML string to create + */ + public static function createResource($path, $object) + { + if (is_array($object)) $object = (object)$object; + + return self::connection()->post(self::$api_path . $path, $object); + } + + /** + * Send a put request to update the specified resource. + * + * @param string $path api endpoint + * @param mixed $object object or XML string to update + */ + public static function updateResource($path, $object) + { + if (is_array($object)) $object = (object)$object; + + return self::connection()->put(self::$api_path . $path, $object); + } + + /** + * Send a delete request to remove the specified resource. + * + * @param string $path api endpoint + */ + public static function deleteResource($path) + { + return self::connection()->delete(self::$api_path . $path); + } + + /** + * Internal method to wrap items in a collection to resource classes. + * + * @param string $resource name of the resource class + * @param array $object object collection + * @return array + */ + private static function mapCollection($resource, $object) + { + if ($object == false || is_string($object)) return $object; + $baseResource = __NAMESPACE__ . '\\' . $resource; + self::$resource = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; + + return array_map(array('self', 'mapCollectionObject'), $object); + } + + /** + * Callback for mapping collection objects resource classes. + * + * @param stdClass $object + * @return Resource + */ + private static function mapCollectionObject($object) + { + $class = self::$resource; + + return new $class($object); + } + + /** + * Map a single object to a resource class. + * + * @param string $resource name of the resource class + * @param stdClass $object + * @return Resource + */ + private static function mapResource($resource, $object) + { + if ($object == false || is_string($object)) return $object; + + $baseResource = __NAMESPACE__ . '\\' . $resource; + $class = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; + + return new $class($object); + } + + /** + * Map object representing a count to an integer value. + * + * @param stdClass $object + * @return int + */ + private static function mapCount($object) + { + if ($object == false || is_string($object)) return $object; + + return $object->count; + } + + /** + * Pings the time endpoint to test the connection to a store. + * + * @return DateTime + */ + public static function getTime() + { + $response = self::connection()->get(self::$api_path . '/time'); + + if ($response == false || is_string($response)) return $response; + + return new \DateTime("@{$response->time}"); + } + + /** + * Returns the default collection of products. + * + * @param array $filter + * @return mixed array|string list of products or XML string if useXml is true + */ + public static function getProducts($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/products' . $filter->toQuery(), 'Product'); + } + + /** + * Gets collection of images for a product. + * + * @param int $id product id + * @return mixed array|string list of products or XML string if useXml is true + */ + public static function getProductImages($id) + { + return self::getResource('/products/' . $id . '/images/', 'ProductImage'); + } + + /** + * Gets collection of custom fields for a product. + * + * @param int $id product ID + * @return mixed array|string list of products or XML string if useXml is true + */ + public static function getProductCustomFields($id) + { + return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField'); + } + + /** + * Returns a single custom field by given id + * @param int $product_id product id + * @param int $id custom field id + * @return ProductCustomField|bool Returns ProductCustomField if exists, false if not exists + */ + public static function getProductCustomField($product_id, $id) + { + return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField'); + } + + /** + * Create a new custom field for a given product. + * + * @param int $product_id product id + * @param int $id custom field id + * @param mixed $object fields to create + * @return Object Object with `id`, `product_id`, `name` and `text` keys + */ + public static function createProductCustomField($product_id, $object) + { + return self::createResource('/products/' . $product_id . '/customfields', $object); + } + + /** + * Update the given custom field. + * + * @param int $product_id product id + * @param int $id custom field id + * @param mixed $object custom field to update + */ + public static function updateProductCustomField($product_id, $id, $object) + { + return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object); + } + + /** + * Delete the given custom field. + * + * @param int $product_id product id + * @param int $id custom field id + */ + public static function deleteProductCustomField($product_id, $id) + { + return self::deleteResource('/products/' . $product_id . '/customfields/' . $id); + } + + /** + * Returns the total number of products in the collection. + * + * @param array $filter + * @return mixed int|string number of products or XML string if useXml is true + */ + public static function getProductsCount($filter = false) + { + $filter = Filter::create($filter); + return self::getCount('/products/count' . $filter->toQuery()); + } + + /** + * Returns a single product resource by the given id. + * + * @param int $id product id + * @return Product|string + */ + public static function getProduct($id) + { + return self::getResource('/products/' . $id, 'Product'); + } + + /** + * Create a new product. + * + * @param mixed $object fields to create + */ + public static function createProduct($object) + { + return self::createResource('/products', $object); + } + + /** + * Update the given product. + * + * @param int $id product id + * @param mixed $object fields to update + */ + public static function updateProduct($id, $object) + { + return self::updateResource('/products/' . $id, $object); + } + + /** + * Delete the given product. + * + * @param int $id product id + */ + public static function deleteProduct($id) + { + return self::deleteResource('/products/' . $id); + } + + /** + * Return the collection of options. + * + * @param array $filter + * @return array + */ + public static function getOptions($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/options' . $filter->toQuery(), 'Option'); + } + + /** create options **/ + public static function createOptions($object) + { + return self::createResource('/options', $object); + } + + + /** + * Return the number of options in the collection + * + * @return int + */ + public static function getOptionsCount() + { + return self::getCount('/options/count'); + } + + /** + * Return a single option by given id. + * + * @param int $id option id + * @return Option + */ + public static function getOption($id) + { + return self::getResource('/options/' . $id, 'Option'); + } + + + /** + * Delete the given option. + * + * @param int $id option id + */ + public static function deleteOption($id) + { + return self::deleteResource('/options/' . $id); + } + + /** + * Return a single value for an option. + * + * @param int $option_id option id + * @param int $id value id + * @return OptionValue + */ + public static function getOptionValue($option_id, $id) + { + return self::getResource('/options/' . $option_id . '/values/' . $id, 'OptionValue'); + } + + /** + * Return the collection of all option values. + * + * @param mixed $filter + * @return array + */ + public static function getOptionValues($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/options/values' . $filter->toQuery(), 'OptionValue'); + } + + /** + * The collection of categories. + * + * @param mixed $filter + * @return array + */ + public static function getCategories($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/categories' . $filter->toQuery(), 'Category'); + } + + /** + * The number of categories in the collection. + * + * @param mixed $filter + * @return int + */ + public static function getCategoriesCount($filter = false) + { + $filter = Filter::create($filter); + return self::getCount('/categories/count' . $filter->toQuery()); + } + + /** + * A single category by given id. + * + * @param int $id category id + * @return Category + */ + public static function getCategory($id) + { + return self::getResource('/categories/' . $id, 'Category'); + } + + /** + * Create a new category from the given data. + * + * @param mixed $object + */ + public static function createCategory($object) + { + return self::createResource('/categories/', $object); + } + + /** + * Update the given category. + * + * @param int $id category id + * @param mixed $object + */ + public static function updateCategory($id, $object) + { + return self::updateResource('/categories/' . $id, $object); + } + + /** + * Delete the given category. + * + * @param int $id category id + */ + public static function deleteCategory($id) + { + return self::deleteResource('/categories/' . $id); + } + + /** + * The collection of brands. + * + * @param mixed $filter + * @return array + */ + public static function getBrands($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/brands' . $filter->toQuery(), 'Brand'); + } + + /** + * The total number of brands in the collection. + * + * @param mixed $filter + * @return int + */ + public static function getBrandsCount($filter = false) + { + $filter = Filter::create($filter); + return self::getCount('/brands/count' . $filter->toQuery()); + } + + /** + * A single brand by given id. + * + * @param int $id brand id + * @return Brand + */ + public static function getBrand($id) + { + return self::getResource('/brands/' . $id, 'Brand'); + } + + /** + * Create a new brand from the given data. + * + * @param mixed $object + */ + public static function createBrand($object) + { + return self::createResource('/brands', $object); + } + + /** + * Update the given brand. + * + * @param int $id brand id + * @param mixed $object + */ + public static function updateBrand($id, $object) + { + return self::updateResource('/brands/' . $id, $object); + } + + /** + * Delete the given brand. + * + * @param int $id brand id + */ + public static function deleteBrand($id) + { + return self::deleteResource('/brands/' . $id); + } + + /** + * The collection of orders. + * + * @param mixed $filter + * @return array + */ + public static function getOrders($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/orders' . $filter->toQuery(), 'Order'); + } + + /** + * The number of orders in the collection. + * + * @return int + */ + public static function getOrdersCount() + { + return self::getCount('/orders/count'); + } + + /** + * A single order. + * + * @param int $id order id + * @return Order + */ + public static function getOrder($id) + { + return self::getResource('/orders/' . $id, 'Order'); + } + + /** + * Delete the given order (unlike in the Control Panel, this will permanently + * delete the order). + * + * @param int $id order id + */ + public static function deleteOrder($id) + { + return self::deleteResource('/orders/' . $id); + } + + /** + * Create an order + **/ + + public static function createOrder($object) + { + return self::createResource('/orders', $object); + } + + /** + * The list of customers. + * + * @param mixed $filter + * @return array + */ + public static function getCustomers($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/customers' . $filter->toQuery(), 'Customer'); + } + + /** + * The total number of customers in the collection. + * + * @param mixed $filter + * @return int + */ + public static function getCustomersCount($filter = false) + { + $filter = Filter::create($filter); + return self::getCount('/customers/count' . $filter->toQuery()); + } + + /** + * Bulk delete customers. + * + * @param mixed $filter + * @return array + */ + public static function deleteCustomers($filter = false) + { + $filter = Filter::create($filter); + return self::deleteResource('/customers' . $filter->toQuery()); + } + + /** + * A single customer by given id. + * + * @param int $id customer id + * @return Customer + */ + public static function getCustomer($id) + { + return self::getResource('/customers/' . $id, 'Customer'); + } + + /** + * Create a new customer from the given data. + * + * @param mixed $object + */ + public static function createCustomer($object) + { + return self::createResource('/customers', $object); + } + + /** + * Update the given customer. + * + * @param int $id customer id + * @param mixed $object + */ + public static function updateCustomer($id, $object) + { + return self::updateResource('/customers/' . $id, $object); + } + + /** + * Delete the given customer. + * + * @param int $id customer id + */ + public static function deleteCustomer($id) + { + return self::deleteResource('/customers/' . $id); + } + + /** + * A list of addresses belonging to the given customer. + * + * @param int $id customer id + * @return array + */ + public static function getCustomerAddresses($id) + { + return self::getCollection('/customers/' . $id . '/addresses', 'Address'); + } + + /** + * Returns the collection of option sets. + * + * @param array $filter + * @return array + */ + public static function getOptionSets($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/optionsets' . $filter->toQuery(), 'OptionSet'); + } + + /** create optionsets **/ + public static function createOptionsets($object) + { + return self::createResource('/optionsets', $object); + } + + /** connect optionsets options **/ + public static function createOptionsets_Options($object, $id) + { + return self::createResource('/optionsets/' . $id . '/options', $object); + } + + + /** + * Returns the total number of option sets in the collection. + * + * @return int + */ + public static function getOptionSetsCount() + { + return self::getCount('/optionsets/count'); + } + + /** + * A single option set by given id. + * + * @param int $id option set id + * @return OptionSet + */ + public static function getOptionSet($id) + { + return self::getResource('/optionsets/' . $id, 'OptionSet'); + } + + /** + * Status codes used to represent the state of an order. + * + * @return array + */ + public static function getOrderStatuses() + { + return self::getCollection('/orderstatuses', 'OrderStatus'); + } + + /* product skus */ + public static function getSkus($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/products/skus' . $filter->toQuery(), 'Sku'); + } + + public static function createSku($object) + { + return self::createResource('/product/skus', $object); + } + + public static function updateSku($id, $object) + { + return self::updateResource('/product/skus' . $id, $object); + } + + + /* coupons */ + public static function getCoupons($filter = false) + { + $filter = Filter::create($filter); + return self::getCollection('/coupons' . $filter->toQuery(), 'Sku'); + } + + public static function createCoupon($object) + { + return self::createResource('/coupons', $object); + } + + public static function updateCoupon($id, $object) + { + return self::updateResource('/coupons/' . $id, $object); + } + + /** + * The request logs with usage history statistics. + */ + public static function getRequestLogs() + { + return self::getCollection('/requestlogs'); + } + + public static function getStore() + { + $response = self::connection()->get(self::$api_path . '/store'); + return $response; + } + + /** + * The number of requests remaining at the current time. Based on the + * last request that was fetched within the current script. If no + * requests have been made, pings the time endpoint to get the value. + * + * @return int + */ + public static function getRequestsRemaining() + { + $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); + + if (!$limit) { + $result = self::getTime(); + + if (!$result) return false; + + $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); + } + + return intval($limit); + } } diff --git a/src/Bigcommerce/Api/ClientError.php b/src/Bigcommerce/Api/ClientError.php index b93f06ec..95a28878 100644 --- a/src/Bigcommerce/Api/ClientError.php +++ b/src/Bigcommerce/Api/ClientError.php @@ -8,9 +8,8 @@ class ClientError extends Error { - public function __toString() - { - return "Client Error ({$this->code}): " . $this->message; - } - -} \ No newline at end of file + public function __toString() + { + return "Client Error ({$this->code}): " . $this->message; + } +} diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 5cc793ff..d10eede0 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -8,468 +8,467 @@ class Connection { - /** - * @var cURL resource - */ - private $curl; - - /** - * @var hash of HTTP request headers - */ - private $headers = array(); - - /** - * @var hash of headers from HTTP response - */ - private $responseHeaders = array(); - - /** - * The status line of the response. - * @var string - */ - private $responseStatusLine; - - /** - * @var hash of headers from HTTP response - */ - private $responseBody; - - /** - * @var boolean - */ - private $failOnError = false; - - /** - * Manually follow location redirects. Used if CURLOPT_FOLLOWLOCATION - * is unavailable due to open_basedir restriction. - * @var boolean - */ - private $followLocation = false; - - /** - * Maximum number of redirects to try. - * @var int - */ - private $maxRedirects = 20; - - /** - * Number of redirects followed in a loop. - * @var int - */ - private $redirectsFollowed = 0; - - /** - * Deal with failed requests if failOnError is not set. - * @var mixed - */ - private $lastError = false; - - /** - * Current cURL error code. - */ - private $errorCode; - - /** - * Determines whether requests and responses should be treated - * as XML. Defaults to false (using JSON). - */ - private $useXml = false; - - /** - * Initializes the connection object. - */ - public function __construct() - { - $this->curl = curl_init(); - curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array($this, 'parseHeader')); - curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, array($this, 'parseBody')); - - // Bigcommerce only supports RC4-SHA (rsa_rc4_128_sha) - $this->setCipher('rsa_rc4_128_sha'); - - if (!ini_get("open_basedir")) { - curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - } else { - $this->followLocation = true; - } - } - - /** - * Controls whether requests and responses should be treated - * as XML. Defaults to false (using JSON). - */ - public function useXml($option=true) + /** + * @var cURL resource + */ + private $curl; + + /** + * @var hash of HTTP request headers + */ + private $headers = array(); + + /** + * @var hash of headers from HTTP response + */ + private $responseHeaders = array(); + + /** + * The status line of the response. + * @var string + */ + private $responseStatusLine; + + /** + * @var hash of headers from HTTP response + */ + private $responseBody; + + /** + * @var boolean + */ + private $failOnError = false; + + /** + * Manually follow location redirects. Used if CURLOPT_FOLLOWLOCATION + * is unavailable due to open_basedir restriction. + * @var boolean + */ + private $followLocation = false; + + /** + * Maximum number of redirects to try. + * @var int + */ + private $maxRedirects = 20; + + /** + * Number of redirects followed in a loop. + * @var int + */ + private $redirectsFollowed = 0; + + /** + * Deal with failed requests if failOnError is not set. + * @var mixed + */ + private $lastError = false; + + /** + * Current cURL error code. + */ + private $errorCode; + + /** + * Determines whether requests and responses should be treated + * as XML. Defaults to false (using JSON). + */ + private $useXml = false; + + /** + * Initializes the connection object. + */ + public function __construct() { - $this->useXml = $option; - } - - /** - * Throw an exception if the request encounters an HTTP error condition. - * - *

An error condition is considered to be:

- * - * - * - *

Note that this doesn't use the builtin CURL_FAILONERROR option, - * as this fails fast, making the HTTP body and headers inaccessible.

- */ - public function failOnError($option = true) - { - $this->failOnError = $option; - } - - /** - * Sets the HTTP basic authentication. - */ - public function authenticate($username, $password) - { - curl_setopt($this->curl, CURLOPT_USERPWD, "$username:$password"); - } - - /** - * Set a default timeout for the request. The client will error if the - * request takes longer than this to respond. - * - * @param int $timeout number of seconds to wait on a response - */ - public function setTimeout($timeout) - { - curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout); - curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $timeout); - } - - /** - * Set a proxy server for outgoing requests to tunnel through. - */ - public function useProxy($server, $port=false) - { - curl_setopt($this->curl, CURLOPT_PROXY, $server); - - if ($port) { - curl_setopt($this->curl, CURLOPT_PROXYPORT, $port); - } - } - - /** - * @todo may need to handle CURLOPT_SSL_VERIFYHOST and CURLOPT_CAINFO as well - * @param boolean - */ - public function verifyPeer($option=false) - { - curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $option); - } - - /** - * Set which cipher to use during SSL requests. - * @param string $cipher the name of the cipher - */ - public function setCipher($cipher='rsa_rc4_128_sha') - { - curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, $cipher); - } - - /** - * Add a custom header to the request. - */ - public function addHeader($header, $value) - { - $this->headers[$header] = "$header: $value"; - } - - /** - * Get the MIME type that should be used for this request. - */ - private function getContentType() - { - return ($this->useXml) ? 'application/xml' : 'application/json'; - } - - /** - * Clear previously cached request data and prepare for - * making a fresh request. - */ - private function initializeRequest() - { - $this->isComplete = false; - $this->responseBody = ''; - $this->responseHeaders = array(); - $this->lastError = false; - $this->addHeader('Accept', $this->getContentType()); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); - } - - /** - * Check the response for possible errors and handle the response body returned. - * - * If failOnError is true, a client or server error is raised, otherwise returns false - * on error. - */ - private function handleResponse() - { - if (curl_errno($this->curl)) { - throw new NetworkError(curl_error($this->curl), curl_errno($this->curl)); - } - - $body = ($this->useXml) ? $this->getBody() : json_decode($this->getBody()); - - $status = $this->getStatus(); - - if ($status >= 400 && $status <= 499) { - if ($this->failOnError) { - throw new ClientError($body, $status); - } else { - $this->lastError = $body; - return false; - } - } elseif ($status >= 500 && $status <= 599) { - if ($this->failOnError) { - throw new ServerError($body, $status); - } else { - $this->lastError = $body; - return false; - } - } - - if ($this->followLocation) { - $this->followRedirectPath(); - } - - return $body; - } - - /** - * Return an representation of an error returned by the last request, or false - * if the last request was not an error. - */ - public function getLastError() - { - return $this->lastError; - } - - /** - * Recursively follow redirect until an OK response is recieved or - * the maximum redirects limit is reached. - * - * Only 301 and 302 redirects are handled. Redirects from POST and PUT requests will - * be converted into GET requests, as per the HTTP spec. - */ - private function followRedirectPath() - { - $this->redirectsFollowed++; - - if ($this->getStatus() == 301 || $this->getStatus() == 302) { - - if ($this->redirectsFollowed < $this->maxRedirects) { - - $location = $this->getHeader('Location'); - $forwardTo = parse_url($location); - - if (isset($forwardTo['scheme']) && isset($forwardTo['host'])) { - $url = $location; - } else { - $forwardFrom = parse_url(curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL)); - $url = $forwardFrom['scheme'] . '://' . $forwardFrom['host'] . $location; - } - - $this->get($url); - - } else { - $errorString = "Too many redirects when trying to follow location."; - throw new NetworkError($errorString, CURLE_TOO_MANY_REDIRECTS); - } - } else { - $this->redirectsFollowed = 0; - } - } - - /** - * Make an HTTP GET request to the specified endpoint. - */ - public function get($url, $query=false) - { - $this->initializeRequest(); - - if (is_array($query)) { - $url .= '?' . http_build_query($query); - } - - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POST, false); - curl_setopt($this->curl, CURLOPT_PUT, false); - curl_setopt($this->curl, CURLOPT_HTTPGET, true); - curl_exec($this->curl); - - return $this->handleResponse(); - } - - /** - * Make an HTTP POST request to the specified endpoint. - */ - public function post($url, $body) - { - $this->addHeader('Content-Type', $this->getContentType()); - - if (!is_string($body)) { - $body = json_encode($body); - } - - $this->initializeRequest(); - - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_PUT, false); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_exec($this->curl); - - return $this->handleResponse(); - } - - /** - * Make an HTTP HEAD request to the specified endpoint. - */ - public function head($url) - { - $this->initializeRequest(); - - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_NOBODY, true); - curl_exec($this->curl); - - return $this->handleResponse(); - } - - /** - * Make an HTTP PUT request to the specified endpoint. - * - * Requires a tmpfile() handle to be opened on the system, as the cURL - * API requires it to send data. - */ - public function put($url, $body) - { - $this->addHeader('Content-Type', $this->getContentType()); - - if (!is_string($body)) { - $body = json_encode($body); - } - - $this->initializeRequest(); - - $handle = tmpfile(); - fwrite($handle, $body); - fseek($handle, 0); - curl_setopt($this->curl, CURLOPT_INFILE, $handle); - curl_setopt($this->curl, CURLOPT_INFILESIZE, strlen($body)); - - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); - curl_setopt($this->curl, CURLOPT_POST, false); - curl_setopt($this->curl, CURLOPT_PUT, true); - curl_exec($this->curl); - - fclose($handle); - curl_setopt($this->curl, CURLOPT_INFILE, STDIN); - - return $this->handleResponse(); - } - - /** - * Make an HTTP DELETE request to the specified endpoint. - */ - public function delete($url) - { - $this->initializeRequest(); - - curl_setopt($this->curl, CURLOPT_PUT, false); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); - curl_setopt($this->curl, CURLOPT_POST, false); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_exec($this->curl); - - return $this->handleResponse(); - } - - /** - * Callback method collects body content from the response. - */ - private function parseBody($curl, $body) - { - $this->responseBody .= $body; - return strlen($body); - } - - /** - * Callback methods collects header lines from the response. - */ - private function parseHeader($curl, $headers) - { - if (!$this->responseStatusLine && strpos($headers, 'HTTP/') === 0) { - $this->responseStatusLine = $headers; - } else { - $parts = explode(': ', $headers); - if (isset($parts[1])) { - $this->responseHeaders[$parts[0]] = trim($parts[1]); - } - } + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array($this, 'parseHeader')); + curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, array($this, 'parseBody')); + + // Bigcommerce only supports RC4-SHA (rsa_rc4_128_sha) + $this->setCipher('rsa_rc4_128_sha'); + + if (!ini_get("open_basedir")) { + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + } else { + $this->followLocation = true; + } + } + + /** + * Controls whether requests and responses should be treated + * as XML. Defaults to false (using JSON). + */ + public function useXml($option = true) + { + $this->useXml = $option; + } + + /** + * Throw an exception if the request encounters an HTTP error condition. + * + *

An error condition is considered to be:

+ * + * + * + *

Note that this doesn't use the builtin CURL_FAILONERROR option, + * as this fails fast, making the HTTP body and headers inaccessible.

+ */ + public function failOnError($option = true) + { + $this->failOnError = $option; + } + + /** + * Sets the HTTP basic authentication. + */ + public function authenticate($username, $password) + { + curl_setopt($this->curl, CURLOPT_USERPWD, "$username:$password"); + } + + /** + * Set a default timeout for the request. The client will error if the + * request takes longer than this to respond. + * + * @param int $timeout number of seconds to wait on a response + */ + public function setTimeout($timeout) + { + curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout); + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $timeout); + } + + /** + * Set a proxy server for outgoing requests to tunnel through. + */ + public function useProxy($server, $port = false) + { + curl_setopt($this->curl, CURLOPT_PROXY, $server); + + if ($port) { + curl_setopt($this->curl, CURLOPT_PROXYPORT, $port); + } + } + + /** + * @todo may need to handle CURLOPT_SSL_VERIFYHOST and CURLOPT_CAINFO as well + * @param boolean + */ + public function verifyPeer($option = false) + { + curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $option); + } + + /** + * Set which cipher to use during SSL requests. + * @param string $cipher the name of the cipher + */ + public function setCipher($cipher = 'rsa_rc4_128_sha') + { + curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, $cipher); + } + + /** + * Add a custom header to the request. + */ + public function addHeader($header, $value) + { + $this->headers[$header] = "$header: $value"; + } + + /** + * Get the MIME type that should be used for this request. + */ + private function getContentType() + { + return ($this->useXml) ? 'application/xml' : 'application/json'; + } + + /** + * Clear previously cached request data and prepare for + * making a fresh request. + */ + private function initializeRequest() + { + $this->isComplete = false; + $this->responseBody = ''; + $this->responseHeaders = array(); + $this->lastError = false; + $this->addHeader('Accept', $this->getContentType()); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); + } + + /** + * Check the response for possible errors and handle the response body returned. + * + * If failOnError is true, a client or server error is raised, otherwise returns false + * on error. + */ + private function handleResponse() + { + if (curl_errno($this->curl)) { + throw new NetworkError(curl_error($this->curl), curl_errno($this->curl)); + } + + $body = ($this->useXml) ? $this->getBody() : json_decode($this->getBody()); + + $status = $this->getStatus(); + + if ($status >= 400 && $status <= 499) { + if ($this->failOnError) { + throw new ClientError($body, $status); + } else { + $this->lastError = $body; + return false; + } + } elseif ($status >= 500 && $status <= 599) { + if ($this->failOnError) { + throw new ServerError($body, $status); + } else { + $this->lastError = $body; + return false; + } + } + + if ($this->followLocation) { + $this->followRedirectPath(); + } + + return $body; + } + + /** + * Return an representation of an error returned by the last request, or false + * if the last request was not an error. + */ + public function getLastError() + { + return $this->lastError; + } + + /** + * Recursively follow redirect until an OK response is recieved or + * the maximum redirects limit is reached. + * + * Only 301 and 302 redirects are handled. Redirects from POST and PUT requests will + * be converted into GET requests, as per the HTTP spec. + */ + private function followRedirectPath() + { + $this->redirectsFollowed++; + + if ($this->getStatus() == 301 || $this->getStatus() == 302) { + + if ($this->redirectsFollowed < $this->maxRedirects) { + + $location = $this->getHeader('Location'); + $forwardTo = parse_url($location); + + if (isset($forwardTo['scheme']) && isset($forwardTo['host'])) { + $url = $location; + } else { + $forwardFrom = parse_url(curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL)); + $url = $forwardFrom['scheme'] . '://' . $forwardFrom['host'] . $location; + } + + $this->get($url); + + } else { + $errorString = "Too many redirects when trying to follow location."; + throw new NetworkError($errorString, CURLE_TOO_MANY_REDIRECTS); + } + } else { + $this->redirectsFollowed = 0; + } + } + + /** + * Make an HTTP GET request to the specified endpoint. + */ + public function get($url, $query = false) + { + $this->initializeRequest(); + + if (is_array($query)) { + $url .= '?' . http_build_query($query); + } + + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET'); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, true); + curl_exec($this->curl); + + return $this->handleResponse(); + } + + /** + * Make an HTTP POST request to the specified endpoint. + */ + public function post($url, $body) + { + $this->addHeader('Content-Type', $this->getContentType()); + + if (!is_string($body)) { + $body = json_encode($body); + } + + $this->initializeRequest(); + + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); + curl_exec($this->curl); + + return $this->handleResponse(); + } + + /** + * Make an HTTP HEAD request to the specified endpoint. + */ + public function head($url) + { + $this->initializeRequest(); + + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_NOBODY, true); + curl_exec($this->curl); + + return $this->handleResponse(); + } + + /** + * Make an HTTP PUT request to the specified endpoint. + * + * Requires a tmpfile() handle to be opened on the system, as the cURL + * API requires it to send data. + */ + public function put($url, $body) + { + $this->addHeader('Content-Type', $this->getContentType()); + + if (!is_string($body)) { + $body = json_encode($body); + } + + $this->initializeRequest(); + + $handle = tmpfile(); + fwrite($handle, $body); + fseek($handle, 0); + curl_setopt($this->curl, CURLOPT_INFILE, $handle); + curl_setopt($this->curl, CURLOPT_INFILESIZE, strlen($body)); + + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_PUT, true); + curl_exec($this->curl); + + fclose($handle); + curl_setopt($this->curl, CURLOPT_INFILE, STDIN); + + return $this->handleResponse(); + } + + /** + * Make an HTTP DELETE request to the specified endpoint. + */ + public function delete($url) + { + $this->initializeRequest(); + + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_exec($this->curl); + + return $this->handleResponse(); + } + + /** + * Callback method collects body content from the response. + */ + private function parseBody($curl, $body) + { + $this->responseBody .= $body; + return strlen($body); + } + + /** + * Callback methods collects header lines from the response. + */ + private function parseHeader($curl, $headers) + { + if (!$this->responseStatusLine && strpos($headers, 'HTTP/') === 0) { + $this->responseStatusLine = $headers; + } else { + $parts = explode(': ', $headers); + if (isset($parts[1])) { + $this->responseHeaders[$parts[0]] = trim($parts[1]); + } + } return strlen($headers); - } - - /** - * Access the status code of the response. - */ - public function getStatus() - { - return curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - } - - /** - * Access the message string from the status line of the response. - */ - public function getStatusMessage() - { - return $this->responseStatusLine; - } - - /** - * Access the content body of the response - */ - public function getBody() - { - return $this->responseBody; - } - - /** - * Access given header from the response. - */ - public function getHeader($header) - { - if (array_key_exists($header, $this->responseHeaders)) { - return $this->responseHeaders[$header]; - } - } - - /** - * Return the full list of response headers - */ - public function getHeaders() - { - return $this->responseHeaders; - } - - /** - * Close the cURL resource when the instance is garbage collected - */ - public function __destruct() - { - curl_close($this->curl); - } + } + + /** + * Access the status code of the response. + */ + public function getStatus() + { + return curl_getinfo($this->curl, CURLINFO_HTTP_CODE); + } + + /** + * Access the message string from the status line of the response. + */ + public function getStatusMessage() + { + return $this->responseStatusLine; + } + /** + * Access the content body of the response + */ + public function getBody() + { + return $this->responseBody; + } + + /** + * Access given header from the response. + */ + public function getHeader($header) + { + if (array_key_exists($header, $this->responseHeaders)) { + return $this->responseHeaders[$header]; + } + } + + /** + * Return the full list of response headers + */ + public function getHeaders() + { + return $this->responseHeaders; + } + + /** + * Close the cURL resource when the instance is garbage collected + */ + public function __destruct() + { + curl_close($this->curl); + } } diff --git a/src/Bigcommerce/Api/Error.php b/src/Bigcommerce/Api/Error.php index b60e93ca..aae1d5ab 100644 --- a/src/Bigcommerce/Api/Error.php +++ b/src/Bigcommerce/Api/Error.php @@ -7,14 +7,12 @@ */ class Error extends \Exception { + public function __construct($message, $code) + { + if (is_array($message)) { + $message = $message[0]->message; + } - public function __construct($message, $code) - { - if (is_array($message)) { - $message = $message[0]->message; - } - - parent::__construct($message, $code); - } - -} \ No newline at end of file + parent::__construct($message, $code); + } +} diff --git a/src/Bigcommerce/Api/Filter.php b/src/Bigcommerce/Api/Filter.php index 79c05f45..53f58fa3 100644 --- a/src/Bigcommerce/Api/Filter.php +++ b/src/Bigcommerce/Api/Filter.php @@ -7,46 +7,45 @@ */ class Filter { - private $parameters; - - /** - * Factory method, creates an instance of a filter. - * Used to build URLs to collection endpoints. - */ - public static function create($filter=false) - { - if ($filter instanceof self) { - return $filter; - } - - if (is_int($filter)) { - $filter = array('page'=> $filter); - } - - return new self($filter); - } - - public function __construct($filter=array()) - { - $this->parameters = ($filter) ? $filter : array(); - } - - public function __set($parameter, $value) - { - $this->parameters[$parameter] = $value; - } - - /** - * Converts the filter into a URL querystring that can be - * applied as GET parameters. - * - * @return string - */ - public function toQuery() - { - $query = http_build_query($this->parameters); - - return ($query) ? '?' . $query : ''; - } - + private $parameters; + + /** + * Factory method, creates an instance of a filter. + * Used to build URLs to collection endpoints. + */ + public static function create($filter = false) + { + if ($filter instanceof self) { + return $filter; + } + + if (is_int($filter)) { + $filter = array('page' => $filter); + } + + return new self($filter); + } + + public function __construct($filter = array()) + { + $this->parameters = ($filter) ? $filter : array(); + } + + public function __set($parameter, $value) + { + $this->parameters[$parameter] = $value; + } + + /** + * Converts the filter into a URL querystring that can be + * applied as GET parameters. + * + * @return string + */ + public function toQuery() + { + $query = http_build_query($this->parameters); + + return ($query) ? '?' . $query : ''; + } } diff --git a/src/Bigcommerce/Api/Resource.php b/src/Bigcommerce/Api/Resource.php index ab00409b..92481f3e 100644 --- a/src/Bigcommerce/Api/Resource.php +++ b/src/Bigcommerce/Api/Resource.php @@ -4,104 +4,103 @@ class Resource { - /** - * - * @var stdclass - */ - protected $fields; - - /** - * @var int - */ - protected $id; - - /** - * @var array - */ - protected $ignoreOnCreate = array(); - - /** - * @var array - */ - protected $ignoreOnUpdate = array(); - - /** - * @var array - */ - protected $ignoreIfZero = array(); - - /** - * @var array - */ - protected $fieldMap = array(); - - public function __construct($object=false) - { - if (is_array($object)) { - $object = (isset($object[0])) ? $object[0] : false; - } - $this->fields = ($object) ? $object : new \stdClass; - $this->id = ($object && isset($object->id)) ? $object->id : 0; - } - - public function __get($field) - { - // first, find the field we should actually be examining - $fieldName = isset($this->fieldMap[$field]) ? $this->fieldMap[$field] : $field; - // then, if a method exists for the specified field and the field we should actually be examining - // has a value, call the method instead - if (method_exists($this, $field) && isset($this->fields->$fieldName)) { - return $this->$field(); - } - // otherwise, just return the field directly (or null) - return (isset($this->fields->$field)) ? $this->fields->$field : null; - } - - public function __set($field, $value) - { - $this->fields->$field = $value; - } - - public function __isset($field) - { - return (isset($this->fields->$field)); - } - - public function getCreateFields() - { - $resource = $this->fields; - - foreach($this->ignoreOnCreate as $field) { - if (isset($resource->$field)) unset($resource->$field); - } - - return $resource; - } - - public function getUpdateFields() - { - $resource = $this->fields; - - foreach($this->ignoreOnUpdate as $field) { - if (isset($resource->$field)) unset($resource->$field); - } - - foreach($resource as $field => $value) { - if ($this->isIgnoredField($field, $value)) unset($resource->$field); - } - - return $resource; - } - - private function isIgnoredField($field, $value) - { - if ($value === null) return true; - - if ((strpos($field, "date") !== FALSE) && $value === "") return true; - - if (in_array($field, $this->ignoreIfZero) && $value === 0) return true; - - return false; - } - -} \ No newline at end of file + /** + * + * @var stdclass + */ + protected $fields; + + /** + * @var int + */ + protected $id; + + /** + * @var array + */ + protected $ignoreOnCreate = array(); + + /** + * @var array + */ + protected $ignoreOnUpdate = array(); + + /** + * @var array + */ + protected $ignoreIfZero = array(); + + /** + * @var array + */ + protected $fieldMap = array(); + + public function __construct($object = false) + { + if (is_array($object)) { + $object = (isset($object[0])) ? $object[0] : false; + } + $this->fields = ($object) ? $object : new \stdClass; + $this->id = ($object && isset($object->id)) ? $object->id : 0; + } + + public function __get($field) + { + // first, find the field we should actually be examining + $fieldName = isset($this->fieldMap[$field]) ? $this->fieldMap[$field] : $field; + // then, if a method exists for the specified field and the field we should actually be examining + // has a value, call the method instead + if (method_exists($this, $field) && isset($this->fields->$fieldName)) { + return $this->$field(); + } + // otherwise, just return the field directly (or null) + return (isset($this->fields->$field)) ? $this->fields->$field : null; + } + + public function __set($field, $value) + { + $this->fields->$field = $value; + } + + public function __isset($field) + { + return (isset($this->fields->$field)); + } + + public function getCreateFields() + { + $resource = $this->fields; + + foreach ($this->ignoreOnCreate as $field) { + if (isset($resource->$field)) unset($resource->$field); + } + + return $resource; + } + + public function getUpdateFields() + { + $resource = $this->fields; + + foreach ($this->ignoreOnUpdate as $field) { + if (isset($resource->$field)) unset($resource->$field); + } + + foreach ($resource as $field => $value) { + if ($this->isIgnoredField($field, $value)) unset($resource->$field); + } + + return $resource; + } + + private function isIgnoredField($field, $value) + { + if ($value === null) return true; + + if ((strpos($field, "date") !== FALSE) && $value === "") return true; + + if (in_array($field, $this->ignoreIfZero) && $value === 0) return true; + + return false; + } +} diff --git a/src/Bigcommerce/Api/Resources/Brand.php b/src/Bigcommerce/Api/Resources/Brand.php index c1344d2d..a8b301fe 100644 --- a/src/Bigcommerce/Api/Resources/Brand.php +++ b/src/Bigcommerce/Api/Resources/Brand.php @@ -7,23 +7,21 @@ class Brand extends Resource { - - protected $ignoreOnCreate = array( - 'id', - ); - - protected $ignoreOnUpdate = array( - 'id', - ); - - public function create() - { - return Client::createBrand($this->getCreateFields()); - } - - public function update() - { - return Client::updateBrand($this->id, $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + ); + + protected $ignoreOnUpdate = array( + 'id', + ); + + public function create() + { + return Client::createBrand($this->getCreateFields()); + } + + public function update() + { + return Client::updateBrand($this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/Category.php b/src/Bigcommerce/Api/Resources/Category.php index 9f56c4ae..352549b0 100644 --- a/src/Bigcommerce/Api/Resources/Category.php +++ b/src/Bigcommerce/Api/Resources/Category.php @@ -7,25 +7,23 @@ class Category extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'parent_category_list', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'parent_category_list', - ); - - public function create() - { - return Client::createCategory($this->getCreateFields()); - } - - public function update() - { - return Client::updateCategory($this->id, $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + 'parent_category_list', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'parent_category_list', + ); + + public function create() + { + return Client::createCategory($this->getCreateFields()); + } + + public function update() + { + return Client::updateCategory($this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/Coupon.php b/src/Bigcommerce/Api/Resources/Coupon.php index 913bdb25..61ca88e3 100644 --- a/src/Bigcommerce/Api/Resources/Coupon.php +++ b/src/Bigcommerce/Api/Resources/Coupon.php @@ -7,23 +7,23 @@ class Coupon extends Resource { - protected $ignoreOnCreate = array( - 'id', - 'num_uses', - ); + protected $ignoreOnCreate = array( + 'id', + 'num_uses', + ); - protected $ignoreOnUpdate = array( - 'id', - 'num_uses', - ); + protected $ignoreOnUpdate = array( + 'id', + 'num_uses', + ); - public function create() - { - return Client::createCoupon($this->getCreateFields()); - } + public function create() + { + return Client::createCoupon($this->getCreateFields()); + } - public function update() - { - return Client::updateCoupon($this->id, $this->getUpdateFields()); - } + public function update() + { + return Client::updateCoupon($this->id, $this->getUpdateFields()); + } } diff --git a/src/Bigcommerce/Api/Resources/Customer.php b/src/Bigcommerce/Api/Resources/Customer.php index b06f5c2d..af76769c 100644 --- a/src/Bigcommerce/Api/Resources/Customer.php +++ b/src/Bigcommerce/Api/Resources/Customer.php @@ -7,33 +7,31 @@ class Customer extends Resource { + protected $ignoreOnCreate = array( + 'id', + ); - protected $ignoreOnCreate = array( - 'id', - ); - - protected $ignoreOnUpdate = array( - 'id', - ); - - public function addresses() - { - return Client::getCollection($this->fields->addresses->resource, 'Address'); - } - - public function create() - { - return Client::createCustomer($this->getCreateFields()); - } - - public function update() - { - return Client::updateCustomer($this->id, $this->getUpdateFields()); - } - - public function delete() - { - return Client::deleteCustomer($this->id); - } - -} \ No newline at end of file + protected $ignoreOnUpdate = array( + 'id', + ); + + public function addresses() + { + return Client::getCollection($this->fields->addresses->resource, 'Address'); + } + + public function create() + { + return Client::createCustomer($this->getCreateFields()); + } + + public function update() + { + return Client::updateCustomer($this->id, $this->getUpdateFields()); + } + + public function delete() + { + return Client::deleteCustomer($this->id); + } +} diff --git a/src/Bigcommerce/Api/Resources/Option.php b/src/Bigcommerce/Api/Resources/Option.php index c89b96a1..4c4b76b9 100644 --- a/src/Bigcommerce/Api/Resources/Option.php +++ b/src/Bigcommerce/Api/Resources/Option.php @@ -10,12 +10,8 @@ */ class Option extends Resource { - - public function values() - { - return Client::getCollection($this->fields->values->resource, 'OptionValue'); - } - + public function values() + { + return Client::getCollection($this->fields->values->resource, 'OptionValue'); + } } - - diff --git a/src/Bigcommerce/Api/Resources/OptionSet.php b/src/Bigcommerce/Api/Resources/OptionSet.php index ed68f2ae..e58ba041 100644 --- a/src/Bigcommerce/Api/Resources/OptionSet.php +++ b/src/Bigcommerce/Api/Resources/OptionSet.php @@ -7,28 +7,26 @@ class OptionSet extends Resource { - - protected $ignoreOnCreate = array( - 'id', - ); - - protected $ignoreOnUpdate = array( - 'id', - ); - - public function options() - { - return Client::getCollection($this->fields->options->resource, 'OptionSetOption'); - } - - public function create() - { - return Client::createResource('/optionsets', $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/optionsets/' . $this->id, $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + ); + + protected $ignoreOnUpdate = array( + 'id', + ); + + public function options() + { + return Client::getCollection($this->fields->options->resource, 'OptionSetOption'); + } + + public function create() + { + return Client::createResource('/optionsets', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/optionsets/' . $this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/OptionSetOption.php b/src/Bigcommerce/Api/Resources/OptionSetOption.php index 92e75c8e..b7305436 100644 --- a/src/Bigcommerce/Api/Resources/OptionSetOption.php +++ b/src/Bigcommerce/Api/Resources/OptionSetOption.php @@ -7,31 +7,29 @@ class OptionSetOption extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'option_set_id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'option_set_id', - 'option_id', - ); - - public function option() - { - return Client::getResource($this->fields->option->resource, 'Option'); - } - - public function create() - { - return Client::createResource('/optionsets/options', $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/optionsets/options/' . $this->id, $this->getUpdateFields()); - } - + protected $ignoreOnCreate = array( + 'id', + 'option_set_id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'option_set_id', + 'option_id', + ); + + public function option() + { + return Client::getResource($this->fields->option->resource, 'Option'); + } + + public function create() + { + return Client::createResource('/optionsets/options', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/optionsets/options/' . $this->id, $this->getUpdateFields()); + } } diff --git a/src/Bigcommerce/Api/Resources/OptionValue.php b/src/Bigcommerce/Api/Resources/OptionValue.php index 61126b17..ffe7fe19 100644 --- a/src/Bigcommerce/Api/Resources/OptionValue.php +++ b/src/Bigcommerce/Api/Resources/OptionValue.php @@ -10,34 +10,32 @@ */ class OptionValue extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'option_id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'option_id', - ); - - protected $fieldMap = array( - 'option' => 'option_id' - ); - - public function option() - { - return Client::getResource('/options/' . $this->fields->option_id, 'Option'); - } - - public function create() - { - return Client::createResource('/options/' . $this->fields->option_id . '/values', $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/options/' . $this->fields->option_id . '/values/' . $this->id, $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + 'option_id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'option_id', + ); + + protected $fieldMap = array( + 'option' => 'option_id' + ); + + public function option() + { + return Client::getResource('/options/' . $this->fields->option_id, 'Option'); + } + + public function create() + { + return Client::createResource('/options/' . $this->fields->option_id . '/values', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/options/' . $this->fields->option_id . '/values/' . $this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/Order.php b/src/Bigcommerce/Api/Resources/Order.php index c5e90c2a..c44ed683 100644 --- a/src/Bigcommerce/Api/Resources/Order.php +++ b/src/Bigcommerce/Api/Resources/Order.php @@ -7,37 +7,36 @@ class Order extends Resource { - protected $fieldMap = array( - 'shipments' => 'id' - ); - - public function shipments() - { - return Client::getCollection('/orders/'. $this->id . '/shipments', 'Shipment'); - } - - public function products() - { - return Client::getCollection($this->fields->products->resource, 'OrderProduct'); - } - - public function shipping_addresses() - { - return Client::getCollection($this->fields->shipping_addresses->resource, 'Address'); - } - - public function coupons() - { - return Client::getCollection($this->fields->coupons->resource, 'Coupon'); - } - - public function update() - { - $order = new \stdClass; // to use stdClass in global namespace use this... - $order->status_id = $this->status_id; - $order->is_deleted = $this->is_deleted; - - Client::updateResource('/orders/' . $this->id, $order); - } - + protected $fieldMap = array( + 'shipments' => 'id' + ); + + public function shipments() + { + return Client::getCollection('/orders/' . $this->id . '/shipments', 'Shipment'); + } + + public function products() + { + return Client::getCollection($this->fields->products->resource, 'OrderProduct'); + } + + public function shipping_addresses() + { + return Client::getCollection($this->fields->shipping_addresses->resource, 'Address'); + } + + public function coupons() + { + return Client::getCollection($this->fields->coupons->resource, 'Coupon'); + } + + public function update() + { + $order = new \stdClass; // to use stdClass in global namespace use this... + $order->status_id = $this->status_id; + $order->is_deleted = $this->is_deleted; + + Client::updateResource('/orders/' . $this->id, $order); + } } diff --git a/src/Bigcommerce/Api/Resources/Product.php b/src/Bigcommerce/Api/Resources/Product.php index d2fdc999..3c698249 100644 --- a/src/Bigcommerce/Api/Resources/Product.php +++ b/src/Bigcommerce/Api/Resources/Product.php @@ -10,109 +10,107 @@ */ class Product extends Resource { - - protected $ignoreOnCreate = array( - 'date_created', - 'date_modified', - ); - - /** - * @see https://developer.bigcommerce.com/display/API/Products#Products-ReadOnlyFields - * @var array - */ - protected $ignoreOnUpdate = array( - 'id', - 'rating_total', - 'rating_count', - 'date_created', - 'date_modified', - 'date_last_imported', - 'number_sold', - 'brand', - 'images', - 'discount_rules', - 'configurable_fields', - 'custom_fields', - 'videos', - 'skus', - 'rules', - 'option_set', - 'options', - 'tax_class', - ); - - protected $ignoreIfZero = array( - 'tax_class_id', - ); - - public function brand() - { - return Client::getResource($this->fields->brand->resource, 'Brand'); - } - - public function images() - { - return Client::getCollection($this->fields->images->resource, 'ProductImage'); - } - - public function skus() - { - return Client::getCollection($this->fields->skus->resource, 'Sku'); - } - - public function rules() - { - return Client::getCollection($this->fields->rules->resource, 'Rule'); - } - - public function videos() - { - return Client::getCollection($this->fields->videos->resource, 'ProductVideo'); - } - - public function custom_fields() - { - return Client::getCollection($this->fields->custom_fields->resource, 'ProductCustomField'); - } - - public function configurable_fields() - { - return Client::getCollection($this->fields->configurable_fields->resource, 'ProductConfigurableField'); - } - - public function discount_rules() - { - return Client::getCollection($this->fields->discount_rules->resource, 'DiscountRule'); - } - - public function option_set() - { - return Client::getResource($this->fields->option_set->resource, 'OptionSet'); - } - - public function options() - { - return Client::getCollection('/products/' . $this->id . '/options', 'ProductOption'); - } - - public function create() - { - return Client::createProduct($this->getCreateFields()); - } - - public function update() - { - return Client::updateProduct($this->id, $this->getUpdateFields()); - } - - public function delete() - { - return Client::deleteProduct($this->id); - } - - public function tax_class() - { - return Client::getResource($this->fields->tax_class->resource, 'TaxClass'); - } - + protected $ignoreOnCreate = array( + 'date_created', + 'date_modified', + ); + + /** + * @see https://developer.bigcommerce.com/display/API/Products#Products-ReadOnlyFields + * @var array + */ + protected $ignoreOnUpdate = array( + 'id', + 'rating_total', + 'rating_count', + 'date_created', + 'date_modified', + 'date_last_imported', + 'number_sold', + 'brand', + 'images', + 'discount_rules', + 'configurable_fields', + 'custom_fields', + 'videos', + 'skus', + 'rules', + 'option_set', + 'options', + 'tax_class', + ); + + protected $ignoreIfZero = array( + 'tax_class_id', + ); + + public function brand() + { + return Client::getResource($this->fields->brand->resource, 'Brand'); + } + + public function images() + { + return Client::getCollection($this->fields->images->resource, 'ProductImage'); + } + + public function skus() + { + return Client::getCollection($this->fields->skus->resource, 'Sku'); + } + + public function rules() + { + return Client::getCollection($this->fields->rules->resource, 'Rule'); + } + + public function videos() + { + return Client::getCollection($this->fields->videos->resource, 'ProductVideo'); + } + + public function custom_fields() + { + return Client::getCollection($this->fields->custom_fields->resource, 'ProductCustomField'); + } + + public function configurable_fields() + { + return Client::getCollection($this->fields->configurable_fields->resource, 'ProductConfigurableField'); + } + + public function discount_rules() + { + return Client::getCollection($this->fields->discount_rules->resource, 'DiscountRule'); + } + + public function option_set() + { + return Client::getResource($this->fields->option_set->resource, 'OptionSet'); + } + + public function options() + { + return Client::getCollection('/products/' . $this->id . '/options', 'ProductOption'); + } + + public function create() + { + return Client::createProduct($this->getCreateFields()); + } + + public function update() + { + return Client::updateProduct($this->id, $this->getUpdateFields()); + } + + public function delete() + { + return Client::deleteProduct($this->id); + } + + public function tax_class() + { + return Client::getResource($this->fields->tax_class->resource, 'TaxClass'); + } } diff --git a/src/Bigcommerce/Api/Resources/ProductCustomField.php b/src/Bigcommerce/Api/Resources/ProductCustomField.php index fd7d381a..be663eb0 100644 --- a/src/Bigcommerce/Api/Resources/ProductCustomField.php +++ b/src/Bigcommerce/Api/Resources/ProductCustomField.php @@ -10,30 +10,28 @@ */ class ProductCustomField extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'product_id' - ); - - protected $ignoreOnUpdate = array( - 'id', - 'product_id' - ); - - public function create() - { - return Client::createResource('/products/' . $this->fields->product_id . '/customfields', $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->fields->product_id . '/customfields/' . $this->id, $this->getUpdateFields()); - } - - public function delete() - { - Client::deleteResource('/products/' . $this->fields->product_id . '/customfields/' . $this->id); - } + protected $ignoreOnCreate = array( + 'id', + 'product_id' + ); + + protected $ignoreOnUpdate = array( + 'id', + 'product_id' + ); + + public function create() + { + return Client::createResource('/products/' . $this->fields->product_id . '/customfields', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->fields->product_id . '/customfields/' . $this->id, $this->getUpdateFields()); + } + + public function delete() + { + Client::deleteResource('/products/' . $this->fields->product_id . '/customfields/' . $this->id); + } } - diff --git a/src/Bigcommerce/Api/Resources/ProductImage.php b/src/Bigcommerce/Api/Resources/ProductImage.php index 03bc762b..a906828d 100644 --- a/src/Bigcommerce/Api/Resources/ProductImage.php +++ b/src/Bigcommerce/Api/Resources/ProductImage.php @@ -10,29 +10,25 @@ */ class ProductImage extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'date_created', - 'product_id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'date_created', - 'product_id', - ); - - - - public function create() - { - return Client::createResource('/products/' . $this->fields->product_id . '/images' , $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->fields->product_id . '/images/' . $this->id , $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + 'date_created', + 'product_id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'date_created', + 'product_id', + ); + + public function create() + { + return Client::createResource('/products/' . $this->fields->product_id . '/images' , $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->fields->product_id . '/images/' . $this->id , $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/ProductOption.php b/src/Bigcommerce/Api/Resources/ProductOption.php index 679bac50..9af59913 100644 --- a/src/Bigcommerce/Api/Resources/ProductOption.php +++ b/src/Bigcommerce/Api/Resources/ProductOption.php @@ -14,11 +14,8 @@ class ProductOption extends Resource 'option' => 'option_id' ); - public function option() - { - return Client::getResource('/options/' . $this->fields->option_id, 'Option'); - } - + public function option() + { + return Client::getResource('/options/' . $this->fields->option_id, 'Option'); + } } - - diff --git a/src/Bigcommerce/Api/Resources/Rule.php b/src/Bigcommerce/Api/Resources/Rule.php index d599ef04..2455dcdb 100644 --- a/src/Bigcommerce/Api/Resources/Rule.php +++ b/src/Bigcommerce/Api/Resources/Rule.php @@ -10,36 +10,34 @@ */ class Rule extends Resource { - - protected $ignoreOnCreate = array( - 'id', - 'product_id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'product_id', - ); - - public function conditions() - { - $conditions = Client::getCollection($this->fields->conditions->resource, 'RuleCondition'); - - foreach($conditions as $condition) { - $condition->product_id = $this->fields->product_id; - } - - return $conditions; - } - - public function create() - { - return Client::createResource('/products/' . $this->fields->product_id . '/rules', $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->fields->product_id . '/rules/' . $this->fields->id, $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + 'product_id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'product_id', + ); + + public function conditions() + { + $conditions = Client::getCollection($this->fields->conditions->resource, 'RuleCondition'); + + foreach ($conditions as $condition) { + $condition->product_id = $this->product_id; + } + + return $conditions; + } + + public function create() + { + return Client::createResource('/products/' . $this->fields->product_id . '/rules', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->fields->product_id . '/rules/' . $this->fields->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/RuleCondition.php b/src/Bigcommerce/Api/Resources/RuleCondition.php index b1a6a1df..9ba5c954 100644 --- a/src/Bigcommerce/Api/Resources/RuleCondition.php +++ b/src/Bigcommerce/Api/Resources/RuleCondition.php @@ -10,25 +10,24 @@ */ class RuleCondition extends Resource { - - protected $ignoreOnCreate = array( - 'id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'rule_id', - ); - - public $product_id; - - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/rules/' . $this->fields->rule_id . '/conditions' , $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/rules/' . $this->fields->rule_id . '/conditions/' .$this->id , $this->getUpdateFields()); - } -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'rule_id', + ); + + public $product_id; + + public function create() + { + return Client::createResource('/products/' . $this->product_id . '/rules/' . $this->fields->rule_id . '/conditions', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->product_id . '/rules/' . $this->fields->rule_id . '/conditions/' . $this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/Shipment.php b/src/Bigcommerce/Api/Resources/Shipment.php index d8e10a48..ceed1efd 100644 --- a/src/Bigcommerce/Api/Resources/Shipment.php +++ b/src/Bigcommerce/Api/Resources/Shipment.php @@ -7,6 +7,7 @@ class Shipment extends Resource { +<<<<<<< HEAD protected $ignoreOnCreate = array( 'id', @@ -35,4 +36,33 @@ public function update() return Client::updateResource('/orders/' . $this->fields->order_id . '/shipments/' . $this->id, $this->getUpdateFields()); } -} \ No newline at end of file +} +======= + protected $ignoreOnCreate = array( + 'id', + 'order_id', + 'date_created', + 'customer_id', + 'shipping_method', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'order_id', + 'date_created', + 'customer_id', + 'shipping_method', + 'items', + ); + + public function create() + { + return Client::createResource('/orders/' . $this->order_id . '/shipments', $this->getCreateFields()); + } + + public function update() + { + return Client::createResource('/orders/' . $this->order_id . '/shipments' . $this->id, $this->getCreateFields()); + } +} +>>>>>>> BIG-15160: standardize spacing diff --git a/src/Bigcommerce/Api/Resources/Sku.php b/src/Bigcommerce/Api/Resources/Sku.php index fb4083a7..58dbdecb 100644 --- a/src/Bigcommerce/Api/Resources/Sku.php +++ b/src/Bigcommerce/Api/Resources/Sku.php @@ -10,35 +10,33 @@ */ class Sku extends Resource { - - protected $ignoreOnCreate = array( - 'product_id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'product_id', - ); - - public function options() - { - $options = Client::getCollection($this->fields->options->resource, 'SkuOption'); - - foreach($options as $option) { - $option->product_id = $this->product_id; - } - - return $options; - } - - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/skus' , $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->id , $this->getUpdateFields()); - } - -} \ No newline at end of file + protected $ignoreOnCreate = array( + 'product_id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'product_id', + ); + + public function options() + { + $options = Client::getCollection($this->fields->options->resource, 'SkuOption'); + + foreach ($options as $option) { + $option->product_id = $this->product_id; + } + + return $options; + } + + public function create() + { + return Client::createResource('/products/' . $this->product_id . '/skus', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->id, $this->getUpdateFields()); + } +} diff --git a/src/Bigcommerce/Api/Resources/SkuOption.php b/src/Bigcommerce/Api/Resources/SkuOption.php index b340ff0a..73b002cb 100644 --- a/src/Bigcommerce/Api/Resources/SkuOption.php +++ b/src/Bigcommerce/Api/Resources/SkuOption.php @@ -10,49 +10,24 @@ */ class SkuOption extends Resource { - - protected $ignoreOnCreate = array( - 'id', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'sku_id', - ); - - public $product_id; - - public function create() - { - return Client::createResource('/products/' . $this->fields->product_id . '/skus/' . $this->fields->sku_id . '/options' , $this->getCreateFields()); - } - - public function update() - { - Client::updateResource('/products/' . $this->fields->product_id . '/skus/' . $this->fields->sku_id . '/options/' .$this->id , $this->getUpdateFields()); - } - + protected $ignoreOnCreate = array( + 'id', + ); + + protected $ignoreOnUpdate = array( + 'id', + 'sku_id', + ); + + public $product_id; + + public function create() + { + return Client::createResource('/products/' . $this->product_id . '/skus/' . $this->fields->sku_id . '/options', $this->getCreateFields()); + } + + public function update() + { + Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->fields->sku_id . '/options/' . $this->id, $this->getUpdateFields()); + } } - - - - - - - - - - - - - - - - - - - - - - - From 9287b3c28a7a465402965a60c0cb086993e2fb5c Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 05:29:58 -0800 Subject: [PATCH 03/18] BIG-15160: update readme to remove information about bigcommerce.php single file --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 35ab4a06..13ef61de 100644 --- a/README.md +++ b/README.md @@ -47,14 +47,6 @@ php composer.phar install composer install ``` -If you don’t want to use Composer and Packagist, the API client is also distributed as a [single -PHP file](https://raw.github.com/bigcommerce/bigcommerce-api-php/master/bigcommerce.php) which you can -download and include directly into your project: - -``` -require 'path/to/bigcommerce.php'; -``` - Namespace --------- From 43d20c7cd6e03b688e2f62ff5ef669bac032e0af Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 05:40:37 -0800 Subject: [PATCH 04/18] BIG-15160: add curl connection timeout --- src/Bigcommerce/Api/Connection.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index d10eede0..53e0dd11 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -92,6 +92,8 @@ public function __construct() } else { $this->followLocation = true; } + + $this->setTimeout(60); } /** From a3a9164a4de04adf000aa88c1b080ed3e88f2ddd Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 05:45:12 -0800 Subject: [PATCH 05/18] BIG-15160: add cipher info to readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 13ef61de..07ff184d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Requirements - PHP 5.3 or greater - cUrl extension enabled +- RC4-SHA (rsa_rc4_128_sha) cipher To connect to the API, you need the following credentials: @@ -74,6 +75,19 @@ Bigcommerce::configure(array( )); ``` +Specifying the SSL cipher +----------------------- + +The API requires that all client SSL connections use the RC4-SHA (rsa_rc4_128_sha) cipher. +The client will set the cipher to "rsa_rc4_128_sha" by default. + +Sometimes the cipher is named different on a server. +The setCipher method can be used to override this setting if required. + +``` +Bigcommerce_Api::setCipher('RC4-SHA'); +``` + Connecting to the store ----------------------- From f613d9ea20e9665bdc2d7c303e317ec1dc5393fb Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 06:03:29 -0800 Subject: [PATCH 06/18] BIG-15160: fix phpdocs and filter defaults from false to array --- src/Bigcommerce/Api/Client.php | 127 +++++++++++++++++++++++++-------- src/Bigcommerce/Api/Filter.php | 2 +- 2 files changed, 97 insertions(+), 32 deletions(-) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 6848df05..f83f9e84 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -33,6 +33,7 @@ class Client * - api_key * * @param array $settings + * @throws \Exception */ public static function configure($settings) { @@ -102,7 +103,7 @@ public static function setCipher($cipher = 'rsa_rc4_128_sha') * Connect to the internet through a proxy server. * * @param string $host host server - * @param string $port port + * @param bool $port port */ public static function useProxy($host, $port = false) { @@ -151,7 +152,6 @@ public static function getConnection() * * @param string $path api endpoint * @param string $resource resource class to map individual items - * @param array $fields additional key=>value properties to apply to the object * @return mixed array|string mapped collection or XML string if useXml is true */ public static function getCollection($path, $resource = 'Resource') @@ -195,6 +195,7 @@ public static function getCount($path) * * @param string $path api endpoint * @param mixed $object object or XML string to create + * @return hash|bool|mixed */ public static function createResource($path, $object) { @@ -208,6 +209,7 @@ public static function createResource($path, $object) * * @param string $path api endpoint * @param mixed $object object or XML string to update + * @return hash|bool|mixed */ public static function updateResource($path, $object) { @@ -220,6 +222,7 @@ public static function updateResource($path, $object) * Send a delete request to remove the specified resource. * * @param string $path api endpoint + * @return hash|bool|mixed */ public static function deleteResource($path) { @@ -306,7 +309,7 @@ public static function getTime() * @param array $filter * @return mixed array|string list of products or XML string if useXml is true */ - public static function getProducts($filter = false) + public static function getProducts($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/products' . $filter->toQuery(), 'Product'); @@ -349,7 +352,6 @@ public static function getProductCustomField($product_id, $id) * Create a new custom field for a given product. * * @param int $product_id product id - * @param int $id custom field id * @param mixed $object fields to create * @return Object Object with `id`, `product_id`, `name` and `text` keys */ @@ -364,6 +366,7 @@ public static function createProductCustomField($product_id, $object) * @param int $product_id product id * @param int $id custom field id * @param mixed $object custom field to update + * @return hash|bool|mixed */ public static function updateProductCustomField($product_id, $id, $object) { @@ -375,6 +378,7 @@ public static function updateProductCustomField($product_id, $id, $object) * * @param int $product_id product id * @param int $id custom field id + * @return hash|bool|mixed */ public static function deleteProductCustomField($product_id, $id) { @@ -387,7 +391,7 @@ public static function deleteProductCustomField($product_id, $id) * @param array $filter * @return mixed int|string number of products or XML string if useXml is true */ - public static function getProductsCount($filter = false) + public static function getProductsCount($filter = array()) { $filter = Filter::create($filter); return self::getCount('/products/count' . $filter->toQuery()); @@ -408,6 +412,7 @@ public static function getProduct($id) * Create a new product. * * @param mixed $object fields to create + * @return hash|bool|mixed */ public static function createProduct($object) { @@ -419,6 +424,7 @@ public static function createProduct($object) * * @param int $id product id * @param mixed $object fields to update + * @return hash|bool|mixed */ public static function updateProduct($id, $object) { @@ -429,6 +435,7 @@ public static function updateProduct($id, $object) * Delete the given product. * * @param int $id product id + * @return hash|bool|mixed */ public static function deleteProduct($id) { @@ -441,7 +448,7 @@ public static function deleteProduct($id) * @param array $filter * @return array */ - public static function getOptions($filter = false) + public static function getOptions($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/options' . $filter->toQuery(), 'Option'); @@ -480,6 +487,7 @@ public static function getOption($id) * Delete the given option. * * @param int $id option id + * @return hash|bool|mixed */ public static function deleteOption($id) { @@ -501,10 +509,10 @@ public static function getOptionValue($option_id, $id) /** * Return the collection of all option values. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function getOptionValues($filter = false) + public static function getOptionValues($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/options/values' . $filter->toQuery(), 'OptionValue'); @@ -513,10 +521,10 @@ public static function getOptionValues($filter = false) /** * The collection of categories. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function getCategories($filter = false) + public static function getCategories($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/categories' . $filter->toQuery(), 'Category'); @@ -525,10 +533,10 @@ public static function getCategories($filter = false) /** * The number of categories in the collection. * - * @param mixed $filter + * @param array $filter * @return int */ - public static function getCategoriesCount($filter = false) + public static function getCategoriesCount($filter = array()) { $filter = Filter::create($filter); return self::getCount('/categories/count' . $filter->toQuery()); @@ -549,6 +557,7 @@ public static function getCategory($id) * Create a new category from the given data. * * @param mixed $object + * @return hash|bool|mixed */ public static function createCategory($object) { @@ -560,6 +569,7 @@ public static function createCategory($object) * * @param int $id category id * @param mixed $object + * @return hash|bool|mixed */ public static function updateCategory($id, $object) { @@ -570,6 +580,7 @@ public static function updateCategory($id, $object) * Delete the given category. * * @param int $id category id + * @return hash|bool|mixed */ public static function deleteCategory($id) { @@ -579,10 +590,10 @@ public static function deleteCategory($id) /** * The collection of brands. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function getBrands($filter = false) + public static function getBrands($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/brands' . $filter->toQuery(), 'Brand'); @@ -591,10 +602,10 @@ public static function getBrands($filter = false) /** * The total number of brands in the collection. * - * @param mixed $filter + * @param array $filter * @return int */ - public static function getBrandsCount($filter = false) + public static function getBrandsCount($filter = array()) { $filter = Filter::create($filter); return self::getCount('/brands/count' . $filter->toQuery()); @@ -615,6 +626,7 @@ public static function getBrand($id) * Create a new brand from the given data. * * @param mixed $object + * @return hash|bool|mixed */ public static function createBrand($object) { @@ -626,6 +638,7 @@ public static function createBrand($object) * * @param int $id brand id * @param mixed $object + * @return hash|bool|mixed */ public static function updateBrand($id, $object) { @@ -636,6 +649,7 @@ public static function updateBrand($id, $object) * Delete the given brand. * * @param int $id brand id + * @return hash|bool|mixed */ public static function deleteBrand($id) { @@ -645,10 +659,10 @@ public static function deleteBrand($id) /** * The collection of orders. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function getOrders($filter = false) + public static function getOrders($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/orders' . $filter->toQuery(), 'Order'); @@ -680,6 +694,7 @@ public static function getOrder($id) * delete the order). * * @param int $id order id + * @return hash|bool|mixed */ public static function deleteOrder($id) { @@ -698,10 +713,10 @@ public static function createOrder($object) /** * The list of customers. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function getCustomers($filter = false) + public static function getCustomers($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/customers' . $filter->toQuery(), 'Customer'); @@ -710,10 +725,10 @@ public static function getCustomers($filter = false) /** * The total number of customers in the collection. * - * @param mixed $filter + * @param array $filter * @return int */ - public static function getCustomersCount($filter = false) + public static function getCustomersCount($filter = array()) { $filter = Filter::create($filter); return self::getCount('/customers/count' . $filter->toQuery()); @@ -722,10 +737,10 @@ public static function getCustomersCount($filter = false) /** * Bulk delete customers. * - * @param mixed $filter + * @param array $filter * @return array */ - public static function deleteCustomers($filter = false) + public static function deleteCustomers($filter = array()) { $filter = Filter::create($filter); return self::deleteResource('/customers' . $filter->toQuery()); @@ -746,6 +761,7 @@ public static function getCustomer($id) * Create a new customer from the given data. * * @param mixed $object + * @return hash|bool|mixed */ public static function createCustomer($object) { @@ -757,6 +773,7 @@ public static function createCustomer($object) * * @param int $id customer id * @param mixed $object + * @return hash|bool|mixed */ public static function updateCustomer($id, $object) { @@ -767,6 +784,7 @@ public static function updateCustomer($id, $object) * Delete the given customer. * * @param int $id customer id + * @return hash|bool|mixed */ public static function deleteCustomer($id) { @@ -790,19 +808,30 @@ public static function getCustomerAddresses($id) * @param array $filter * @return array */ - public static function getOptionSets($filter = false) + public static function getOptionSets($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/optionsets' . $filter->toQuery(), 'OptionSet'); } - /** create optionsets **/ + /** + * Create Optionsets + * + * @param $object + * @return hash|bool|mixed + */ public static function createOptionsets($object) { return self::createResource('/optionsets', $object); } - /** connect optionsets options **/ + /** + * Create Optionset Options + * + * @param $object + * @param $id + * @return hash|bool|mixed + */ public static function createOptionsets_Options($object, $id) { return self::createResource('/optionsets/' . $id . '/options', $object); @@ -840,36 +869,72 @@ public static function getOrderStatuses() return self::getCollection('/orderstatuses', 'OrderStatus'); } - /* product skus */ - public static function getSkus($filter = false) + /** + * Get collection of product skus + * + * @param array $filter + * @return mixed + */ + public static function getSkus($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/products/skus' . $filter->toQuery(), 'Sku'); } + /** + * Create sku + * + * @param $object + * @return hash|bool|mixed + */ public static function createSku($object) { return self::createResource('/product/skus', $object); } + /** + * Update sku + * + * @param $id + * @param $object + * @return hash|bool|mixed + */ public static function updateSku($id, $object) { return self::updateResource('/product/skus' . $id, $object); } - /* coupons */ - public static function getCoupons($filter = false) + /** + * Get coupons + * + * @param array $filter + * @return mixed + */ + public static function getCoupons($filter = array()) { $filter = Filter::create($filter); return self::getCollection('/coupons' . $filter->toQuery(), 'Sku'); } + /** + * Create coupon + * + * @param $object + * @return hash|bool|mixed + */ public static function createCoupon($object) { return self::createResource('/coupons', $object); } + /** + * Update coupon + * + * @param $id + * @param $object + * @return hash|bool|mixed + */ public static function updateCoupon($id, $object) { return self::updateResource('/coupons/' . $id, $object); diff --git a/src/Bigcommerce/Api/Filter.php b/src/Bigcommerce/Api/Filter.php index 53f58fa3..c31b901a 100644 --- a/src/Bigcommerce/Api/Filter.php +++ b/src/Bigcommerce/Api/Filter.php @@ -13,7 +13,7 @@ class Filter * Factory method, creates an instance of a filter. * Used to build URLs to collection endpoints. */ - public static function create($filter = false) + public static function create($filter = array()) { if ($filter instanceof self) { return $filter; From 3f69260c68dcc7381cdf5f3de44770d7be57943c Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 06:22:18 -0800 Subject: [PATCH 07/18] BIG-15160: add getOrderProducts --- src/Bigcommerce/Api/Client.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index f83f9e84..1338a3ef 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -689,6 +689,15 @@ public static function getOrder($id) return self::getResource('/orders/' . $id, 'Order'); } + /** + * @param $id + * @return mixed + */ + public static function getOrderProducts($id) + { + return self::getCollection('/orders/' . $id . '/products', 'OrderProduct'); + } + /** * Delete the given order (unlike in the Control Panel, this will permanently * delete the order). From c2d6c070798a1967c84236eab7c5ad52335b5b33 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 10:34:04 -0800 Subject: [PATCH 08/18] BIG-15160: add getProductReviews and ProductReview resource --- src/Bigcommerce/Api/Client.php | 11 +++++++++++ src/Bigcommerce/Api/Resources/ProductReview.php | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/Bigcommerce/Api/Resources/ProductReview.php diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 1338a3ef..79388736 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -360,6 +360,17 @@ public static function createProductCustomField($product_id, $object) return self::createResource('/products/' . $product_id . '/customfields', $object); } + /** + * Gets collection of reviews for a product. + * + * @param $id + * @return mixed + */ + public static function getProductReviews($id) + { + return self::getCollection('/products/' . $id . '/reviews/', 'ProductReview'); + } + /** * Update the given custom field. * diff --git a/src/Bigcommerce/Api/Resources/ProductReview.php b/src/Bigcommerce/Api/Resources/ProductReview.php new file mode 100644 index 00000000..6456fa6c --- /dev/null +++ b/src/Bigcommerce/Api/Resources/ProductReview.php @@ -0,0 +1,14 @@ + Date: Tue, 17 Feb 2015 10:49:40 -0800 Subject: [PATCH 09/18] BIG-15160: update getOrdersCount to accept filters --- src/Bigcommerce/Api/Client.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 79388736..5240c09b 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -682,11 +682,13 @@ public static function getOrders($filter = array()) /** * The number of orders in the collection. * + * @param array $filter * @return int */ - public static function getOrdersCount() + public static function getOrdersCount($filter = array()) { - return self::getCount('/orders/count'); + $filter = Filter::create($filter); + return self::getCount('/orders/count' . $filter->toQuery()); } /** From cd816a54badd7fddb4ad06f49afa614d5f47144f Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 13:01:05 -0800 Subject: [PATCH 10/18] BIG-15160: add updateOrder to client --- src/Bigcommerce/Api/Client.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 5240c09b..87089e68 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -732,6 +732,18 @@ public static function createOrder($object) return self::createResource('/orders', $object); } + /** + * Update the given order. + * + * @param int $id order id + * @param mixed $object fields to update + * @return hash|bool|mixed + */ + public static function updateOrder($id, $object) + { + return self::updateResource('/orders/' . $id, $object); + } + /** * The list of customers. * From 43cd169a15632dcd3ddbe23b8835c3d167b9ef81 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Tue, 17 Feb 2015 14:48:24 -0800 Subject: [PATCH 11/18] BIG-15160: remove dupe cipher information from readme --- README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/README.md b/README.md index 07ff184d..b9c524b0 100644 --- a/README.md +++ b/README.md @@ -75,19 +75,6 @@ Bigcommerce::configure(array( )); ``` -Specifying the SSL cipher ------------------------ - -The API requires that all client SSL connections use the RC4-SHA (rsa_rc4_128_sha) cipher. -The client will set the cipher to "rsa_rc4_128_sha" by default. - -Sometimes the cipher is named different on a server. -The setCipher method can be used to override this setting if required. - -``` -Bigcommerce_Api::setCipher('RC4-SHA'); -``` - Connecting to the store ----------------------- From aa06c8feb8cd094b2fc934b10de8086d4975bceb Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Thu, 19 Feb 2015 13:12:47 -0800 Subject: [PATCH 12/18] BIG-15160: fix merge conflicts and spacing issues --- bigcommerce.php | 1220 ----------------- composer.json | 5 +- src/Bigcommerce/Api.php | 40 - src/Bigcommerce/Api/Client.php | 20 +- .../Api/Resources/ProductImage.php | 4 +- src/Bigcommerce/Api/Resources/Shipment.php | 36 +- src/Bigcommerce/Api/Resources/SkuOption.php | 6 +- test/Unit/Api/ClientTest.php | 288 ++-- .../Api/Resources/AbstractResourceTest.php | 1 + test/Unit/Api/Resources/BrandTest.php | 8 +- test/Unit/Api/Resources/CategoryTest.php | 8 +- test/Unit/Api/Resources/CouponTest.php | 8 +- test/Unit/Api/Resources/CustomerTest.php | 20 +- .../Api/Resources/OptionSetOptionTest.php | 14 +- test/Unit/Api/Resources/OptionSetTest.php | 16 +- test/Unit/Api/Resources/OptionTest.php | 8 +- test/Unit/Api/Resources/OptionValueTest.php | 14 +- test/Unit/Api/Resources/OrderTest.php | 36 +- .../Api/Resources/ProductCustomFieldTest.php | 12 +- test/Unit/Api/Resources/ProductImageTest.php | 8 +- test/Unit/Api/Resources/ProductOptionTest.php | 6 +- test/Unit/Api/Resources/ProductTest.php | 24 +- test/Unit/Api/Resources/ResourceTestBase.php | 48 +- test/Unit/Api/Resources/RuleConditionTest.php | 8 +- test/Unit/Api/Resources/RuleTest.php | 14 +- test/Unit/Api/Resources/ShipmentTest.php | 8 +- test/Unit/Api/Resources/SkuOptionTest.php | 8 +- test/Unit/Api/Resources/SkuTest.php | 14 +- 28 files changed, 308 insertions(+), 1594 deletions(-) delete mode 100644 bigcommerce.php delete mode 100644 src/Bigcommerce/Api.php diff --git a/bigcommerce.php b/bigcommerce.php deleted file mode 100644 index 4e7e09ce..00000000 --- a/bigcommerce.php +++ /dev/null @@ -1,1220 +0,0 @@ -curl = curl_init(); - curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array($this, 'parseHeader')); - curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, array($this, 'parseBody')); - $this->setCipher('rsa_rc4_128_sha'); - if (!ini_get('open_basedir')) { - curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - } else { - $this->followLocation = true; - } - } - public function useXml($option = true) - { - $this->useXml = $option; - } - public function failOnError($option = true) - { - $this->failOnError = $option; - } - public function authenticate($username, $password) - { - curl_setopt($this->curl, CURLOPT_USERPWD, "{$username}:{$password}"); - } - public function setTimeout($timeout) - { - curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout); - curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $timeout); - } - public function useProxy($server, $port = false) - { - curl_setopt($this->curl, CURLOPT_PROXY, $server); - if ($port) { - curl_setopt($this->curl, CURLOPT_PROXYPORT, $port); - } - } - public function verifyPeer($option = false) - { - curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $option); - } - public function setCipher($cipher = 'rsa_rc4_128_sha') - { - curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, $cipher); - } - public function addHeader($header, $value) - { - $this->headers[$header] = "{$header}: {$value}"; - } - private function getContentType() - { - return $this->useXml ? 'application/xml' : 'application/json'; - } - private function initializeRequest() - { - $this->isComplete = false; - $this->responseBody = ''; - $this->responseHeaders = array(); - $this->lastError = false; - $this->addHeader('Accept', $this->getContentType()); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); - } - private function handleResponse() - { - if (curl_errno($this->curl)) { - throw new NetworkError(curl_error($this->curl), curl_errno($this->curl)); - } - $body = $this->useXml ? $this->getBody() : json_decode($this->getBody()); - $status = $this->getStatus(); - if ($status >= 400 && $status <= 499) { - if ($this->failOnError) { - throw new ClientError($body, $status); - } else { - $this->lastError = $body; - return false; - } - } elseif ($status >= 500 && $status <= 599) { - if ($this->failOnError) { - throw new ServerError($body, $status); - } else { - $this->lastError = $body; - return false; - } - } - if ($this->followLocation) { - $this->followRedirectPath(); - } - return $body; - } - public function getLastError() - { - return $this->lastError; - } - private function followRedirectPath() - { - $this->redirectsFollowed++; - if ($this->getStatus() == 301 || $this->getStatus() == 302) { - if ($this->redirectsFollowed < $this->maxRedirects) { - $location = $this->getHeader('Location'); - $forwardTo = parse_url($location); - if (isset($forwardTo['scheme']) && isset($forwardTo['host'])) { - $url = $location; - } else { - $forwardFrom = parse_url(curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL)); - $url = $forwardFrom['scheme'] . '://' . $forwardFrom['host'] . $location; - } - $this->get($url); - } else { - $errorString = 'Too many redirects when trying to follow location.'; - throw new NetworkError($errorString, CURLE_TOO_MANY_REDIRECTS); - } - } else { - $this->redirectsFollowed = 0; - } - } - public function get($url, $query = false) - { - $this->initializeRequest(); - if (is_array($query)) { - $url .= '?' . http_build_query($query); - } - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_HTTPGET, true); - curl_exec($this->curl); - return $this->handleResponse(); - } - public function post($url, $body) - { - $this->addHeader('Content-Type', $this->getContentType()); - if (!is_string($body)) { - $body = json_encode($body); - } - $this->initializeRequest(); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_exec($this->curl); - return $this->handleResponse(); - } - public function head($url) - { - $this->initializeRequest(); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_NOBODY, true); - curl_exec($this->curl); - return $this->handleResponse(); - } - public function put($url, $body) - { - $this->addHeader('Content-Type', $this->getContentType()); - if (!is_string($body)) { - $body = json_encode($body); - } - $this->initializeRequest(); - $handle = tmpfile(); - fwrite($handle, $body); - fseek($handle, 0); - curl_setopt($this->curl, CURLOPT_INFILE, $handle); - curl_setopt($this->curl, CURLOPT_INFILESIZE, strlen($body)); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_PUT, true); - curl_exec($this->curl); - fclose($handle); - return $this->handleResponse(); - } - public function delete($url) - { - $this->initializeRequest(); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_exec($this->curl); - return $this->handleResponse(); - } - private function parseBody($curl, $body) - { - $this->responseBody .= $body; - return strlen($body); - } - private function parseHeader($curl, $headers) - { - if (!$this->responseStatusLine && strpos($headers, 'HTTP/') === 0) { - $this->responseStatusLine = $headers; - } else { - $parts = explode(': ', $headers); - if (isset($parts[1])) { - $this->responseHeaders[$parts[0]] = trim($parts[1]); - } - } - return strlen($headers); - } - public function getStatus() - { - return curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - } - public function getStatusMessage() - { - return $this->responseStatusLine; - } - public function getBody() - { - return $this->responseBody; - } - public function getHeader($header) - { - if (array_key_exists($header, $this->responseHeaders)) { - return $this->responseHeaders[$header]; - } - } - public function getHeaders() - { - return $this->responseHeaders; - } - public function __destruct() - { - curl_close($this->curl); - } -} -namespace Bigcommerce\Api; - -class Error extends \Exception -{ - public function __construct($message, $code) - { - if (is_array($message)) { - $message = $message[0]->message; - } - parent::__construct($message, $code); - } -} -namespace Bigcommerce\Api; - -class ClientError extends Error -{ - public function __toString() - { - return "Client Error ({$this->code}): " . $this->message; - } -} -namespace Bigcommerce\Api; - -class ServerError extends Error -{ - -} -namespace Bigcommerce\Api; - -class NetworkError extends Error -{ - -} -namespace Bigcommerce\Api; - -use Exception; -class Client -{ - private static $store_url; - private static $username; - private static $api_key; - private static $connection; - private static $resource; - private static $path_prefix = '/api/v2'; - public static $api_path; - public static function configure($settings) - { - if (!isset($settings['store_url'])) { - throw new Exception('\'store_url\' must be provided'); - } - if (!isset($settings['username'])) { - throw new Exception('\'username\' must be provided'); - } - if (!isset($settings['api_key'])) { - throw new Exception('\'api_key\' must be provided'); - } - self::$username = $settings['username']; - self::$api_key = $settings['api_key']; - self::$store_url = rtrim($settings['store_url'], '/'); - self::$api_path = self::$store_url . self::$path_prefix; - self::$connection = false; - } - public static function failOnError($option = true) - { - self::connection()->failOnError($option); - } - public static function useXml() - { - self::connection()->useXml(); - } - public static function verifyPeer($option = false) - { - self::connection()->verifyPeer($option); - } - public static function setCipher($cipher = 'rsa_rc4_128_sha') - { - self::connection()->setCipher($cipher); - } - public static function useProxy($host, $port = false) - { - self::connection()->useProxy($host, $port); - } - public static function getLastError() - { - return self::connection()->getLastError(); - } - private static function connection() - { - if (!self::$connection) { - self::$connection = new Connection(); - self::$connection->authenticate(self::$username, self::$api_key); - } - return self::$connection; - } - public static function getCollection($path, $resource = 'Resource') - { - $response = self::connection()->get(self::$api_path . $path); - return self::mapCollection($resource, $response); - } - public static function getResource($path, $resource = 'Resource') - { - $response = self::connection()->get(self::$api_path . $path); - return self::mapResource($resource, $response); - } - public static function getCount($path) - { - $response = self::connection()->get(self::$api_path . $path); - if ($response == false || is_string($response)) { - return $response; - } - return $response->count; - } - public static function createResource($path, $object) - { - if (is_array($object)) { - $object = (object) $object; - } - return self::connection()->post(self::$api_path . $path, $object); - } - public static function updateResource($path, $object) - { - if (is_array($object)) { - $object = (object) $object; - } - return self::connection()->put(self::$api_path . $path, $object); - } - public static function deleteResource($path) - { - return self::connection()->delete(self::$api_path . $path); - } - private static function mapCollection($resource, $object) - { - if ($object == false || is_string($object)) { - return $object; - } - $baseResource = __NAMESPACE__ . '\\' . $resource; - self::$resource = class_exists($baseResource) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; - return array_map(array('self', 'mapCollectionObject'), $object); - } - private static function mapCollectionObject($object) - { - $class = self::$resource; - return new $class($object); - } - private static function mapResource($resource, $object) - { - if ($object == false || is_string($object)) { - return $object; - } - $baseResource = __NAMESPACE__ . '\\' . $resource; - $class = class_exists($baseResource) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource; - return new $class($object); - } - private static function mapCount($object) - { - if ($object == false || is_string($object)) { - return $object; - } - return $object->count; - } - public static function getTime() - { - $response = self::connection()->get(self::$api_path . '/time'); - if ($response == false || is_string($response)) { - return $response; - } - return new \DateTime("@{$response->time}"); - } - public static function getProducts($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/products' . $filter->toQuery(), 'Product'); - } - public static function getProductImages($id) - { - return self::getResource('/products/' . $id . '/images/', 'ProductImage'); - } - public static function getProductCustomFields($id) - { - return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField'); - } - public static function getProductCustomField($product_id, $id) - { - return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField'); - } - public static function createProductCustomField($product_id, $object) - { - return self::createResource('/products/' . $product_id . '/customfields', $object); - } - public static function updateProductCustomField($product_id, $id, $object) - { - return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object); - } - public static function deleteProductCustomField($product_id, $id) - { - return self::deleteResource('/products/' . $product_id . '/customfields/' . $id); - } - public static function getProductsCount($filter = false) - { - $filter = Filter::create($filter); - return self::getCount('/products/count' . $filter->toQuery()); - } - public static function getProduct($id) - { - return self::getResource('/products/' . $id, 'Product'); - } - public static function createProduct($object) - { - return self::createResource('/products', $object); - } - public static function updateProduct($id, $object) - { - return self::updateResource('/products/' . $id, $object); - } - public static function deleteProduct($id) - { - return self::deleteResource('/products/' . $id); - } - public static function getOptions($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/options' . $filter->toQuery(), 'Option'); - } - public static function createOptions($object) - { - return self::createResource('/options', $object); - } - public static function getOptionsCount() - { - return self::getCount('/options/count'); - } - public static function getOption($id) - { - return self::getResource('/options/' . $id, 'Option'); - } - public static function deleteOption($id) - { - return self::deleteResource('/options/' . $id); - } - public static function getOptionValue($option_id, $id) - { - return self::getResource('/options/' . $option_id . '/values/' . $id, 'OptionValue'); - } - public static function getOptionValues($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/options/values' . $filter->toQuery(), 'OptionValue'); - } - public static function getCategories($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/categories' . $filter->toQuery(), 'Category'); - } - public static function getCategoriesCount($filter = false) - { - $filter = Filter::create($filter); - return self::getCount('/categories/count' . $filter->toQuery()); - } - public static function getCategory($id) - { - return self::getResource('/categories/' . $id, 'Category'); - } - public static function createCategory($object) - { - return self::createResource('/categories/', $object); - } - public static function updateCategory($id, $object) - { - return self::updateResource('/categories/' . $id, $object); - } - public static function deleteCategory($id) - { - return self::deleteResource('/categories/' . $id); - } - public static function getBrands($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/brands' . $filter->toQuery(), 'Brand'); - } - public static function getBrandsCount($filter = false) - { - $filter = Filter::create($filter); - return self::getCount('/brands/count' . $filter->toQuery()); - } - public static function getBrand($id) - { - return self::getResource('/brands/' . $id, 'Brand'); - } - public static function createBrand($object) - { - return self::createResource('/brands', $object); - } - public static function updateBrand($id, $object) - { - return self::updateResource('/brands/' . $id, $object); - } - public static function deleteBrand($id) - { - return self::deleteResource('/brands/' . $id); - } - public static function getOrders($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/orders' . $filter->toQuery(), 'Order'); - } - public static function getOrdersCount() - { - return self::getCount('/orders/count'); - } - public static function getOrder($id) - { - return self::getResource('/orders/' . $id, 'Order'); - } - public static function deleteOrder($id) - { - return self::deleteResource('/orders/' . $id); - } - public static function createOrder($object) - { - return self::createResource('/orders', $object); - } - public static function getCustomers($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/customers' . $filter->toQuery(), 'Customer'); - } - public static function getCustomersCount($filter = false) - { - $filter = Filter::create($filter); - return self::getCount('/customers/count' . $filter->toQuery()); - } - public static function deleteCustomers($filter = false) - { - $filter = Filter::create($filter); - return self::deleteResource('/customers' . $filter->toQuery()); - } - public static function getCustomer($id) - { - return self::getResource('/customers/' . $id, 'Customer'); - } - public static function createCustomer($object) - { - return self::createResource('/customers', $object); - } - public static function updateCustomer($id, $object) - { - return self::updateResource('/customers/' . $id, $object); - } - public static function deleteCustomer($id) - { - return self::deleteResource('/customers/' . $id); - } - public static function getCustomerAddresses($id) - { - return self::getCollection('/customers/' . $id . '/addresses', 'Address'); - } - public static function getOptionSets($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/optionsets' . $filter->toQuery(), 'OptionSet'); - } - public static function createOptionsets($object) - { - return self::createResource('/optionsets', $object); - } - public static function createOptionsets_Options($object, $id) - { - return self::createResource('/optionsets/' . $id . '/options', $object); - } - public static function getOptionSetsCount() - { - return self::getCount('/optionsets/count'); - } - public static function getOptionSet($id) - { - return self::getResource('/optionsets/' . $id, 'OptionSet'); - } - public static function getOrderStatuses() - { - return self::getCollection('/orderstatuses', 'OrderStatus'); - } - public static function getSkus($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/products/skus' . $filter->toQuery(), 'Sku'); - } - public static function createSku($object) - { - return self::createResource('/product/skus', $object); - } - public static function updateSku($id, $object) - { - return self::updateResource('/product/skus' . $id, $object); - } - public static function getCoupons($filter = false) - { - $filter = Filter::create($filter); - return self::getCollection('/coupons' . $filter->toQuery(), 'Sku'); - } - public static function createCoupon($object) - { - return self::createResource('/coupons', $object); - } - public static function updateCoupon($id, $object) - { - return self::updateResource('/coupons/' . $id, $object); - } - public static function getRequestLogs() - { - return self::getCollection('/requestlogs'); - } - public static function getStore() - { - $response = self::connection()->get(self::$api_path . '/store'); - return $response; - } - public static function getRequestsRemaining() - { - $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); - if (!$limit) { - $result = self::getTime(); - if (!$result) { - return false; - } - $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining'); - } - return intval($limit); - } -} -namespace Bigcommerce\Api; - -class Filter -{ - private $parameters; - public static function create($filter = false) - { - if ($filter instanceof self) { - return $filter; - } - if (is_int($filter)) { - $filter = array('page' => $filter); - } - return new self($filter); - } - public function __construct($filter = array()) - { - $this->parameters = $filter ? $filter : array(); - } - public function __set($parameter, $value) - { - $this->parameters[$parameter] = $value; - } - public function toQuery() - { - $query = http_build_query($this->parameters); - return $query ? '?' . $query : ''; - } -} -namespace Bigcommerce\Api; - -class Resource -{ - protected $fields; - protected $id; - protected $ignoreOnCreate = array(); - protected $ignoreOnUpdate = array(); - protected $ignoreIfZero = array(); - public function __construct($object = false) - { - if (is_array($object)) { - $object = isset($object[0]) ? $object[0] : false; - } - $this->fields = $object ? $object : new \stdClass(); - $this->id = $object && isset($object->id) ? $object->id : 0; - } - public function __get($field) - { - if (method_exists($this, $field) && isset($this->fields->{$field})) { - return $this->{$field}(); - } - return isset($this->fields->{$field}) ? $this->fields->{$field} : null; - } - public function __set($field, $value) - { - $this->fields->{$field} = $value; - } - public function __isset($field) - { - return isset($this->fields->{$field}); - } - public function getCreateFields() - { - $resource = $this->fields; - foreach ($this->ignoreOnCreate as $field) { - if (isset($resource->{$field})) { - unset($resource->{$field}); - } - } - return $resource; - } - public function getUpdateFields() - { - $resource = $this->fields; - foreach ($this->ignoreOnUpdate as $field) { - if (isset($resource->{$field})) { - unset($resource->{$field}); - } - } - foreach ($resource as $field => $value) { - if ($this->isIgnoredField($field, $value)) { - unset($resource->{$field}); - } - } - return $resource; - } - private function isIgnoredField($field, $value) - { - if ($value === null) { - return true; - } - if (strpos($field, 'date') !== FALSE && $value === '') { - return true; - } - if (in_array($field, $this->ignoreIfZero) && $value === 0) { - return true; - } - return false; - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Address extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Brand extends Resource -{ - protected $ignoreOnCreate = array('id'); - protected $ignoreOnUpdate = array('id'); - public function create() - { - return Client::createBrand($this->getCreateFields()); - } - public function update() - { - return Client::updateBrand($this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Category extends Resource -{ - protected $ignoreOnCreate = array('id', 'parent_category_list'); - protected $ignoreOnUpdate = array('id', 'parent_category_list'); - public function create() - { - return Client::createCategory($this->getCreateFields()); - } - public function update() - { - return Client::updateCategory($this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Coupon extends Resource -{ - protected $ignoreOnCreate = array('id', 'num_uses'); - protected $ignoreOnUpdate = array('id', 'num_uses'); - public function create() - { - return Client::createCoupon($this->getCreateFields()); - } - public function update() - { - return Client::updateCoupon($this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Customer extends Resource -{ - protected $ignoreOnCreate = array('id'); - protected $ignoreOnUpdate = array('id'); - public function addresses() - { - return Client::getCollection($this->fields->addresses->resource, 'Address'); - } - public function create() - { - return Client::createCustomer($this->getCreateFields()); - } - public function update() - { - return Client::updateCustomer($this->id, $this->getUpdateFields()); - } - public function delete() - { - return Client::deleteCustomer($this->id); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class DiscountRule extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Option extends Resource -{ - public function values() - { - return Client::getCollection($this->fields->values->resource, 'OptionValue'); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class OptionSet extends Resource -{ - protected $ignoreOnCreate = array('id'); - protected $ignoreOnUpdate = array('id'); - public function options() - { - return Client::getCollection($this->fields->options->resource, 'OptionSetOption'); - } - public function create() - { - return Client::createResource('/optionsets', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/optionsets/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class OptionSetOption extends Resource -{ - protected $ignoreOnCreate = array('id', 'option_set_id'); - protected $ignoreOnUpdate = array('id', 'option_set_id', 'option_id'); - public function option() - { - return Client::getCollection($this->fields->option->resource); - } - public function create() - { - return Client::createResource('/optionsets/options', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/optionsets/options/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class OptionValue extends Resource -{ - protected $ignoreOnCreate = array('id', 'option_id'); - protected $ignoreOnUpdate = array('id', 'option_id'); - public function option() - { - return self::getResource('/options/' . $this->option_id, 'Option'); - } - public function create() - { - return Client::createResource('/options/' . $this->option_id . '/values', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/options/' . $this->option_id . '/values/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Order extends Resource -{ - public function shipments() - { - return Client::getCollection('/orders/' . $this->id . '/shipments', 'Shipment'); - } - public function products() - { - return Client::getCollection($this->fields->products->resource, 'OrderProduct'); - } - public function shipping_addresses() - { - return Client::getCollection($this->fields->shipping_addresses->resource, 'Address'); - } - public function coupons() - { - return Client::getCollection($this->fields->coupons->resource, 'Coupon'); - } - public function update() - { - $order = new \stdClass(); - $order->status_id = $this->status_id; - $order->is_deleted = $this->is_deleted; - Client::updateResource('/orders/' . $this->id, $order); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class OrderProduct extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class OrderStatus extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Product extends Resource -{ - protected $ignoreOnCreate = array('date_created', 'date_modified'); - protected $ignoreOnUpdate = array('id', 'rating_total', 'rating_count', 'date_created', 'date_modified', 'date_last_imported', 'number_sold', 'brand', 'images', 'discount_rules', 'configurable_fields', 'custom_fields', 'videos', 'skus', 'rules', 'option_set', 'options', 'tax_class'); - protected $ignoreIfZero = array('tax_class_id'); - public function brand() - { - return Client::getResource($this->fields->brand->resource, 'Brand'); - } - public function images() - { - return Client::getCollection($this->fields->images->resource, 'ProductImage'); - } - public function skus() - { - return Client::getCollection($this->fields->skus->resource, 'Sku'); - } - public function rules() - { - return Client::getCollection($this->fields->rules->resource, 'Rule'); - } - public function videos() - { - return Client::getCollection($this->fields->videos->resource, 'ProductVideo'); - } - public function custom_fields() - { - return Client::getCollection($this->fields->custom_fields->resource, 'ProductCustomField'); - } - public function configurable_fields() - { - return Client::getCollection($this->fields->configurable_fields->resource, 'ProductConfigurableField'); - } - public function discount_rules() - { - return Client::getCollection($this->fields->discount_rules->resource, 'DiscountRule'); - } - public function option_set() - { - return Client::getResource($this->fields->option_set->resource, 'OptionSet'); - } - public function options() - { - return Client::getCollection('/products/' . $this->id . '/options', 'ProductOption'); - } - public function create() - { - return Client::createProduct($this->getCreateFields()); - } - public function update() - { - return Client::updateProduct($this->id, $this->getUpdateFields()); - } - public function delete() - { - return Client::deleteProduct($this->id); - } - public function tax_class() - { - return Client::getResource($this->fields->tax_class->resource, 'TaxClass'); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class ProductConfigurableField extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class ProductCustomField extends Resource -{ - protected $ignoreOnCreate = array('id', 'product_id'); - protected $ignoreOnUpdate = array('id', 'product_id'); - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/customfields', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/customfields/' . $this->id, $this->getUpdateFields()); - } - public function delete() - { - Client::deleteResource('/products/' . $this->product_id . '/customfields/' . $this->id); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class ProductImage extends Resource -{ - protected $ignoreOnCreate = array('id', 'date_created', 'product_id'); - protected $ignoreOnUpdate = array('id', 'date_created', 'product_id'); - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/images', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/images/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class ProductOption extends Resource -{ - public function option() - { - return self::getResource('/options/' . $this->option_id, 'Option'); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class ProductVideo extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class RequestLog extends Resource -{ - -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Rule extends Resource -{ - protected $ignoreOnCreate = array('id', 'product_id'); - protected $ignoreOnUpdate = array('id', 'product_id'); - public function conditions() - { - $conditions = Client::getCollection($this->fields->conditions->resource, 'RuleCondition'); - foreach ($conditions as $condition) { - $condition->product_id = $this->product_id; - } - return $conditions; - } - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/rules', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/rules/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class RuleCondition extends Resource -{ - protected $ignoreOnCreate = array('id'); - protected $ignoreOnUpdate = array('id', 'rule_id'); - public $product_id; - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/rules/' . $this->rule_id . '/conditions', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/rules/' . $this->rule_id . '/conditions/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Shipment extends Resource -{ - protected $ignoreOnCreate = array('id', 'order_id', 'date_created', 'customer_id', 'shipping_method'); - protected $ignoreOnUpdate = array('id', 'order_id', 'date_created', 'customer_id', 'shipping_method', 'items'); - public function create() - { - return Client::createResource('/orders/' . $this->order_id . '/shipments', $this->getCreateFields()); - } - public function update() - { - return Client::createResource('/orders/' . $this->order_id . '/shipments' . $this->id, $this->getCreateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class Sku extends Resource -{ - protected $ignoreOnCreate = array('product_id'); - protected $ignoreOnUpdate = array('id', 'product_id'); - public function options() - { - $options = Client::getCollection($this->fields->options->resource, 'SkuOption'); - foreach ($options as $option) { - $option->product_id = $this->product_id; - } - return $options; - } - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/skus', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->id, $this->getUpdateFields()); - } -} -namespace Bigcommerce\Api\Resources; - -use Bigcommerce\Api\Resource; -use Bigcommerce\Api\Client; -class SkuOption extends Resource -{ - protected $ignoreOnCreate = array('id'); - protected $ignoreOnUpdate = array('id', 'sku_id'); - public $product_id; - public function create() - { - return Client::createResource('/products/' . $this->product_id . '/skus/' . $this->sku_id . '/options', $this->getCreateFields()); - } - public function update() - { - Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->sku_id . '/options/' . $this->id, $this->getUpdateFields()); - } -} \ No newline at end of file diff --git a/composer.json b/composer.json index 74cdeba9..0e19140d 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "bigcommerce/api", "type": "library", "description": "Enables PHP applications to communicate with the Bigcommerce API.", - "keywords": ["api","http","rest","ecommerce","business"], + "keywords": ["api", "http", "rest", "ecommerce", "business"], "homepage": "http://developer.bigcommerce.com", "license": "MIT", "authors": [ @@ -27,9 +27,6 @@ "Bigcommerce\\Test\\": "test/" } }, - "archive": { - "exclude": ["bin", "bigcommerce.php"] - }, "scripts": { "test": "phpunit" } diff --git a/src/Bigcommerce/Api.php b/src/Bigcommerce/Api.php deleted file mode 100644 index 5b47a7c4..00000000 --- a/src/Bigcommerce/Api.php +++ /dev/null @@ -1,40 +0,0 @@ -toQuery(), 'Sku'); + return self::getCollection('/coupons' . $filter->toQuery(), 'Coupon'); } /** @@ -979,7 +989,7 @@ public static function updateCoupon($id, $object) */ public static function getRequestLogs() { - return self::getCollection('/requestlogs'); + return self::getCollection('/requestlogs', 'RequestLog'); } public static function getStore() diff --git a/src/Bigcommerce/Api/Resources/ProductImage.php b/src/Bigcommerce/Api/Resources/ProductImage.php index a906828d..2add0709 100644 --- a/src/Bigcommerce/Api/Resources/ProductImage.php +++ b/src/Bigcommerce/Api/Resources/ProductImage.php @@ -24,11 +24,11 @@ class ProductImage extends Resource public function create() { - return Client::createResource('/products/' . $this->fields->product_id . '/images' , $this->getCreateFields()); + return Client::createResource('/products/' . $this->fields->product_id . '/images', $this->getCreateFields()); } public function update() { - Client::updateResource('/products/' . $this->fields->product_id . '/images/' . $this->id , $this->getUpdateFields()); + Client::updateResource('/products/' . $this->fields->product_id . '/images/' . $this->id, $this->getUpdateFields()); } } diff --git a/src/Bigcommerce/Api/Resources/Shipment.php b/src/Bigcommerce/Api/Resources/Shipment.php index ceed1efd..3ba233f2 100644 --- a/src/Bigcommerce/Api/Resources/Shipment.php +++ b/src/Bigcommerce/Api/Resources/Shipment.php @@ -7,37 +7,6 @@ class Shipment extends Resource { -<<<<<<< HEAD - - protected $ignoreOnCreate = array( - 'id', - 'order_id', - 'date_created', - 'customer_id', - 'shipping_method', - ); - - protected $ignoreOnUpdate = array( - 'id', - 'order_id', - 'date_created', - 'customer_id', - 'shipping_method', - 'items', - ); - - public function create() - { - return Client::createResource('/orders/' . $this->fields->order_id . '/shipments', $this->getCreateFields()); - } - - public function update() - { - return Client::updateResource('/orders/' . $this->fields->order_id . '/shipments/' . $this->id, $this->getUpdateFields()); - } - -} -======= protected $ignoreOnCreate = array( 'id', 'order_id', @@ -57,12 +26,11 @@ public function update() public function create() { - return Client::createResource('/orders/' . $this->order_id . '/shipments', $this->getCreateFields()); + return Client::createResource('/orders/' . $this->fields->order_id . '/shipments', $this->getCreateFields()); } public function update() { - return Client::createResource('/orders/' . $this->order_id . '/shipments' . $this->id, $this->getCreateFields()); + return Client::updateResource('/orders/' . $this->fields->order_id . '/shipments/' . $this->id, $this->getUpdateFields()); } } ->>>>>>> BIG-15160: standardize spacing diff --git a/src/Bigcommerce/Api/Resources/SkuOption.php b/src/Bigcommerce/Api/Resources/SkuOption.php index 73b002cb..88ab7524 100644 --- a/src/Bigcommerce/Api/Resources/SkuOption.php +++ b/src/Bigcommerce/Api/Resources/SkuOption.php @@ -19,15 +19,13 @@ class SkuOption extends Resource 'sku_id', ); - public $product_id; - public function create() { - return Client::createResource('/products/' . $this->product_id . '/skus/' . $this->fields->sku_id . '/options', $this->getCreateFields()); + return Client::createResource('/products/' . $this->fields->product_id . '/skus/' . $this->fields->sku_id . '/options', $this->getCreateFields()); } public function update() { - Client::updateResource('/products/' . $this->product_id . '/skus/' . $this->fields->sku_id . '/options/' . $this->id, $this->getUpdateFields()); + Client::updateResource('/products/' . $this->fields->product_id . '/skus/' . $this->fields->sku_id . '/options/' . $this->id, $this->getUpdateFields()); } } diff --git a/test/Unit/Api/ClientTest.php b/test/Unit/Api/ClientTest.php index 3d27c36f..16b86a35 100644 --- a/test/Unit/Api/ClientTest.php +++ b/test/Unit/Api/ClientTest.php @@ -11,31 +11,31 @@ class ClientTest extends \PHPUnit_Framework_TestCase public function setUp() { $methods = array( - 'useXml', - 'failOnError', - 'authenticate', - 'setTimeout', - 'useProxy', - 'verifyPeer', - 'setCipher', - 'addHeader', - 'getLastError', - 'get', - 'post', - 'head', - 'put', - 'delete', - 'getStatus', - 'getStatusMessage', - 'getBody', - 'getHeader', - 'getHeaders', - '__destruct' - ); + 'useXml', + 'failOnError', + 'authenticate', + 'setTimeout', + 'useProxy', + 'verifyPeer', + 'setCipher', + 'addHeader', + 'getLastError', + 'get', + 'post', + 'head', + 'put', + 'delete', + 'getStatus', + 'getStatusMessage', + 'getBody', + 'getHeader', + 'getHeaders', + '__destruct' + ); $this->connection = $this->getMockBuilder('Bigcommerce\\Api\\Connection') - ->disableOriginalConstructor() - ->setMethods($methods) - ->getMock(); + ->disableOriginalConstructor() + ->setMethods($methods) + ->getMock(); Client::setConnection($this->connection); } @@ -60,11 +60,11 @@ public function testConfigureRequiresApiKey() public function testFailOnErrorPassesThroughToConnection() { $this->connection->expects($this->exactly(2)) - ->method('failOnError') - ->withConsecutive( - array(true), - array(false) - ); + ->method('failOnError') + ->withConsecutive( + array(true), + array(false) + ); Client::failOnError(true); Client::failOnError(false); } @@ -72,7 +72,7 @@ public function testFailOnErrorPassesThroughToConnection() public function testUseXmlPassesThroughToConnection() { $this->connection->expects($this->once()) - ->method('useXml'); + ->method('useXml'); Client::useXml(); } @@ -80,11 +80,11 @@ public function testUseXmlPassesThroughToConnection() public function testVerifyPeerPassesThroughToConnection() { $this->connection->expects($this->exactly(2)) - ->method('verifyPeer') - ->withConsecutive( - array(true), - array(false) - ); + ->method('verifyPeer') + ->withConsecutive( + array(true), + array(false) + ); Client::verifyPeer(true); Client::verifyPeer(false); } @@ -92,11 +92,11 @@ public function testVerifyPeerPassesThroughToConnection() public function testSetCipherPassesThroughToConnection() { $this->connection->expects($this->exactly(2)) - ->method('setCipher') - ->withConsecutive( - array('rsa'), - array('rsa_rc4_128_sha') // this is the default value - ); + ->method('setCipher') + ->withConsecutive( + array('rsa'), + array('rsa_rc4_128_sha') // this is the default value + ); Client::setCipher('rsa'); Client::setCipher(); } @@ -104,8 +104,8 @@ public function testSetCipherPassesThroughToConnection() public function testUseProxyPassesThroughToConnection() { $this->connection->expects($this->once()) - ->method('useProxy') - ->with('127.0.0.1', 6559); + ->method('useProxy') + ->with('127.0.0.1', 6559); Client::useProxy('127.0.0.1', 6559); } @@ -113,8 +113,8 @@ public function testUseProxyPassesThroughToConnection() public function testGetLastErrorGetsErrorFromConnection() { $this->connection->expects($this->once()) - ->method('getLastError') - ->will($this->returnValue(5)); + ->method('getLastError') + ->will($this->returnValue(5)); $this->assertSame(5, Client::getLastError()); } @@ -122,9 +122,9 @@ public function testGetLastErrorGetsErrorFromConnection() public function testGetResourceReturnsSpecifiedType() { $this->connection->expects($this->once()) - ->method('get') - ->with('http://storeurl/api/v2/whatever', false) - ->will($this->returnValue(array(array()))); + ->method('get') + ->with('http://storeurl/api/v2/whatever', false) + ->will($this->returnValue(array(array()))); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -135,9 +135,9 @@ public function testGetResourceReturnsSpecifiedType() public function testGetCountReturnsSpecifiedCount() { $this->connection->expects($this->once()) - ->method('get') - ->with('http://storeurl/api/v2/whatever', false) - ->will($this->returnValue((object)array('count' => 5))); + ->method('get') + ->with('http://storeurl/api/v2/whatever', false) + ->will($this->returnValue((object)array('count' => 5))); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -148,9 +148,9 @@ public function testGetCountReturnsSpecifiedCount() public function testGetCollectionReturnsCollectionOfSpecifiedTypes() { $this->connection->expects($this->once()) - ->method('get') - ->with('http://storeurl/api/v2/whatever', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('http://storeurl/api/v2/whatever', false) + ->will($this->returnValue(array(array(), array()))); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -165,9 +165,9 @@ public function testCreateResourcePostsToTheRightPlace() { $new = array(rand() => rand()); $this->connection->expects($this->once()) - ->method('post') - ->with('http://storeurl/api/v2/whatever', (object)$new) - ->will($this->returnValue($new)); + ->method('post') + ->with('http://storeurl/api/v2/whatever', (object)$new) + ->will($this->returnValue($new)); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -179,9 +179,9 @@ public function testUpdateResourcePutsToTheRightPlace() { $update = array(rand() => rand()); $this->connection->expects($this->once()) - ->method('put') - ->with('http://storeurl/api/v2/whatever', (object)$update) - ->will($this->returnValue($update)); + ->method('put') + ->with('http://storeurl/api/v2/whatever', (object)$update) + ->will($this->returnValue($update)); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -192,9 +192,9 @@ public function testUpdateResourcePutsToTheRightPlace() public function testDeleteResourceDeletesToTheRightPlace() { $this->connection->expects($this->once()) - ->method('delete') - ->with('http://storeurl/api/v2/whatever') - ->will($this->returnValue(5)); + ->method('delete') + ->with('http://storeurl/api/v2/whatever') + ->will($this->returnValue(5)); Client::configure(array('store_url' => 'http://storeurl/', 'username' => 'whatever', 'api_key' => 'whatever')); Client::setConnection($this->connection); // re-set the connection since Client::configure unsets it @@ -206,9 +206,9 @@ public function testGetTimeReturnsTheExpectedTime() { $now = new \DateTime(); $this->connection->expects($this->once()) - ->method('get') - ->with('/time', false) - ->will($this->returnValue((object)array('time' => $now->format('U')))); + ->method('get') + ->with('/time', false) + ->will($this->returnValue((object)array('time' => $now->format('U')))); $this->assertEquals($now, Client::getTime()); } @@ -217,9 +217,9 @@ public function testGetStoreReturnsTheResultBodyDirectly() { $body = array(rand() => rand()); $this->connection->expects($this->once()) - ->method('get') - ->with('/store') - ->will($this->returnValue($body)); + ->method('get') + ->with('/store') + ->will($this->returnValue($body)); $this->assertSame($body, Client::getStore()); } @@ -227,8 +227,8 @@ public function testGetStoreReturnsTheResultBodyDirectly() public function testGetRequestsRemainingReturnsTheValueFromTheLastHeader() { $this->connection->expects($this->once()) - ->method('getHeader') - ->will($this->returnValue('12345')); + ->method('getHeader') + ->will($this->returnValue('12345')); $this->assertSame(12345, Client::getRequestsRemaining()); } @@ -236,13 +236,13 @@ public function testGetRequestsRemainingReturnsTheValueFromTheLastHeader() public function testGetRequestsRemainingRequestsTimeWhenNoValueAvailable() { $this->connection->expects($this->exactly(2)) - ->method('getHeader') - ->will($this->onConsecutiveCalls(false, '12345')); + ->method('getHeader') + ->will($this->onConsecutiveCalls(false, '12345')); $this->connection->expects($this->once()) - ->method('get') - ->with('/time', false) - ->will($this->returnValue((object)array('time' => time()))); + ->method('get') + ->with('/time', false) + ->will($this->returnValue((object)array('time' => time()))); $this->assertSame(12345, Client::getRequestsRemaining()); } @@ -251,17 +251,17 @@ public function collections() { return array( // path function classname - array('products', 'getProducts', 'Product'), - array('brands', 'getBrands', 'Brand'), - array('orders', 'getOrders', 'Order'), - array('customers', 'getCustomers', 'Customer'), - array('coupons', 'getCoupons', 'Coupon'), + array('products', 'getProducts', 'Product'), + array('brands', 'getBrands', 'Brand'), + array('orders', 'getOrders', 'Order'), + array('customers', 'getCustomers', 'Customer'), + array('coupons', 'getCoupons', 'Coupon'), array('orderstatuses', 'getOrderStatuses', 'OrderStatus'), - array('categories', 'getCategories', 'Category'), - array('options', 'getOptions', 'Option'), - array('optionsets', 'getOptionSets', 'OptionSet'), - array('products/skus', 'getSkus', 'Sku'), - array('requestlogs', 'getRequestLogs', 'RequestLog'), + array('categories', 'getCategories', 'Category'), + array('options', 'getOptions', 'Option'), + array('optionsets', 'getOptionSets', 'OptionSet'), + array('products/skus', 'getSkus', 'Sku'), + array('requestlogs', 'getRequestLogs', 'RequestLog'), ); } @@ -271,9 +271,9 @@ public function collections() public function testGettingASpecificResourceReturnsACollectionOfThatResource($path, $fnName, $class) { $this->connection->expects($this->once()) - ->method('get') - ->with('/' . $path, false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/' . $path, false) + ->will($this->returnValue(array(array(), array()))); $collection = Client::$fnName(); $this->assertInternalType('array', $collection); @@ -292,9 +292,9 @@ public function testGettingTheCountOfACollectionReturnsThatCollectionsCount($pat } $this->connection->expects($this->once()) - ->method('get') - ->with('/' . $path . '/count', false) - ->will($this->returnValue((object)array('count' => 7))); + ->method('get') + ->with('/' . $path . '/count', false) + ->will($this->returnValue((object)array('count' => 7))); $fnName .= 'Count'; $count = Client::$fnName(); @@ -305,14 +305,14 @@ public function resources() { return array( // path function classname - array('products', '%sProduct', 'Product'), - array('brands', '%sBrand', 'Brand'), - array('orders', '%sOrder', 'Order'), - array('customers', '%sCustomer', 'Customer'), - array('categories', '%sCategory', 'Category'), - array('options', '%sOption', 'Option'), - array('optionsets', '%sOptionSet', 'OptionSet'), - array('coupons', '%sCoupon', 'Coupon'), + array('products', '%sProduct', 'Product'), + array('brands', '%sBrand', 'Brand'), + array('orders', '%sOrder', 'Order'), + array('customers', '%sCustomer', 'Customer'), + array('categories', '%sCategory', 'Category'), + array('options', '%sOption', 'Option'), + array('optionsets', '%sOptionSet', 'OptionSet'), + array('coupons', '%sCoupon', 'Coupon'), ); } @@ -326,9 +326,9 @@ public function testGettingASpecificResourceReturnsThatResource($path, $fnName, } $this->connection->expects($this->once()) - ->method('get') - ->with('/' . $path . '/1', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/' . $path . '/1', false) + ->will($this->returnValue(array(array(), array()))); $fnName = sprintf($fnName, 'get'); $resource = Client::$fnName(1); @@ -345,8 +345,8 @@ public function testCreatingASpecificResourcePostsToThatResource($path, $fnName, } $this->connection->expects($this->once()) - ->method('post') - ->with('/' . $path, (object)array()); + ->method('post') + ->with('/' . $path, (object)array()); $fnName = sprintf($fnName, 'create'); $resource = Client::$fnName(array()); @@ -362,8 +362,8 @@ public function testDeletingASpecificResourceDeletesToThatResource($path, $fnNam } $this->connection->expects($this->once()) - ->method('delete') - ->with('/' . $path . '/1'); + ->method('delete') + ->with('/' . $path . '/1'); $fnName = sprintf($fnName, 'delete'); $resource = Client::$fnName(1); @@ -379,8 +379,8 @@ public function testUpdatingASpecificResourcePutsToThatResource($path, $fnName, } $this->connection->expects($this->once()) - ->method('put') - ->with('/' . $path . '/1'); + ->method('put') + ->with('/' . $path . '/1'); $fnName = sprintf($fnName, 'update'); $resource = Client::$fnName(1, array()); @@ -390,8 +390,8 @@ public function testUpdatingASpecificResourcePutsToThatResource($path, $fnName, public function testCreatingASkuPostsToTheSkuResource() { $this->connection->expects($this->once()) - ->method('post') - ->with('/product/skus', (object)array()); + ->method('post') + ->with('/product/skus', (object)array()); $resource = Client::createSku(array()); } @@ -399,8 +399,8 @@ public function testCreatingASkuPostsToTheSkuResource() public function testUpdatingASkuPutsToTheSkuResource() { $this->connection->expects($this->once()) - ->method('put') - ->with('/product/skus/1', (object)array()); + ->method('put') + ->with('/product/skus/1', (object)array()); $resource = Client::updateSku(1, array()); } @@ -408,9 +408,9 @@ public function testUpdatingASkuPutsToTheSkuResource() public function testGettingProductImagesReturnsCollectionOfProductImages() { $this->connection->expects($this->once()) - ->method('get') - ->with('/products/1/images/', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/products/1/images/', false) + ->will($this->returnValue(array(array(), array()))); $collection = Client::getProductImages(1); $this->assertInternalType('array', $collection); @@ -422,9 +422,9 @@ public function testGettingProductImagesReturnsCollectionOfProductImages() public function testGettingProductCustomFieldsReturnsCollectionOfProductCustomFields() { $this->connection->expects($this->once()) - ->method('get') - ->with('/products/1/customfields/', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/products/1/customfields/', false) + ->will($this->returnValue(array(array(), array()))); $collection = Client::getProductCustomFields(1); $this->assertInternalType('array', $collection); @@ -436,9 +436,9 @@ public function testGettingProductCustomFieldsReturnsCollectionOfProductCustomFi public function testGettingASpecifiedProductCustomFieldReturnsThatProductCustomField() { $this->connection->expects($this->once()) - ->method('get') - ->with('/products/1/customfields/1', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/products/1/customfields/1', false) + ->will($this->returnValue(array(array(), array()))); $resource = Client::getProductCustomField(1, 1); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\ProductCustomField', $resource); @@ -447,9 +447,9 @@ public function testGettingASpecifiedProductCustomFieldReturnsThatProductCustomF public function testGettingASpecifiedOptionValueReturnsThatOptionValue() { $this->connection->expects($this->once()) - ->method('get') - ->with('/options/1/values/1', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/options/1/values/1', false) + ->will($this->returnValue(array(array(), array()))); $resource = Client::getOptionValue(1, 1); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\OptionValue', $resource); @@ -458,9 +458,9 @@ public function testGettingASpecifiedOptionValueReturnsThatOptionValue() public function testGettingCustomerAddressesReturnsCollectionOfCustomerAddresses() { $this->connection->expects($this->once()) - ->method('get') - ->with('/customers/1/addresses', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/customers/1/addresses', false) + ->will($this->returnValue(array(array(), array()))); $collection = Client::getCustomerAddresses(1); $this->assertInternalType('array', $collection); @@ -472,9 +472,9 @@ public function testGettingCustomerAddressesReturnsCollectionOfCustomerAddresses public function testGettingOptionValuesReturnsCollectionOfOptionValues() { $this->connection->expects($this->once()) - ->method('get') - ->with('/options/values', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/options/values', false) + ->will($this->returnValue(array(array(), array()))); $collection = Client::getOptionValues(); $this->assertInternalType('array', $collection); @@ -486,8 +486,8 @@ public function testGettingOptionValuesReturnsCollectionOfOptionValues() public function testCreatingAnOptionSetPostsToTheOptionSetsResource() { $this->connection->expects($this->once()) - ->method('post') - ->with('/optionsets', (object)array()); + ->method('post') + ->with('/optionsets', (object)array()); $resource = Client::createOptionsets(array()); } @@ -495,8 +495,8 @@ public function testCreatingAnOptionSetPostsToTheOptionSetsResource() public function testCreatingAnOptionPostsToTheOptionResource() { $this->connection->expects($this->once()) - ->method('post') - ->with('/options', (object)array()); + ->method('post') + ->with('/options', (object)array()); $resource = Client::createOptions(array()); } @@ -504,8 +504,8 @@ public function testCreatingAnOptionPostsToTheOptionResource() public function testCreatingAnOptionSetsOptionPostsToTheOptionSetsOptionResource() { $this->connection->expects($this->once()) - ->method('post') - ->with('/optionsets/1/options', (object)array()); + ->method('post') + ->with('/optionsets/1/options', (object)array()); $resource = Client::createOptionsets_Options(array(), 1); } @@ -513,8 +513,8 @@ public function testCreatingAnOptionSetsOptionPostsToTheOptionSetsOptionResource public function testCreatingAProductCustomFieldPostsToTheProductCustomFieldResource() { $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/customfields', (object)array()); + ->method('post') + ->with('/products/1/customfields', (object)array()); $resource = Client::createProductCustomField(1, array()); } @@ -522,8 +522,8 @@ public function testCreatingAProductCustomFieldPostsToTheProductCustomFieldResou public function testUpdatingAProductCustomFieldPutsToTheProductCustomFieldResource() { $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/customfields/1', (object)array()); + ->method('put') + ->with('/products/1/customfields/1', (object)array()); Client::updateProductCustomField(1, 1, array()); } @@ -531,8 +531,8 @@ public function testUpdatingAProductCustomFieldPutsToTheProductCustomFieldResour public function testDeletingAProductCustomFieldDeletesToTheProductCustomFieldResource() { $this->connection->expects($this->once()) - ->method('delete') - ->with('/products/1/customfields/1'); + ->method('delete') + ->with('/products/1/customfields/1'); Client::deleteProductCustomField(1, 1); } @@ -540,8 +540,8 @@ public function testDeletingAProductCustomFieldDeletesToTheProductCustomFieldRes public function testDeletingACustomerDeletesToTheCustomerResource() { $this->connection->expects($this->once()) - ->method('delete') - ->with('/customers'); + ->method('delete') + ->with('/customers'); Client::deleteCustomers(); } diff --git a/test/Unit/Api/Resources/AbstractResourceTest.php b/test/Unit/Api/Resources/AbstractResourceTest.php index ef060ce8..fcfa6774 100644 --- a/test/Unit/Api/Resources/AbstractResourceTest.php +++ b/test/Unit/Api/Resources/AbstractResourceTest.php @@ -7,6 +7,7 @@ Because the Resource class is abstract, test it through one of its' children. We've picked Product here because it exhibits all behaviors of the Resource object. */ + class AbstractResourceTest extends \PHPUnit_Framework_TestCase { public function testGetCreateFieldsReturnsAllFieldsNotMarkedIgnore() diff --git a/test/Unit/Api/Resources/BrandTest.php b/test/Unit/Api/Resources/BrandTest.php index d76738e5..430d3b85 100644 --- a/test/Unit/Api/Resources/BrandTest.php +++ b/test/Unit/Api/Resources/BrandTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $brand = new Brand(); $this->connection->expects($this->once()) - ->method('post') - ->with('/brands', $brand->getCreateFields()); + ->method('post') + ->with('/brands', $brand->getCreateFields()); $brand->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $brand = new Brand((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/brands/1', $brand->getUpdateFields()); + ->method('put') + ->with('/brands/1', $brand->getUpdateFields()); $brand->update(); } diff --git a/test/Unit/Api/Resources/CategoryTest.php b/test/Unit/Api/Resources/CategoryTest.php index 28d87efc..90e93040 100644 --- a/test/Unit/Api/Resources/CategoryTest.php +++ b/test/Unit/Api/Resources/CategoryTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $category = new Category(); $this->connection->expects($this->once()) - ->method('post') - ->with('/categories', $category->getCreateFields()); + ->method('post') + ->with('/categories', $category->getCreateFields()); $category->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $category = new Category((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/categories/1', $category->getUpdateFields()); + ->method('put') + ->with('/categories/1', $category->getUpdateFields()); $category->update(); } diff --git a/test/Unit/Api/Resources/CouponTest.php b/test/Unit/Api/Resources/CouponTest.php index 05272cf6..a3992a1e 100644 --- a/test/Unit/Api/Resources/CouponTest.php +++ b/test/Unit/Api/Resources/CouponTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $coupon = new Coupon(); $this->connection->expects($this->once()) - ->method('post') - ->with('/coupons', $coupon->getCreateFields()); + ->method('post') + ->with('/coupons', $coupon->getCreateFields()); $coupon->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $coupon = new Coupon((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/coupons/1', $coupon->getUpdateFields()); + ->method('put') + ->with('/coupons/1', $coupon->getUpdateFields()); $coupon->update(); } diff --git a/test/Unit/Api/Resources/CustomerTest.php b/test/Unit/Api/Resources/CustomerTest.php index 835828e2..f6247cf5 100644 --- a/test/Unit/Api/Resources/CustomerTest.php +++ b/test/Unit/Api/Resources/CustomerTest.php @@ -10,11 +10,11 @@ public function testAddressesPassesThroughToConnection() { $customer = new Customer((object)array('addresses' => (object)array('resource' => '/customers/1/addresses'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/customers/1/addresses') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/customers/1/addresses') + ->will($this->returnValue(array(array(), array()))); - foreach($customer->addresses as $address) { + foreach ($customer->addresses as $address) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Address', $address); } } @@ -23,8 +23,8 @@ public function testCreatePassesThroughToConnection() { $customer = new Customer(); $this->connection->expects($this->once()) - ->method('post') - ->with('/customers', $customer->getCreateFields()); + ->method('post') + ->with('/customers', $customer->getCreateFields()); $customer->create(); } @@ -33,8 +33,8 @@ public function testUpdatePassesThroughToConnection() { $customer = new Customer((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/customers/1', $customer->getUpdateFields()); + ->method('put') + ->with('/customers/1', $customer->getUpdateFields()); $customer->update(); } @@ -43,8 +43,8 @@ public function testDeletePassesThroughToConnection() { $customer = new Customer((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('delete') - ->with('/customers/1'); + ->method('delete') + ->with('/customers/1'); $customer->delete(); } diff --git a/test/Unit/Api/Resources/OptionSetOptionTest.php b/test/Unit/Api/Resources/OptionSetOptionTest.php index 179390c4..ac52b631 100644 --- a/test/Unit/Api/Resources/OptionSetOptionTest.php +++ b/test/Unit/Api/Resources/OptionSetOptionTest.php @@ -10,9 +10,9 @@ public function testOptionPassesThroughToConnection() { $optionsetoption = new OptionSetOption((object)array('option' => (object)array('resource' => '/options/1'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/options/1') - ->will($this->returnValue(array(array()))); + ->method('get') + ->with('/options/1') + ->will($this->returnValue(array(array()))); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Option', $optionsetoption->option); } @@ -21,8 +21,8 @@ public function testCreatePassesThroughToConnection() { $optionsetoption = new OptionSetOption(); $this->connection->expects($this->once()) - ->method('post') - ->with('/optionsets/options', $optionsetoption->getCreateFields()); + ->method('post') + ->with('/optionsets/options', $optionsetoption->getCreateFields()); $optionsetoption->create(); } @@ -31,8 +31,8 @@ public function testUpdatePassesThroughToConnection() { $optionsetoption = new OptionSetOption((object)(array('id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/optionsets/options/1', $optionsetoption->getUpdateFields()); + ->method('put') + ->with('/optionsets/options/1', $optionsetoption->getUpdateFields()); $optionsetoption->update(); } diff --git a/test/Unit/Api/Resources/OptionSetTest.php b/test/Unit/Api/Resources/OptionSetTest.php index 09e7ff6b..8fa2e501 100644 --- a/test/Unit/Api/Resources/OptionSetTest.php +++ b/test/Unit/Api/Resources/OptionSetTest.php @@ -10,11 +10,11 @@ public function testOptionsPassesThroughToConnection() { $optionset = new OptionSet((object)array('options' => (object)array('resource' => '/optionsets/1/options'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/optionsets/1/options') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/optionsets/1/options') + ->will($this->returnValue(array(array(), array()))); - foreach($optionset->options as $value) { + foreach ($optionset->options as $value) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\OptionSetOption', $value); } } @@ -23,8 +23,8 @@ public function testCreatePassesThroughToConnection() { $optionset = new OptionSet(); $this->connection->expects($this->once()) - ->method('post') - ->with('/optionsets', $optionset->getCreateFields()); + ->method('post') + ->with('/optionsets', $optionset->getCreateFields()); $optionset->create(); } @@ -33,8 +33,8 @@ public function testUpdatePassesThroughToConnection() { $optionset = new OptionSet((object)array('id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/optionsets/1', $optionset->getUpdateFields()); + ->method('put') + ->with('/optionsets/1', $optionset->getUpdateFields()); $optionset->update(); } diff --git a/test/Unit/Api/Resources/OptionTest.php b/test/Unit/Api/Resources/OptionTest.php index 184504a7..603fa24d 100644 --- a/test/Unit/Api/Resources/OptionTest.php +++ b/test/Unit/Api/Resources/OptionTest.php @@ -10,11 +10,11 @@ public function testValuesPassesThroughToConnection() { $option = new Option((object)array('values' => (object)array('resource' => '/options/1/values'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/options/1/values') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/options/1/values') + ->will($this->returnValue(array(array(), array()))); - foreach($option->values as $value) { + foreach ($option->values as $value) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\OptionValue', $value); } } diff --git a/test/Unit/Api/Resources/OptionValueTest.php b/test/Unit/Api/Resources/OptionValueTest.php index 24b25f16..4d05384f 100644 --- a/test/Unit/Api/Resources/OptionValueTest.php +++ b/test/Unit/Api/Resources/OptionValueTest.php @@ -10,9 +10,9 @@ public function testOptionPassesThroughToConnection() { $optionvalue = new OptionValue((object)array('option_id' => 1)); $this->connection->expects($this->once()) - ->method('get') - ->with('/options/1') - ->will($this->returnValue(array(array()))); + ->method('get') + ->with('/options/1') + ->will($this->returnValue(array(array()))); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Option', $optionvalue->option); } @@ -22,8 +22,8 @@ public function testCreatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $optionvalue = new OptionValue((object)array('option_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/options/1/values', $optionvalue->getCreateFields()); + ->method('post') + ->with('/options/1/values', $optionvalue->getCreateFields()); $optionvalue->create(); } @@ -33,8 +33,8 @@ public function testUpdatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $optionvalue = new OptionValue((object)array('id' => 1, 'option_id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/options/1/values/1', $optionvalue->getUpdateFields()); + ->method('put') + ->with('/options/1/values/1', $optionvalue->getUpdateFields()); $optionvalue->update(); } diff --git a/test/Unit/Api/Resources/OrderTest.php b/test/Unit/Api/Resources/OrderTest.php index 9b681756..f40926a5 100644 --- a/test/Unit/Api/Resources/OrderTest.php +++ b/test/Unit/Api/Resources/OrderTest.php @@ -10,8 +10,8 @@ public function testUpdatePassesThroughToConnection() { $order = new Order((object)(array('id' => 1, 'status_id' => 5, 'is_deleted' => false))); $this->connection->expects($this->once()) - ->method('put') - ->with('/orders/1', (object)array('status_id' => 5, 'is_deleted' => false)); + ->method('put') + ->with('/orders/1', (object)array('status_id' => 5, 'is_deleted' => false)); $order->update(); } @@ -20,11 +20,11 @@ public function testShipmentsPassesThroughToConnection() { $order = new Order((object)array('id' => 1)); $this->connection->expects($this->once()) - ->method('get') - ->with('/orders/1/shipments', false) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/orders/1/shipments', false) + ->will($this->returnValue(array(array(), array()))); - foreach($order->shipments as $shipment) { + foreach ($order->shipments as $shipment) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Shipment', $shipment); } } @@ -33,11 +33,11 @@ public function testProductsPassesThroughToConnection() { $order = new Order((object)array('products' => (object)array('resource' => '/orders/1/products'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/orders/1/products') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/orders/1/products') + ->will($this->returnValue(array(array(), array()))); - foreach($order->products as $product) { + foreach ($order->products as $product) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\OrderProduct', $product); } } @@ -46,11 +46,11 @@ public function testShippingAddressesPassesThroughToConnection() { $order = new Order((object)array('shipping_addresses' => (object)array('resource' => '/orders/1/shippingaddresses'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/orders/1/shippingaddresses') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/orders/1/shippingaddresses') + ->will($this->returnValue(array(array(), array()))); - foreach($order->shipping_addresses as $address) { + foreach ($order->shipping_addresses as $address) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Address', $address); } } @@ -59,11 +59,11 @@ public function testCouponsPassesThroughToConnection() { $order = new Order((object)array('coupons' => (object)array('resource' => '/orders/1/coupons'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/orders/1/coupons') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/orders/1/coupons') + ->will($this->returnValue(array(array(), array()))); - foreach($order->coupons as $coupon) { + foreach ($order->coupons as $coupon) { $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Coupon', $coupon); } } diff --git a/test/Unit/Api/Resources/ProductCustomFieldTest.php b/test/Unit/Api/Resources/ProductCustomFieldTest.php index db910460..184863ff 100644 --- a/test/Unit/Api/Resources/ProductCustomFieldTest.php +++ b/test/Unit/Api/Resources/ProductCustomFieldTest.php @@ -11,8 +11,8 @@ public function testCreatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $customfield = new ProductCustomField((object)array('product_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/customfields', $customfield->getCreateFields()); + ->method('post') + ->with('/products/1/customfields', $customfield->getCreateFields()); $customfield->create(); } @@ -22,8 +22,8 @@ public function testUpdatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $customfield = new ProductCustomField((object)(array('id' => 1, 'product_id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/customfields/1', $customfield->getUpdateFields()); + ->method('put') + ->with('/products/1/customfields/1', $customfield->getUpdateFields()); $customfield->update(); } @@ -32,8 +32,8 @@ public function testDeletePassesThroughToConnection() { $customfield = new ProductCustomField((object)(array('id' => 1, 'product_id' => 1))); $this->connection->expects($this->once()) - ->method('delete') - ->with('/products/1/customfields/1'); + ->method('delete') + ->with('/products/1/customfields/1'); $customfield->delete(); } diff --git a/test/Unit/Api/Resources/ProductImageTest.php b/test/Unit/Api/Resources/ProductImageTest.php index 1dc6f123..aa4a36b1 100644 --- a/test/Unit/Api/Resources/ProductImageTest.php +++ b/test/Unit/Api/Resources/ProductImageTest.php @@ -11,8 +11,8 @@ public function testCreatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $customfield = new ProductImage((object)array('product_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/images', $customfield->getCreateFields()); + ->method('post') + ->with('/products/1/images', $customfield->getCreateFields()); $customfield->create(); } @@ -22,8 +22,8 @@ public function testUpdatePassesThroughToConnection() $this->markTestIncomplete('This currently fails for unknown reasons'); $customfield = new ProductImage((object)(array('id' => 1, 'product_id' => 1))); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/images/1', $customfield->getUpdateFields()); + ->method('put') + ->with('/products/1/images/1', $customfield->getUpdateFields()); $customfield->update(); } diff --git a/test/Unit/Api/Resources/ProductOptionTest.php b/test/Unit/Api/Resources/ProductOptionTest.php index adc0c10f..5729cd47 100644 --- a/test/Unit/Api/Resources/ProductOptionTest.php +++ b/test/Unit/Api/Resources/ProductOptionTest.php @@ -10,9 +10,9 @@ public function testValuesPassesThroughToConnection() { $productoption = new ProductOption((object)array('option_id' => 1)); $this->connection->expects($this->once()) - ->method('get') - ->with('/options/1') - ->will($this->returnValue(array(array()))); + ->method('get') + ->with('/options/1') + ->will($this->returnValue(array(array()))); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\Option', $productoption->option); } diff --git a/test/Unit/Api/Resources/ProductTest.php b/test/Unit/Api/Resources/ProductTest.php index 3d20d5a4..b73103cf 100644 --- a/test/Unit/Api/Resources/ProductTest.php +++ b/test/Unit/Api/Resources/ProductTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $product = new Product((object)array('id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products', (object)array('id' => 1)); + ->method('post') + ->with('/products', (object)array('id' => 1)); $product->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $product = new Product((object)array('id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1', (object)array()); + ->method('put') + ->with('/products/1', (object)array()); $product->update(); } @@ -30,8 +30,8 @@ public function testDeletePassesThroughToConnection() { $product = new Product((object)array('id' => 1)); $this->connection->expects($this->once()) - ->method('delete') - ->with('/products/1'); + ->method('delete') + ->with('/products/1'); $product->delete(); } @@ -58,9 +58,9 @@ public function testPropertyCollectionsPassThroughToTheConnection($property, $cl $url = '/products/1/' . $property; $product = new Product((object)array('id' => 1, $property => (object)array('resource' => $url))); $this->connection->expects($this->once()) - ->method('get') - ->with($url) - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with($url) + ->will($this->returnValue(array(array(), array()))); $collection = $product->$property; $this->assertInternalType('array', $collection); @@ -86,9 +86,9 @@ public function testPropertiesPassThroughToTheConnection($property, $className) $url = '/products/1/' . $property; $product = new Product((object)array($property => (object)array('resource' => $url))); $this->connection->expects($this->once()) - ->method('get') - ->with($url) - ->will($this->returnValue(array(array()))); + ->method('get') + ->with($url) + ->will($this->returnValue(array(array()))); $this->assertInstanceOf('Bigcommerce\\Api\\Resources\\' . $className, $product->$property); } diff --git a/test/Unit/Api/Resources/ResourceTestBase.php b/test/Unit/Api/Resources/ResourceTestBase.php index b7f6653d..e8616270 100644 --- a/test/Unit/Api/Resources/ResourceTestBase.php +++ b/test/Unit/Api/Resources/ResourceTestBase.php @@ -10,31 +10,31 @@ class ResourceTestBase extends \PHPUnit_Framework_TestCase public function setUp() { $methods = array( - 'useXml', - 'failOnError', - 'authenticate', - 'setTimeout', - 'useProxy', - 'verifyPeer', - 'setCipher', - 'addHeader', - 'getLastError', - 'get', - 'post', - 'head', - 'put', - 'delete', - 'getStatus', - 'getStatusMessage', - 'getBody', - 'getHeader', - 'getHeaders', - '__destruct' - ); + 'useXml', + 'failOnError', + 'authenticate', + 'setTimeout', + 'useProxy', + 'verifyPeer', + 'setCipher', + 'addHeader', + 'getLastError', + 'get', + 'post', + 'head', + 'put', + 'delete', + 'getStatus', + 'getStatusMessage', + 'getBody', + 'getHeader', + 'getHeaders', + '__destruct' + ); $this->connection = $this->getMockBuilder('Bigcommerce\\Api\\Connection') - ->disableOriginalConstructor() - ->setMethods($methods) - ->getMock(); + ->disableOriginalConstructor() + ->setMethods($methods) + ->getMock(); Client::setConnection($this->connection); } } \ No newline at end of file diff --git a/test/Unit/Api/Resources/RuleConditionTest.php b/test/Unit/Api/Resources/RuleConditionTest.php index 9d502033..e86997fe 100644 --- a/test/Unit/Api/Resources/RuleConditionTest.php +++ b/test/Unit/Api/Resources/RuleConditionTest.php @@ -11,8 +11,8 @@ public function testCreatePassesThroughToConnection() $rulecondition = new RuleCondition((object)array('rule_id' => 1)); $rulecondition->product_id = 1; $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/rules/1/conditions', $rulecondition->getCreateFields()); + ->method('post') + ->with('/products/1/rules/1/conditions', $rulecondition->getCreateFields()); $rulecondition->create(); } @@ -23,8 +23,8 @@ public function testUpdatePassesThroughToConnection() $rulecondition = new RuleCondition((object)array('id' => 1, 'rule_id' => 1)); $rulecondition->product_id = 1; $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/rules/1/conditions/1', $rulecondition->getUpdateFields()); + ->method('put') + ->with('/products/1/rules/1/conditions/1', $rulecondition->getUpdateFields()); $rulecondition->update(); } diff --git a/test/Unit/Api/Resources/RuleTest.php b/test/Unit/Api/Resources/RuleTest.php index 326f19f1..12a6bc83 100644 --- a/test/Unit/Api/Resources/RuleTest.php +++ b/test/Unit/Api/Resources/RuleTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $rule = new Rule((object)array('id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/rules', (object)array()); + ->method('post') + ->with('/products/1/rules', (object)array()); $rule->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $rule = new Rule((object)array('id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/rules/1', (object)array()); + ->method('put') + ->with('/products/1/rules/1', (object)array()); $rule->update(); } @@ -30,9 +30,9 @@ public function testConditionsPassesThroughToConnection() { $rule = new Rule((object)array('product_id' => 1, 'conditions' => (object)array('resource' => '/products/1/rules/1/conditions'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/products/1/rules/1/conditions') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/products/1/rules/1/conditions') + ->will($this->returnValue(array(array(), array()))); $collection = $rule->conditions; $this->assertInternalType('array', $collection); diff --git a/test/Unit/Api/Resources/ShipmentTest.php b/test/Unit/Api/Resources/ShipmentTest.php index 3b3b5b4d..e8acd1ff 100644 --- a/test/Unit/Api/Resources/ShipmentTest.php +++ b/test/Unit/Api/Resources/ShipmentTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $shipment = new Shipment((object)array('id' => 1, 'order_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/orders/1/shipments', (object)array()); + ->method('post') + ->with('/orders/1/shipments', (object)array()); $shipment->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $shipment = new Shipment((object)array('id' => 1, 'order_id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/orders/1/shipments/1', (object)array()); + ->method('put') + ->with('/orders/1/shipments/1', (object)array()); $shipment->update(); } diff --git a/test/Unit/Api/Resources/SkuOptionTest.php b/test/Unit/Api/Resources/SkuOptionTest.php index 4e8ec769..2afde2b4 100644 --- a/test/Unit/Api/Resources/SkuOptionTest.php +++ b/test/Unit/Api/Resources/SkuOptionTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $skuoption = new SkuOption((object)array('id' => 1, 'sku_id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/skus/1/options', (object)array('sku_id' => 1, 'product_id' => 1)); + ->method('post') + ->with('/products/1/skus/1/options', (object)array('sku_id' => 1, 'product_id' => 1)); $skuoption->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $skuoption = new SkuOption((object)array('id' => 1, 'sku_id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/skus/1/options/1', (object)array('product_id' => 1)); + ->method('put') + ->with('/products/1/skus/1/options/1', (object)array('product_id' => 1)); $skuoption->update(); } diff --git a/test/Unit/Api/Resources/SkuTest.php b/test/Unit/Api/Resources/SkuTest.php index 41bb4219..5ae6bd22 100644 --- a/test/Unit/Api/Resources/SkuTest.php +++ b/test/Unit/Api/Resources/SkuTest.php @@ -10,8 +10,8 @@ public function testCreatePassesThroughToConnection() { $sku = new Sku((object)array('id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('post') - ->with('/products/1/skus', (object)array('id' => 1)); + ->method('post') + ->with('/products/1/skus', (object)array('id' => 1)); $sku->create(); } @@ -20,8 +20,8 @@ public function testUpdatePassesThroughToConnection() { $sku = new Sku((object)array('id' => 1, 'product_id' => 1)); $this->connection->expects($this->once()) - ->method('put') - ->with('/products/1/skus/1', (object)array()); + ->method('put') + ->with('/products/1/skus/1', (object)array()); $sku->update(); } @@ -30,9 +30,9 @@ public function testOptionsPassesThroughToConnection() { $sku = new Sku((object)array('product_id' => 1, 'options' => (object)array('resource' => '/products/1/skus/1/options'))); $this->connection->expects($this->once()) - ->method('get') - ->with('/products/1/skus/1/options') - ->will($this->returnValue(array(array(), array()))); + ->method('get') + ->with('/products/1/skus/1/options') + ->will($this->returnValue(array(array(), array()))); $collection = $sku->options; $this->assertInternalType('array', $collection); From a085dc6dc60e8eac5982b52ef197a14786043fb3 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Thu, 19 Feb 2015 13:46:12 -0800 Subject: [PATCH 13/18] BIG-15160: code review cleanups, additional doc block additions --- src/Bigcommerce/Api/Client.php | 44 +++++++++++++++++++- src/Bigcommerce/Api/Connection.php | 64 ++++++++++-------------------- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index d8f9c4a8..ed025569 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -9,11 +9,51 @@ */ class Client { + /** + * Default SSL Cipher to be used + */ + const DEFAULT_SSL_CIPHER = 'rsa_rc4_128_sha'; + + /** + * Full Store URL to connect to + * + * @var string + */ static private $store_url; + + /** + * Username to connect to the store API with + * + * @var string + */ static private $username; + + /** + * API key + * + * @var string + */ static private $api_key; + + /** + * Connection instance + * + * @var Connection + */ static private $connection; + + /** + * Resource class name + * + * @var string + */ static private $resource; + + /** + * API path prefix to be added to store URL for requests + * + * @var string + */ static private $path_prefix = '/api/v2'; /** @@ -35,7 +75,7 @@ class Client * @param array $settings * @throws \Exception */ - public static function configure($settings) + public static function configure(array $settings) { if (!isset($settings['store_url'])) { throw new Exception("'store_url' must be provided"); @@ -94,7 +134,7 @@ public static function verifyPeer($option = false) /** * Set which cipher to use during SSL requests. */ - public static function setCipher($cipher = 'rsa_rc4_128_sha') + public static function setCipher($cipher = self::DEFAULT_SSL_CIPHER) { self::connection()->setCipher($cipher); } diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 53e0dd11..82bb6c95 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -9,17 +9,17 @@ class Connection { /** - * @var cURL resource + * @var resource cURL resource */ private $curl; /** - * @var hash of HTTP request headers + * @var array Hash of HTTP request headers. */ private $headers = array(); /** - * @var hash of headers from HTTP response + * @var array Hash of headers from HTTP response */ private $responseHeaders = array(); @@ -30,7 +30,7 @@ class Connection private $responseStatusLine; /** - * @var hash of headers from HTTP response + * @var string response body */ private $responseBody; @@ -60,15 +60,10 @@ class Connection /** * Deal with failed requests if failOnError is not set. - * @var mixed + * @var string | false */ private $lastError = false; - /** - * Current cURL error code. - */ - private $errorCode; - /** * Determines whether requests and responses should be treated * as XML. Defaults to false (using JSON). @@ -200,6 +195,11 @@ private function initializeRequest() $this->responseHeaders = array(); $this->lastError = false; $this->addHeader('Accept', $this->getContentType()); + + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_PUT, false); + curl_setopt($this->curl, CURLOPT_HTTPGET, false); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); } @@ -300,8 +300,6 @@ public function get($url, $query = false) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POST, false); - curl_setopt($this->curl, CURLOPT_PUT, false); curl_setopt($this->curl, CURLOPT_HTTPGET, true); curl_exec($this->curl); @@ -324,8 +322,6 @@ public function post($url, $body) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($this->curl, CURLOPT_URL, $url); curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_PUT, false); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); curl_exec($this->curl); @@ -334,6 +330,9 @@ public function post($url, $body) /** * Make an HTTP HEAD request to the specified endpoint. + * + * @param $url + * @return bool|mixed|string */ public function head($url) { @@ -352,6 +351,10 @@ public function head($url) * * Requires a tmpfile() handle to be opened on the system, as the cURL * API requires it to send data. + * + * @param $url + * @param $body + * @return bool|mixed|string */ public function put($url, $body) { @@ -371,8 +374,6 @@ public function put($url, $body) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); - curl_setopt($this->curl, CURLOPT_POST, false); curl_setopt($this->curl, CURLOPT_PUT, true); curl_exec($this->curl); @@ -384,14 +385,14 @@ public function put($url, $body) /** * Make an HTTP DELETE request to the specified endpoint. + * + * @param $url + * @return bool|mixed|string */ public function delete($url) { $this->initializeRequest(); - curl_setopt($this->curl, CURLOPT_PUT, false); - curl_setopt($this->curl, CURLOPT_HTTPGET, false); - curl_setopt($this->curl, CURLOPT_POST, false); curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($this->curl, CURLOPT_URL, $url); curl_exec($this->curl); @@ -399,31 +400,6 @@ public function delete($url) return $this->handleResponse(); } - /** - * Callback method collects body content from the response. - */ - private function parseBody($curl, $body) - { - $this->responseBody .= $body; - return strlen($body); - } - - /** - * Callback methods collects header lines from the response. - */ - private function parseHeader($curl, $headers) - { - if (!$this->responseStatusLine && strpos($headers, 'HTTP/') === 0) { - $this->responseStatusLine = $headers; - } else { - $parts = explode(': ', $headers); - if (isset($parts[1])) { - $this->responseHeaders[$parts[0]] = trim($parts[1]); - } - } - return strlen($headers); - } - /** * Access the status code of the response. */ From 188fa29d9cad65621fcd4c59ee6da77184819f8f Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Thu, 19 Feb 2015 18:21:39 -0800 Subject: [PATCH 14/18] BIG-15160: remove cipher default and instructions, negotiate with server for proper cipher --- README.md | 12 ------------ src/Bigcommerce/Api/Client.php | 7 +------ src/Bigcommerce/Api/Connection.php | 5 +---- test/Unit/Api/ClientTest.php | 4 ++-- 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b9c524b0..4da87843 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ Requirements - PHP 5.3 or greater - cUrl extension enabled -- RC4-SHA (rsa_rc4_128_sha) cipher To connect to the API, you need the following credentials: @@ -299,17 +298,6 @@ The exceptions thrown are subclasses of Error, representing client errors and server errors. The API documentation for response codes contains a list of all the possible error conditions the client may encounter. -Specifying the SSL cipher -------------------------- - -The API requires that all client SSL connections use the RC4-SHA (rsa_rc4_128_sha) cipher. -The client will set this cipher to be used by default. - -The setCipher method can be used to override this setting if required. - -``` -Bigcommerce::setCipher('RC4-SHA'); -``` Verifying SSL certificates -------------------------- diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index ed025569..eecf33a3 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -9,11 +9,6 @@ */ class Client { - /** - * Default SSL Cipher to be used - */ - const DEFAULT_SSL_CIPHER = 'rsa_rc4_128_sha'; - /** * Full Store URL to connect to * @@ -134,7 +129,7 @@ public static function verifyPeer($option = false) /** * Set which cipher to use during SSL requests. */ - public static function setCipher($cipher = self::DEFAULT_SSL_CIPHER) + public static function setCipher($cipher) { self::connection()->setCipher($cipher); } diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 82bb6c95..95a80e49 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -79,9 +79,6 @@ public function __construct() curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array($this, 'parseHeader')); curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, array($this, 'parseBody')); - // Bigcommerce only supports RC4-SHA (rsa_rc4_128_sha) - $this->setCipher('rsa_rc4_128_sha'); - if (!ini_get("open_basedir")) { curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); } else { @@ -163,7 +160,7 @@ public function verifyPeer($option = false) * Set which cipher to use during SSL requests. * @param string $cipher the name of the cipher */ - public function setCipher($cipher = 'rsa_rc4_128_sha') + public function setCipher($cipher) { curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, $cipher); } diff --git a/test/Unit/Api/ClientTest.php b/test/Unit/Api/ClientTest.php index 16b86a35..96a2afa1 100644 --- a/test/Unit/Api/ClientTest.php +++ b/test/Unit/Api/ClientTest.php @@ -95,10 +95,10 @@ public function testSetCipherPassesThroughToConnection() ->method('setCipher') ->withConsecutive( array('rsa'), - array('rsa_rc4_128_sha') // this is the default value + array('tls') // this is the default value ); Client::setCipher('rsa'); - Client::setCipher(); + Client::setCipher('tls'); } public function testUseProxyPassesThroughToConnection() From 4d603e99255bfc92305e060b315b3018c574ac7f Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Fri, 20 Feb 2015 09:10:59 -0800 Subject: [PATCH 15/18] BIG-15160: add back in missing methods --- src/Bigcommerce/Api/Connection.php | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 95a80e49..943c09d8 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -397,6 +397,39 @@ public function delete($url) return $this->handleResponse(); } + /** + * Method that appears unused, but is in fact called by curl + * + * @param $curl + * @param $body + * @return int + */ + private function parseBody($curl, $body) + { + $this->responseBody .= $body; + return strlen($body); + } + + /** + * Method that appears unused, but is in fact called by curl + * + * @param $curl + * @param $headers + * @return int + */ + private function parseHeader($curl, $headers) + { + if (!$this->responseStatusLine && strpos($headers, 'HTTP/') === 0) { + $this->responseStatusLine = $headers; + } else { + $parts = explode(': ', $headers); + if (isset($parts[1])) { + $this->responseHeaders[$parts[0]] = trim($parts[1]); + } + } + return strlen($headers); + } + /** * Access the status code of the response. */ From 183aeafa83d1993b9c77869b67384b6e355b5776 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Fri, 20 Feb 2015 10:04:27 -0800 Subject: [PATCH 16/18] BIG-15160: fix spacing on resource provider --- test/Unit/Api/ClientTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/Unit/Api/ClientTest.php b/test/Unit/Api/ClientTest.php index 96a2afa1..68a28887 100644 --- a/test/Unit/Api/ClientTest.php +++ b/test/Unit/Api/ClientTest.php @@ -304,15 +304,15 @@ public function testGettingTheCountOfACollectionReturnsThatCollectionsCount($pat public function resources() { return array( - // path function classname - array('products', '%sProduct', 'Product'), - array('brands', '%sBrand', 'Brand'), - array('orders', '%sOrder', 'Order'), - array('customers', '%sCustomer', 'Customer'), - array('categories', '%sCategory', 'Category'), - array('options', '%sOption', 'Option'), - array('optionsets', '%sOptionSet', 'OptionSet'), - array('coupons', '%sCoupon', 'Coupon'), + // path function classname + array('products', '%sProduct', 'Product'), + array('brands', '%sBrand', 'Brand'), + array('orders', '%sOrder', 'Order'), + array('customers', '%sCustomer', 'Customer'), + array('categories', '%sCategory', 'Category'), + array('options', '%sOption', 'Option'), + array('optionsets', '%sOptionSet', 'OptionSet'), + array('coupons', '%sCoupon', 'Coupon'), ); } From 598bd27be2bee46efe98df02b238ca486c5303a2 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Fri, 20 Feb 2015 10:15:33 -0800 Subject: [PATCH 17/18] BIG-15160: remove default cipher test since we no longer set a default --- test/Unit/Api/ClientTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/Unit/Api/ClientTest.php b/test/Unit/Api/ClientTest.php index 68a28887..d3ce454a 100644 --- a/test/Unit/Api/ClientTest.php +++ b/test/Unit/Api/ClientTest.php @@ -91,14 +91,12 @@ public function testVerifyPeerPassesThroughToConnection() public function testSetCipherPassesThroughToConnection() { - $this->connection->expects($this->exactly(2)) + $this->connection->expects($this->once()) ->method('setCipher') ->withConsecutive( - array('rsa'), - array('tls') // this is the default value + array('rsa') ); Client::setCipher('rsa'); - Client::setCipher('tls'); } public function testUseProxyPassesThroughToConnection() From f5ecb3d1a247110acc79a091368f141b273d0e64 Mon Sep 17 00:00:00 2001 From: Anthony Leach Date: Sat, 21 Feb 2015 07:06:11 -0800 Subject: [PATCH 18/18] BIG-15160: remove setCipher() and tests --- src/Bigcommerce/Api/Connection.php | 9 --------- test/Unit/Api/ClientTest.php | 11 ----------- test/Unit/Api/Resources/ResourceTestBase.php | 1 - 3 files changed, 21 deletions(-) diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 943c09d8..a9daa336 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -156,15 +156,6 @@ public function verifyPeer($option = false) curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $option); } - /** - * Set which cipher to use during SSL requests. - * @param string $cipher the name of the cipher - */ - public function setCipher($cipher) - { - curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, $cipher); - } - /** * Add a custom header to the request. */ diff --git a/test/Unit/Api/ClientTest.php b/test/Unit/Api/ClientTest.php index d3ce454a..d8c70acd 100644 --- a/test/Unit/Api/ClientTest.php +++ b/test/Unit/Api/ClientTest.php @@ -17,7 +17,6 @@ public function setUp() 'setTimeout', 'useProxy', 'verifyPeer', - 'setCipher', 'addHeader', 'getLastError', 'get', @@ -89,16 +88,6 @@ public function testVerifyPeerPassesThroughToConnection() Client::verifyPeer(false); } - public function testSetCipherPassesThroughToConnection() - { - $this->connection->expects($this->once()) - ->method('setCipher') - ->withConsecutive( - array('rsa') - ); - Client::setCipher('rsa'); - } - public function testUseProxyPassesThroughToConnection() { $this->connection->expects($this->once()) diff --git a/test/Unit/Api/Resources/ResourceTestBase.php b/test/Unit/Api/Resources/ResourceTestBase.php index e8616270..6f78febf 100644 --- a/test/Unit/Api/Resources/ResourceTestBase.php +++ b/test/Unit/Api/Resources/ResourceTestBase.php @@ -16,7 +16,6 @@ public function setUp() 'setTimeout', 'useProxy', 'verifyPeer', - 'setCipher', 'addHeader', 'getLastError', 'get',