diff --git a/bigcommerce.php b/bigcommerce.php index b25c5e16..019bfb9a 100644 --- a/bigcommerce.php +++ b/bigcommerce.php @@ -39,6 +39,11 @@ public function authenticate($username, $password) { curl_setopt($this->curl, CURLOPT_USERPWD, "{$username}:{$password}"); } + public function oAuthAuthenticate($client_id, $access_token) + { + $this->addHeader('X-Auth-Client', $client_id); + $this->addHeader('X-Auth-Token', $access_token); + } public function setTimeout($timeout) { curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout); @@ -278,22 +283,49 @@ class Client private static $connection; private static $resource; private static $path_prefix = '/api/v2'; + private static $oauth_api_path = 'https://api.bigcommerce.com/stores'; + private static $auth_mode = 'oauth'; + private static $oauth_client_id; + private static $oauth_access_token; + private static $oauth_store_hash; + private static $oauth_path_prefix = '/v2'; public static $api_path; public static function configure($settings) { - if (!isset($settings['store_url'])) { + if (isset($settings['auth_mode']) && in_array($settings['auth_mode'], array('oauth', 'basic'))) { + self::$auth_mode = $settings['auth_mode']; + } + if (!isset($settings['store_url']) && self::$auth_mode === 'basic') { throw new Exception('\'store_url\' must be provided'); } - if (!isset($settings['username'])) { + if (!isset($settings['username']) && self::$auth_mode === 'basic') { throw new Exception('\'username\' must be provided'); } - if (!isset($settings['api_key'])) { + if (!isset($settings['api_key']) && self::$auth_mode === 'basic') { 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; + if (!isset($settings['client_id']) && self::$auth_mode === 'oauth') { + throw new Exception('\'client_id\' must be provided'); + } + if (!isset($settings['access_token']) && self::$auth_mode === 'oauth') { + throw new Exception('\'access_token\' must be provided'); + } + if (!isset($settings['store_hash']) && self::$auth_mode === 'oauth') { + throw new Exception('\'store_hash\' must be provided'); + } + if ('basic' === self::$auth_mode) { + 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; + } elseif ('oauth' === self::$auth_mode) { + self::$oauth_client_id = $settings['client_id']; + self::$oauth_access_token = $settings['access_token']; + self::$oauth_store_hash = $settings['store_hash']; + self::$api_path = self::$oauth_api_path . '/' . self::$oauth_store_hash . self::$oauth_path_prefix; + } else { + throw new Exception('Given Auth mode is not supported'); + } self::$connection = false; } public static function failOnError($option = true) @@ -324,7 +356,11 @@ private static function connection() { if (!self::$connection) { self::$connection = new Connection(); - self::$connection->authenticate(self::$username, self::$api_key); + if ('basic' === self::$auth_mode) { + self::$connection->authenticate(self::$username, self::$api_key); + } else { + self::$connection->oAuthAuthenticate(self::$oauth_client_id, self::$oauth_access_token); + } } return self::$connection; } @@ -413,23 +449,23 @@ public static function getProductImages($id) } public static function getProductCustomFields($id) { - return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField'); + return self::getCollection('/products/' . $id . '/custom_fields', 'ProductCustomField'); } public static function getProductCustomField($product_id, $id) { - return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField'); + return self::getResource('/products/' . $product_id . '/custom_fields/' . $id, 'ProductCustomField'); } public static function createProductCustomField($product_id, $object) { - return self::createResource('/products/' . $product_id . '/customfields', $object); + return self::createResource('/products/' . $product_id . '/custom_fields', $object); } public static function updateProductCustomField($product_id, $id, $object) { - return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object); + return self::updateResource('/products/' . $product_id . '/custom_fields/' . $id, $object); } public static function deleteProductCustomField($product_id, $id) { - return self::deleteResource('/products/' . $product_id . '/customfields/' . $id); + return self::deleteResource('/products/' . $product_id . '/custom_fields/' . $id); } public static function getProductsCount($filter = false) { @@ -641,6 +677,26 @@ public static function updateCoupon($id, $object) { return self::updateResource('/coupons/' . $id, $object); } + public static function listWebHook() + { + return self::getResource('/hooks'); + } + public static function getWebHook($id) + { + return self::getResource('/hooks/' . $id); + } + public static function createWebHook($object) + { + return self::createResource('/hooks', $object); + } + public static function updateWebHook($id, $object) + { + return self::updateResource('/hooks/' . $id, $object); + } + public static function deleteWebHook($id) + { + return self::deleteResource('/hooks/' . $id); + } public static function getRequestLogs() { return self::getCollection('/requestlogs'); @@ -982,7 +1038,7 @@ class OrderStatus extends Resource 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 $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', 'calculated_price', 'primary_image', 'downloads'); protected $ignoreIfZero = array('tax_class_id'); public function brand() { @@ -1059,15 +1115,15 @@ class ProductCustomField extends Resource protected $ignoreOnUpdate = array('id', 'product_id'); public function create() { - return Client::createResource('/products/' . $this->product_id . '/customfields', $this->getCreateFields()); + return Client::createResource('/products/' . $this->product_id . '/custom_fields', $this->getCreateFields()); } public function update() { - Client::updateResource('/products/' . $this->product_id . '/customfields/' . $this->id, $this->getUpdateFields()); + Client::updateResource('/products/' . $this->product_id . '/custom_fields/' . $this->id, $this->getUpdateFields()); } public function delete() { - Client::deleteResource('/products/' . $this->product_id . '/customfields/' . $this->id); + Client::deleteResource('/products/' . $this->product_id . '/custom_fields/' . $this->id); } } namespace Bigcommerce\Api\Resources; diff --git a/src/Bigcommerce/Api/Client.php b/src/Bigcommerce/Api/Client.php index 7157a886..2f968402 100644 --- a/src/Bigcommerce/Api/Client.php +++ b/src/Bigcommerce/Api/Client.php @@ -15,8 +15,15 @@ class Client static private $connection; static private $resource; static private $path_prefix = '/api/v2'; + static private $oauth_api_path = 'https://api.bigcommerce.com/stores'; + static private $auth_mode = 'oauth'; + static private $oauth_client_id; + static private $oauth_access_token; + static private $oauth_store_hash; + static private $oauth_path_prefix = '/v2'; - /** + + /** * Full URL path to the configured store API. * * @var string @@ -35,25 +42,49 @@ class Client * @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; - } + { + if (isset($settings['auth_mode']) && in_array($settings['auth_mode'], array('oauth', 'basic'))) { + self::$auth_mode = $settings['auth_mode']; + } + // Basic Auth specific settings + if (!isset($settings['store_url']) && self::$auth_mode === 'basic') { + throw new Exception("'store_url' must be provided"); + } + + if (!isset($settings['username']) && self::$auth_mode === 'basic') { + throw new Exception("'username' must be provided"); + } + + if (!isset($settings['api_key']) && self::$auth_mode === 'basic') { + throw new Exception("'api_key' must be provided"); + } + // OAuth specific settings + if (!isset($settings['client_id']) && self::$auth_mode === 'oauth') { + throw new Exception("'client_id' must be provided"); + } + if (!isset($settings['access_token']) && self::$auth_mode === 'oauth') { + throw new Exception("'access_token' must be provided"); + } + if (!isset($settings['store_hash']) && self::$auth_mode === 'oauth') { + throw new Exception("'store_hash' must be provided"); + } + + if ('basic' === self::$auth_mode) { + 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; + } elseif ('oauth' === self::$auth_mode) { + self::$oauth_client_id = $settings['client_id']; + self::$oauth_access_token = $settings['access_token']; + self::$oauth_store_hash = $settings['store_hash']; + self::$api_path = self::$oauth_api_path . '/' . self::$oauth_store_hash . self::$oauth_path_prefix; + } else { + throw new Exception('Given Auth mode is not supported'); + } + + self::$connection = false; + } /** * Configure the API client to throw exceptions when HTTP errors occur. @@ -121,7 +152,11 @@ private static function connection() { if (!self::$connection) { self::$connection = new Connection(); - self::$connection->authenticate(self::$username, self::$api_key); + if ('basic' === self::$auth_mode) { + self::$connection->authenticate(self::$username, self::$api_key); + } else { + self::$connection->oAuthAuthenticate(self::$oauth_client_id, self::$oauth_access_token); + } } return self::$connection; @@ -312,7 +347,7 @@ public static function getProductImages($id) */ public static function getProductCustomFields($id) { - return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField'); + return self::getCollection('/products/' . $id . '/custom_fields', 'ProductCustomField'); } /** @@ -323,7 +358,7 @@ public static function getProductCustomFields($id) */ public static function getProductCustomField($product_id, $id) { - return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField'); + return self::getResource('/products/' . $product_id . '/custom_fields/' . $id, 'ProductCustomField'); } /** @@ -336,7 +371,7 @@ public static function getProductCustomField($product_id, $id) */ public static function createProductCustomField($product_id, $object) { - return self::createResource('/products/' . $product_id . '/customfields', $object); + return self::createResource('/products/' . $product_id . '/custom_fields', $object); } /** @@ -348,7 +383,7 @@ public static function createProductCustomField($product_id, $object) */ public static function updateProductCustomField($product_id, $id, $object) { - return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object); + return self::updateResource('/products/' . $product_id . '/custom_fields/' . $id, $object); } /** @@ -359,7 +394,7 @@ public static function updateProductCustomField($product_id, $id, $object) */ public static function deleteProductCustomField($product_id, $id) { - return self::deleteResource('/products/' . $product_id . '/customfields/' . $id); + return self::deleteResource('/products/' . $product_id . '/custom_fields/' . $id); } /** @@ -857,6 +892,31 @@ public static function updateCoupon($id, $object) return self::updateResource('/coupons/' . $id, $object); } + public static function listWebHook() + { + return self::getResource('/hooks'); + } + + public static function getWebHook($id) + { + return self::getResource('/hooks/' . $id); + } + + public static function createWebHook($object) + { + return self::createResource('/hooks', $object); + } + + public static function updateWebHook($id, $object) + { + return self::updateResource('/hooks/' . $id, $object); + } + + public static function deleteWebHook($id) + { + return self::deleteResource('/hooks/' . $id); + } + /** * The request logs with usage history statistics. */ diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index 3b0025b3..e7b7ab5a 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -128,6 +128,17 @@ public function authenticate($username, $password) curl_setopt($this->curl, CURLOPT_USERPWD, "$username:$password"); } + /** + * Sets headers for OAuth authentication + * @param string $client_id + * @param string $access_token + */ + public function oAuthAuthenticate($client_id, $access_token) + { + $this->addHeader('X-Auth-Client', $client_id); + $this->addHeader('X-Auth-Token', $access_token); + } + /** * Set a default timeout for the request. The client will error if the * request takes longer than this to respond. @@ -197,6 +208,7 @@ private function initializeRequest() $this->responseHeaders = array(); $this->lastError = false; $this->addHeader('Accept', $this->getContentType()); + // OAuth support curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); } diff --git a/src/Bigcommerce/Api/Resources/Product.php b/src/Bigcommerce/Api/Resources/Product.php index d2fdc999..b260c71e 100644 --- a/src/Bigcommerce/Api/Resources/Product.php +++ b/src/Bigcommerce/Api/Resources/Product.php @@ -17,7 +17,7 @@ class Product extends Resource ); /** - * @see https://developer.bigcommerce.com/display/API/Products#Products-ReadOnlyFields + * @see https://developer.bigcommerce.com/api/stores/v2/products#update-product-read-only * @var array */ protected $ignoreOnUpdate = array( @@ -39,6 +39,9 @@ class Product extends Resource 'option_set', 'options', 'tax_class', + 'calculated_price', + 'primary_image', + 'downloads' ); protected $ignoreIfZero = array( diff --git a/src/Bigcommerce/Api/Resources/ProductCustomField.php b/src/Bigcommerce/Api/Resources/ProductCustomField.php index dfdafc82..a76cbc41 100644 --- a/src/Bigcommerce/Api/Resources/ProductCustomField.php +++ b/src/Bigcommerce/Api/Resources/ProductCustomField.php @@ -23,17 +23,17 @@ class ProductCustomField extends Resource public function create() { - return Client::createResource('/products/' . $this->product_id . '/customfields', $this->getCreateFields()); + return Client::createResource('/products/' . $this->product_id . '/custom_fields', $this->getCreateFields()); } public function update() { - Client::updateResource('/products/' . $this->product_id . '/customfields/' . $this->id, $this->getUpdateFields()); + Client::updateResource('/products/' . $this->product_id . '/custom_fields/' . $this->id, $this->getUpdateFields()); } public function delete() { - Client::deleteResource('/products/' . $this->product_id . '/customfields/' . $this->id); + Client::deleteResource('/products/' . $this->product_id . '/custom_fields/' . $this->id); } }