1
0
mirror of synced 2024-11-25 14:56:07 +03:00

Merge pull request #3 from retailcrm/v3

New client for API v3
This commit is contained in:
Ilyas Salikhov 2014-11-06 16:50:23 +03:00
commit 3c2b25982d
20 changed files with 1880 additions and 637 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
.DS_Store .DS_Store
phpunit.xml
vendor/
composer.lock

101
README.md
View File

@ -1,7 +1,7 @@
IntaroCRM REST API client PHP client for retailCRM API
================= =================
PHP Client for [IntaroCRM REST API](http://docs.intarocrm.ru/rest-api/). PHP client for [retailCRM API](http://www.retailcrm.ru/docs/Разработчики/Разработчики#api).
Requirements Requirements
------------ ------------
@ -12,49 +12,82 @@ Requirements
Installation Installation
------------ ------------
1) Install [composer](https://getcomposer.org/download/) into the project directory. 1) Install [composer](https://getcomposer.org/download/)
2) Add IntaroCRM REST API client in your composer.json: 2) Run:
```js ```bash
{ composer require retailcrm/api-client-php 3.0
"require": {
"intarocrm/rest-api-client": "1.3.*"
}
}
``` ```
3) Use command `php composer.phar update intarocrm/rest-api-client` to install new vendor into `vendor/` folder.
Usage Usage
------------ -----
### Create API clent class Example of the receipt of order:
```php
``` php $client = new \RetailCrm\ApiClient(
$crmApiClient = new \IntaroCrm\RestApi(
'https://demo.intarocrm.ru', 'https://demo.intarocrm.ru',
'T9DMPvuNt7FQJMszHUdG8Fkt6xHsqngH' 'T9DMPvuNt7FQJMszHUdG8Fkt6xHsqngH'
); );
```
Constructor arguments are:
1. Your IntaroCRM acount URL-address
2. Your site API Token
### Example: get order types list
``` php
try { try {
$orderTypes = $crmApiClient->orderTypesList(); $response = $client->ordersGet('M-2342');
} } catch (\RetailCrm\Exception\CurlException $e) {
catch (\IntaroCrm\Exception\CurlException $e) { echo "CRM connection error: " . $e->getMessage();
//$logger->addError('orderTypesList: connection error');
}
catch (\IntaroCrm\Exception\ApiException $e) {
//$logger->addError('orderTypesList: ' . $e->getMessage());
} }
if ($response->isSuccessful()) {
echo $response->order['totalSumm'];
// or $response['order']['totalSumm'];
// or
// $order = $response->getOrder();
// $order['totalSumm'];
} else {
echo sprintf(
"Error of the order receipt: [Code %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
);
}
```
Example of the order creating:
```php
$client = new \RetailCrm\ApiClient(
'https://demo.intarocrm.ru',
'T9DMPvuNt7FQJMszHUdG8Fkt6xHsqngH'
);
try {
$response = $client->ordersCreate(array(
'externalId' => 'some-shop-order-id',
'firstName' => 'Vasily',
'lastName' => 'Pupkin',
'items' => array(
//...
),
'delivery' => array(
'code' => 'russian-post',
)
));
} catch (\RetailCrm\Exception\CurlException $e) {
echo "CRM connection error: " . $e->getMessage();
}
if ($response->isSuccessful()) {
if (201 === $response->getStatusCode()) {
echo 'Order created successfully! Order ID in CRM = ' . $response->id;
// or $response['id'];
// or $response->getId();
} else {
echo 'Order updated successfully!';
}
} else {
echo sprintf(
"Error of the order creating: [Code %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
);
}
``` ```

View File

@ -1,29 +1,28 @@
{ {
"name": "intarocrm/rest-api-client", "name": "retailcrm/api-client-php",
"description": "PHP Client for IntaroCRM REST API", "description": "PHP client for retailCRM API",
"type": "library", "type": "library",
"keywords": ["api", "Intaro CRM", "rest"], "keywords": ["API", "retailCRM", "REST"],
"homepage": "http://www.intarocrm.ru/", "homepage": "http://www.retailcrm.ru/",
"authors": [ "authors": [
{ {
"name": "Kruglov Kirill", "name": "retailCRM",
"email": "kruglov@intaro.ru", "email": "support@retailcrm.ru"
"role": "Developer"
} }
], ],
"require": { "require": {
"php": ">=5.2.0", "php": ">=5.3.0",
"ext-curl": "*" "ext-curl": "*"
}, },
"support": { "support": {
"email": "support@intarocrm.ru" "email": "support@intarocrm.ru"
}, },
"autoload": { "autoload": {
"psr-0": { "IntaroCrm\\": "lib/" } "psr-0": { "RetailCrm\\": "lib/" }
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.0.x-dev" "dev-master": "3.0.x-dev"
} }
} }
} }

View File

@ -1,6 +0,0 @@
<?php
namespace IntaroCrm\Exception;
class ApiException extends \Exception
{
}

View File

@ -1,6 +0,0 @@
<?php
namespace IntaroCrm\Exception;
class CurlException extends \Exception
{
}

View File

@ -1,581 +0,0 @@
<?php
namespace IntaroCrm;
class RestApi
{
protected $apiUrl;
protected $apiKey;
protected $apiVersion = '3';
protected $generatedAt;
protected $parameters;
/**
* @param string $crmUrl - адрес CRM
* @param string $apiKey - ключ для работы с api
*/
public function __construct($crmUrl, $apiKey)
{
$this->apiUrl = $crmUrl.'/api/v'.$this->apiVersion.'/';
$this->apiKey = $apiKey;
$this->parameters = array('apiKey' => $this->apiKey);
}
/* Методы для работы с заказами */
/**
* Получение заказа по id
*
* @param string $id - идентификатор заказа
* @param string $by - поиск заказа по id или externalId
* @return array - информация о заказе
*/
public function orderGet($id, $by = 'externalId')
{
$url = $this->apiUrl.'orders/'.$id;
if ($by != 'externalId')
$this->parameters['by'] = $by;
$result = $this->curlRequest($url);
return $result;
}
/**
* Создание заказа
*
* @param array $order- информация о заказе
* @return array
*/
public function orderCreate($order)
{
$dataJson = json_encode($order);
$this->parameters['order'] = $dataJson;
$url = $this->apiUrl.'orders/create';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Изменение заказа
*
* @param array $order- информация о заказе
* @return array
*/
public function orderEdit($order)
{
$dataJson = json_encode($order);
$this->parameters['order'] = $dataJson;
$url = $this->apiUrl.'orders/'.$order['externalId'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Пакетная загрузка заказов
*
* @param array $orders - массив заказов
* @return array
*/
public function orderUpload($orders)
{
$dataJson = json_encode($orders);
$this->parameters['orders'] = $dataJson;
$url = $this->apiUrl.'orders/upload';
$result = $this->curlRequest($url, 'POST');
if (is_null($result) && isset($result['uploadedOrders']))
return $result['uploadedOrders'];
return $result;
}
/**
* Обновление externalId у заказов с переданными id
*
* @param array $orders- массив, содержащий id и externalId заказа
* @return array
*/
public function orderFixExternalIds($order)
{
$dataJson = json_encode($order);
$this->parameters['orders'] = $dataJson;
$url = $this->apiUrl.'orders/fix-external-ids';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение последних измененных заказов
*
* @param \DateTime|string|int $startDate - начальная дата и время выборки (Y-m-d H:i:s)
* @param \DateTime|string|int $endDate - конечная дата и время выборки (Y-m-d H:i:s)
* @param int $limit - ограничение на размер выборки
* @param int $offset - сдвиг
* @return array - массив заказов
*/
public function orderHistory($startDate = null, $endDate = null, $limit = 100, $offset = 0)
{
$url = $this->apiUrl.'orders/history';
$this->parameters['startDate'] = $this->ensureDateTime($startDate);
$this->parameters['endDate'] = $this->ensureDateTime($endDate);
$this->parameters['limit'] = $limit;
$this->parameters['offset'] = $offset;
$result = $this->curlRequest($url);
return $result;
}
/* Методы для работы с клиентами */
/**
* Получение клиента по id
*
* @param string $id - идентификатор
* @param string $by - поиск заказа по id или externalId
* @return array - информация о клиенте
*/
public function customerGet($id, $by = 'externalId')
{
$url = $this->apiUrl.'customers/'.$id;
if ($by != 'externalId')
$this->parameters['by'] = $by;
$result = $this->curlRequest($url);
return $result;
}
/**
* Получение списка клиентов в соответсвии с запросом
*
* @param string $phone - телефон
* @param string $email - почтовый адрес
* @param string $fio - фио пользователя
* @param int $limit - ограничение на размер выборки
* @param int $offset - сдвиг
* @return array - массив клиентов
*/
public function customers($phone = null, $email = null, $fio = null, $limit = 200, $offset = 0)
{
$url = $this->apiUrl.'customers';
if($phone) $this->parameters['phone'] = $phone;
if($email) $this->parameters['email'] = $email;
if($fio) $this->parameters['fio'] = $fio;
$this->parameters['limit'] = $limit;
$this->parameters['offset'] = $offset;
$result = $this->curlRequest($url);
return $result;
}
/**
* Создание клиента
*
* @param array $customer - информация о клиенте
* @return array
*/
public function customerCreate($customer)
{
$dataJson = json_encode($customer);
$this->parameters['customer'] = $dataJson;
$url = $this->apiUrl.'customers/create';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Редактирование клиента
*
* @param array $customer - информация о клиенте
* @return array
*/
public function customerEdit($customer)
{
$dataJson = json_encode($customer);
$this->parameters['customer'] = $dataJson;
$url = $this->apiUrl.'customers/'.$customer['externalId'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Пакетная загрузка клиентов
*
* @param array $customers - массив клиентов
* @return array
*/
public function customerUpload($customers)
{
$dataJson = json_encode($customers);
$this->parameters['customers'] = $dataJson;
$url = $this->apiUrl.'customers/upload';
$result = $this->curlRequest($url, 'POST');
if (is_null($result) && isset($result['uploaded']))
return $result['uploaded'];
return $result;
}
/**
* Обновление externalId у клиентов с переданными id
*
* @param array $customers- массив, содержащий id и externalId заказа
* @return array
*/
public function customerFixExternalIds($customers)
{
$dataJson = json_encode($customers);
$this->parameters['customers'] = $dataJson;
$url = $this->apiUrl.'customers/fix-external-ids';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка заказов клиента
*
* @param string $id - идентификатор клиента
* @param string $by - поиск заказа по id или externalId
* @param \DateTime|string|int $startDate - начальная дата выборки (Y-m-d H:i:s)
* @param \DateTime|string|int $endDate - конечная дата выборки (Y-m-d H:i:s)
* @param int $limit - ограничение на размер выборки
* @param int $offset - сдвиг
* @return array - массив заказов
*/
public function customerOrdersList($id, $startDate = null, $endDate = null,
$limit = 100, $offset = 0, $by = 'externalId')
{
$url = $this->apiUrl.'customers/'.$id.'/orders';
if ($by != 'externalId')
$this->parameters['by'] = $by;
$this->parameters['startDate'] = $this->ensureDateTime($startDate);
$this->parameters['endDate'] = $this->ensureDateTime($endDate);
$this->parameters['limit'] = $limit;
$this->parameters['offset'] = $offset;
$result = $this->curlRequest($url);
return $result;
}
/* Методы для работы со справочниками */
/**
* Получение списка типов доставки
*
* @return array - массив типов доставки
*/
public function deliveryTypesList()
{
$url = $this->apiUrl.'reference/delivery-types';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование типа доставки
*
* @param array $deliveryType - информация о типе доставки
* @return array
*/
public function deliveryTypeEdit($deliveryType)
{
$dataJson = json_encode($deliveryType);
$this->parameters['deliveryType'] = $dataJson;
$url = $this->apiUrl.'reference/delivery-types/'.$deliveryType['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка служб доставки
*
* @return array - массив типов доставки
*/
public function deliveryServicesList()
{
$url = $this->apiUrl.'reference/delivery-services';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование службы доставки
*
* @param array $deliveryService - информация о типе доставки
* @return array
*/
public function deliveryServiceEdit($deliveryService)
{
$dataJson = json_encode($deliveryService);
$this->parameters['deliveryService'] = $dataJson;
$url = $this->apiUrl.'reference/delivery-services/'.$deliveryService['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка типов оплаты
*
* @return array - массив типов оплаты
*/
public function paymentTypesList()
{
$url = $this->apiUrl.'reference/payment-types';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование типа оплаты
*
* @param array $paymentType - информация о типе оплаты
* @return array
*/
public function paymentTypesEdit($paymentType)
{
$dataJson = json_encode($paymentType);
$this->parameters['paymentType'] = $dataJson;
$url = $this->apiUrl.'reference/payment-types/'.$paymentType['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка статусов оплаты
*
* @return array - массив статусов оплаты
*/
public function paymentStatusesList()
{
$url = $this->apiUrl.'reference/payment-statuses';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование статуса оплаты
*
* @param array $paymentStatus - информация о статусе оплаты
* @return array
*/
public function paymentStatusesEdit($paymentStatus)
{
$dataJson = json_encode($paymentStatus);
$this->parameters['paymentStatus'] = $dataJson;
$url = $this->apiUrl.'reference/payment-statuses/'.$paymentStatus['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка типов заказа
*
* @return array - массив типов заказа
*/
public function orderTypesList()
{
$url = $this->apiUrl.'reference/order-types';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование типа заказа
*
* @param array $orderType - информация о типе заказа
* @return array
*/
public function orderTypesEdit($orderType)
{
$dataJson = json_encode($orderType);
$this->parameters['orderType'] = $dataJson;
$url = $this->apiUrl.'reference/order-types/'.$orderType['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка способов оформления заказа
*
* @return array - массив способов оформления заказа
*/
public function orderMethodsList()
{
$url = $this->apiUrl.'reference/order-methods';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование способа оформления заказа
*
* @param array $orderMethod - информация о способе оформления заказа
* @return array
*/
public function orderMethodsEdit($orderMethod)
{
$dataJson = json_encode($orderMethod);
$this->parameters['orderMethod'] = $dataJson;
$url = $this->apiUrl.'reference/order-methods/'.$orderMethod['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка статусов заказа
*
* @return array - массив статусов заказа
*/
public function orderStatusesList()
{
$url = $this->apiUrl.'reference/statuses';
$result = $this->curlRequest($url);
return $result;
}
/**
* Редактирование статуса заказа
*
* @param array $status - информация о статусе заказа
* @return array
*/
public function orderStatusEdit($status)
{
$dataJson = json_encode($status);
$this->parameters['status'] = $dataJson;
$url = $this->apiUrl.'reference/statuses/'.$status['code'].'/edit';
$result = $this->curlRequest($url, 'POST');
return $result;
}
/**
* Получение списка групп статусов заказа
*
* @return array - массив групп статусов заказа
*/
public function orderStatusGroupsList()
{
$url = $this->apiUrl.'reference/status-groups';
$result = $this->curlRequest($url);
return $result;
}
/**
* Обновление статистики
*
* @return array - статус вып обновления
*/
public function statisticUpdate()
{
$url = $this->apiUrl.'statistic/update';
$result = $this->curlRequest($url);
return $result;
}
/**
* @return \DateTime
*/
public function getGeneratedAt()
{
return $this->generatedAt;
}
protected function ensureDateTime($value)
{
if ($value instanceof \DateTime) {
return $value->format('Y-m-d H:i:s');
} elseif (is_int($value)) {
return date('Y-m-d H:i:s', $value);
}
return $value;
}
protected function getErrorMessage($response)
{
$str = '';
if (isset($response['message']))
$str = $response['message'];
elseif (isset($response[0]['message']))
$str = $response[0]['message'];
elseif (isset($response['error']) && isset($response['error']['message']))
$str = $response['error']['message'];
elseif (isset($response['errorMsg']))
$str = $response['errorMsg'];
if (isset($response['errors']) && sizeof($response['errors'])) {
foreach ($response['errors'] as $error)
$str .= '. ' . $error;
}
if (!strlen($str))
return 'Application Error';
return $str;
}
protected function curlRequest($url, $method = 'GET', $format = 'json')
{
if ($method == 'GET' && !is_null($this->parameters))
$url .= '?'.http_build_query($this->parameters);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, FALSE);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 30s
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if ($method == 'POST')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->parameters);
}
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
unset($this->parameters);
/* Сброс массива с параметрами */
$this->parameters = array('apiKey' => $this->apiKey);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno)
throw new Exception\CurlException($error, $errno);
$result = json_decode($response, true);
if ($statusCode >= 400 || isset($result['success']) && $result['success'] === false) {
throw new Exception\ApiException($this->getErrorMessage($result), $statusCode);
}
if (isset($result['generatedAt'])) {
$this->generatedAt = new \DateTime($result['generatedAt']);
unset($result['generatedAt']);
}
unset($result['success']);
if (count($result) == 0)
return true;
return reset($result);
}
}

571
lib/RetailCrm/ApiClient.php Normal file
View File

@ -0,0 +1,571 @@
<?php
namespace RetailCrm;
use RetailCrm\Http\Client;
use RetailCrm\Response\ApiResponse;
/**
* retailCRM API client class
*/
class ApiClient
{
const VERSION = 'v3';
protected $client;
/**
* Client creating
*
* @param string $url
* @param string $apiKey
* @return void
*/
public function __construct($url, $apiKey)
{
if ('/' != substr($url, strlen($url) - 1, 1)) {
$url .= '/';
}
$url = $url . 'api/' . self::VERSION;
$this->client = new Client($url, array('apiKey' => $apiKey));
}
/**
* Create a order
*
* @param array $order
* @return ApiResponse
*/
public function ordersCreate(array $order)
{
if (!sizeof($order)) {
throw new \InvalidArgumentException('Parameter `order` must contains a data');
}
return $this->client->makeRequest("/orders/create", Client::METHOD_POST, array(
'order' => json_encode($order)
));
}
/**
* Edit a order
*
* @param array $order
* @return ApiResponse
*/
public function ordersEdit(array $order, $by = 'externalId')
{
if (!sizeof($order)) {
throw new \InvalidArgumentException('Parameter `order` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($order[$by])) {
throw new \InvalidArgumentException(sprintf('Order array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest("/orders/" . $order[$by] . "/edit", Client::METHOD_POST, array(
'order' => json_encode($order),
'by' => $by,
));
}
/**
* Upload array of the orders
*
* @param array $orders
* @return ApiResponse
*/
public function ordersUpload(array $orders)
{
if (!sizeof($orders)) {
throw new \InvalidArgumentException('Parameter `orders` must contains array of the orders');
}
return $this->client->makeRequest("/orders/upload", Client::METHOD_POST, array(
'orders' => json_encode($orders),
));
}
/**
* Get order by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @return ApiResponse
*/
public function ordersGet($id, $by = 'externalId')
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/orders/$id", Client::METHOD_GET, array('by' => $by));
}
/**
* Returns a orders history
*
* @param \DateTime $startDate (default: null)
* @param \DateTime $endDate (default: null)
* @param int $limit (default: 100)
* @param int $offset (default: 0)
* @return ApiResponse
*/
public function ordersHistory(\DateTime $startDate = null, \DateTime $endDate = null, $limit = 100, $offset = 0)
{
$parameters = array();
if ($startDate) {
$parameters['startDate'] = $startDate->format('Y-m-d H:i:s');
}
if ($endDate) {
$parameters['endDate'] = $endDate->format('Y-m-d H:i:s');
}
if ($limit) {
$parameters['limit'] = (int) $limit;
}
if ($offset) {
$parameters['offset'] = (int) $offset;
}
return $this->client->makeRequest('/orders/history', Client::METHOD_GET, $parameters);
}
/**
* Returns filtered orders list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return ApiResponse
*/
public function ordersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/orders', Client::METHOD_GET, $parameters);
}
/**
* Save order IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return ApiResponse
*/
public function ordersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new \InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/orders/fix-external-ids", Client::METHOD_POST, array(
'orders' => json_encode($ids),
));
}
/**
* Create a customer
*
* @param array $customer
* @return ApiResponse
*/
public function customersCreate(array $customer)
{
if (!sizeof($customer)) {
throw new \InvalidArgumentException('Parameter `customer` must contains a data');
}
return $this->client->makeRequest("/customers/create", Client::METHOD_POST, array(
'customer' => json_encode($customer)
));
}
/**
* Edit a customer
*
* @param array $customer
* @return ApiResponse
*/
public function customersEdit(array $customer, $by = 'externalId')
{
if (!sizeof($customer)) {
throw new \InvalidArgumentException('Parameter `customer` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($customer[$by])) {
throw new \InvalidArgumentException(sprintf('Customer array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest("/customers/" . $customer[$by] . "/edit", Client::METHOD_POST, array(
'customer' => json_encode($customer),
'by' => $by,
));
}
/**
* Upload array of the customers
*
* @param array $customers
* @return ApiResponse
*/
public function customersUpload(array $customers)
{
if (!sizeof($customers)) {
throw new \InvalidArgumentException('Parameter `customers` must contains array of the customers');
}
return $this->client->makeRequest("/customers/upload", Client::METHOD_POST, array(
'customers' => json_encode($customers),
));
}
/**
* Get customer by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @return ApiResponse
*/
public function customersGet($id, $by = 'externalId')
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/customers/$id", Client::METHOD_GET, array('by' => $by));
}
/**
* Returns filtered customers list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return ApiResponse
*/
public function customersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/customers', Client::METHOD_GET, $parameters);
}
/**
* Save customer IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return ApiResponse
*/
public function customersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new \InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/customers/fix-external-ids", Client::METHOD_POST, array(
'customers' => json_encode($ids),
));
}
/**
* Returns deliveryServices list
*
* @return ApiResponse
*/
public function deliveryServicesList()
{
return $this->client->makeRequest('/reference/delivery-services', Client::METHOD_GET);
}
/**
* Returns deliveryTypes list
*
* @return ApiResponse
*/
public function deliveryTypesList()
{
return $this->client->makeRequest('/reference/delivery-types', Client::METHOD_GET);
}
/**
* Returns orderMethods list
*
* @return ApiResponse
*/
public function orderMethodsList()
{
return $this->client->makeRequest('/reference/order-methods', Client::METHOD_GET);
}
/**
* Returns orderTypes list
*
* @return ApiResponse
*/
public function orderTypesList()
{
return $this->client->makeRequest('/reference/order-types', Client::METHOD_GET);
}
/**
* Returns paymentStatuses list
*
* @return ApiResponse
*/
public function paymentStatusesList()
{
return $this->client->makeRequest('/reference/payment-statuses', Client::METHOD_GET);
}
/**
* Returns paymentTypes list
*
* @return ApiResponse
*/
public function paymentTypesList()
{
return $this->client->makeRequest('/reference/payment-types', Client::METHOD_GET);
}
/**
* Returns productStatuses list
*
* @return ApiResponse
*/
public function productStatusesList()
{
return $this->client->makeRequest('/reference/product-statuses', Client::METHOD_GET);
}
/**
* Returns statusGroups list
*
* @return ApiResponse
*/
public function statusGroupsList()
{
return $this->client->makeRequest('/reference/status-groups', Client::METHOD_GET);
}
/**
* Returns statuses list
*
* @return ApiResponse
*/
public function statusesList()
{
return $this->client->makeRequest('/reference/statuses', Client::METHOD_GET);
}
/**
* Edit deliveryService
*
* @return ApiResponse
*/
public function deliveryServicesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-services/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'deliveryService' => json_encode($data)
)
);
}
/**
* Edit deliveryType
*
* @return ApiResponse
*/
public function deliveryTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-types/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'deliveryType' => json_encode($data)
)
);
}
/**
* Edit orderMethod
*
* @return ApiResponse
*/
public function orderMethodsEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-methods/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'orderMethod' => json_encode($data)
)
);
}
/**
* Edit orderType
*
* @return ApiResponse
*/
public function orderTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-types/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'orderType' => json_encode($data)
)
);
}
/**
* Edit paymentStatus
*
* @return ApiResponse
*/
public function paymentStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-statuses/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'paymentStatus' => json_encode($data)
)
);
}
/**
* Edit paymentType
*
* @return ApiResponse
*/
public function paymentTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-types/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'paymentType' => json_encode($data)
)
);
}
/**
* Edit productStatus
*
* @return ApiResponse
*/
public function productStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/product-statuses/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'productStatus' => json_encode($data)
)
);
}
/**
* Edit order status
*
* @return ApiResponse
*/
public function statusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new \InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/statuses/' . $data['code'] . '/edit',
Client::METHOD_POST,
array(
'status' => json_encode($data)
)
);
}
/**
* Update CRM basic statistic
*
* @return ApiResponse
*/
public function statisticUpdate()
{
return $this->client->makeRequest('/statistic/update', Client::METHOD_GET);
}
/**
* Check ID parameter
*
* @param string $by
* @return bool
*/
protected function checkIdParameter($by)
{
$allowedForBy = array('externalId', 'id');
if (!in_array($by, $allowedForBy)) {
throw new \InvalidArgumentException(sprintf(
'Value "%s" for parameter "by" is not valid. Allowed values are %s.',
$by,
implode(', ', $allowedForBy)
));
}
return true;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace RetailCrm\Exception;
class CurlException extends \RuntimeException
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace RetailCrm\Exception;
class InvalidJsonException extends \DomainException
{
}

View File

@ -0,0 +1,81 @@
<?php
namespace RetailCrm\Http;
use RetailCrm\Exception\CurlException;
use RetailCrm\Response\ApiResponse;
/**
* HTTP client
*/
class Client
{
const METHOD_GET = 'GET';
const METHOD_POST = 'POST';
protected $url;
protected $defaultParameters;
public function __construct($url, array $defaultParameters = array())
{
if (false === stripos($url, 'https://')) {
throw new \InvalidArgumentException('API schema requires HTTPS protocol');
}
$this->url = $url;
$this->defaultParameters = $defaultParameters;
}
/**
* Make HTTP request
*
* @param string $path
* @param string $method (default: 'GET')
* @param array $parameters (default: array())
* @return ApiResponse
*/
public function makeRequest($path, $method, array $parameters = array(), $timeout = 30)
{
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
if (!in_array($method, $allowedMethods)) {
throw new \InvalidArgumentException(sprintf(
'Method "%s" is not valid. Allowed methods are %s',
$method,
implode(', ', $allowedMethods)
));
}
$parameters = array_merge($this->defaultParameters, $parameters);
$path = $this->url . $path;
if (self::METHOD_GET === $method && sizeof($parameters)) {
$path .= '?' . http_build_query($parameters);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $path);
curl_setopt($ch, CURLOPT_FAILONERROR, FALSE);
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout); // times out after 30s
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if (self::METHOD_POST === $method) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
}
$responseBody = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno) {
throw new CurlException($error, $errno);
}
return new ApiResponse($statusCode, $responseBody);
}
}

View File

@ -0,0 +1,112 @@
<?php
namespace RetailCrm\Response;
use RetailCrm\Exception\InvalidJsonException;
/**
* Response from retailCRM API
*/
class ApiResponse implements \ArrayAccess
{
// HTTP response status code
protected $statusCode;
// response assoc array
protected $response;
public function __construct($statusCode, $responseBody = null)
{
$this->statusCode = (int) $statusCode;
if (!empty($responseBody)) {
$response = json_decode($responseBody, true);
if (!$response && JSON_ERROR_NONE !== ($error = json_last_error())) {
throw new InvalidJsonException(
"Invalid JSON in the API response body. Error code #$error",
$error
);
}
$this->response = $response;
}
}
/**
* Return HTTP response status code
*
* @return int
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* HTTP request was successful
*
* @return bool
*/
public function isSuccessful()
{
return $this->statusCode < 400;
}
/**
* Allow to access for the property throw class method
*
* @param string $name
* @return mixed
*/
public function __call($name, $arguments)
{
// convert getSomeProperty to someProperty
$propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4);
if (!isset($this->response[$propertyName])) {
throw new \InvalidArgumentException("Method \"$name\" not found");
}
return $this->response[$propertyName];
}
/**
* Allow to access for the property throw object property
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
if (!isset($this->response[$name])) {
throw new \InvalidArgumentException("Property \"$name\" not found");
}
return $this->response[$name];
}
public function offsetSet($offset, $value)
{
throw new \BadMethodCallException('This activity not allowed');
}
public function offsetUnset($offset)
{
throw new \BadMethodCallException('This call not allowed');
}
public function offsetExists($offset)
{
return isset($this->response[$offset]);
}
public function offsetGet($offset)
{
if (!isset($this->response[$offset])) {
throw new \InvalidArgumentException("Property \"$offset\" not found");
}
return $this->response[$offset];
}
}

21
phpunit.xml.dist Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php" colors="true">
<!-- Dummy values used to provide credentials. No need to change these. -->
<php>
<server name="CRM_URL" value="foo" />
<server name="CRM_API_KEY" value="bar" />
</php>
<testsuites>
<testsuite name="RetailCrm">
<directory>tests/RetailCrm/Tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/RetailCrm</directory>
</whitelist>
</filter>
</phpunit>

View File

@ -0,0 +1,20 @@
<?php
namespace RetailCrm\Test;
use RetailCrm\ApiClient;
class TestCase extends \PHPUnit_Framework_TestCase
{
/**
* Return ApiClient object
*
* @param string $url (default: null)
* @param string $apiKey (default: null)
* @return ApiClient
*/
public static function getApiClient($url = null, $apiKey = null)
{
return new ApiClient($url ?: $_SERVER['CRM_URL'], $apiKey ?: $_SERVER['CRM_API_KEY']);
}
}

View File

@ -0,0 +1,271 @@
<?php
namespace RetailCrm\Tests;
use RetailCrm\Test\TestCase;
class ApiClientCustomersTest extends TestCase
{
const FIRST_NAME = 'Иннокентий';
/**
* @group integration
*/
public function testCustomersCreate()
{
$client = static::getApiClient();
$externalId = 'c-create-' . time();
$response = $client->customersCreate(array(
'firstName' => self::FIRST_NAME,
'externalId' => $externalId,
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(201, $response->getStatusCode());
$this->assertTrue(is_int($response->getId()));
return array(
'id' => $response->getId(),
'externalId' => $externalId,
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersCreateExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->customersCreate(array());
}
/**
* @group integration
* @depends testCustomersCreate
*/
public function testCustomersGet(array $ids)
{
$client = static::getApiClient();
$response = $client->customersGet(678678678);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(404, $response->getStatusCode());
$this->assertFalse($response->success);
$response = $client->customersGet($ids['id'], 'id');
$customerById = $response->customer;
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->success);
$this->assertEquals(self::FIRST_NAME, $response->customer['firstName']);
$response = $client->customersGet($ids['externalId'], 'externalId');
$this->assertEquals($customerById['id'], $response->customer['id']);
return $ids;
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersGetException()
{
$client = static::getApiClient();
$response = $client->customersGet(678678678, 'asdf');
}
/**
* @group integration
* @depends testCustomersGet
*/
public function testCustomersEdit(array $ids)
{
$client = static::getApiClient();
$response = $client->customersEdit(
array(
'id' => 22342134,
'lastName' => '12345',
),
'id'
);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(404, $response->getStatusCode());
$response = $client->customersEdit(array(
'externalId' => $ids['externalId'],
'lastName' => '12345',
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->success);
$response = $client->customersEdit(array(
'externalId' => 'c-edit-' . time(),
'lastName' => '12345',
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(201, $response->getStatusCode());
$this->assertTrue($response->success);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersEditExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->customersEdit(array(), 'asdf');
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersEditException()
{
$client = static::getApiClient();
$response = $client->customersEdit(array('id' => 678678678), 'asdf');
}
/**
* @group integration
*/
public function testCustomersList()
{
$client = static::getApiClient();
$response = $client->customersList();
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertTrue($response->isSuccessful());
$this->assertTrue(isset($response['customers']));
$response = $client->customersList(array(), 1, 300);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertFalse(
$response->isSuccessful(),
'Pagination error'
);
$response = $client->customersList(array('maxOrdersCount' => 10), 1);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertTrue(
$response->isSuccessful(),
'API returns customers list'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersFixExternalIdsException()
{
$client = static::getApiClient();
$response = $client->customersFixExternalIds(array());
}
/**
* @group integration
*/
public function testCustomersFixExternalIds()
{
$client = static::getApiClient();
$response = $client->ordersCreate(array(
'firstName' => 'Aaa111',
));
$this->assertTrue(
$response->isSuccessful(),
'Order created'
);
$response = $client->ordersGet($response->id, 'id');
$this->assertTrue(
$response->isSuccessful(),
'Order fetched'
);
$id = $response->order['customer']['id'];
$externalId = 'asdf' . time();
$response = $client->customersFixExternalIds(array(
array('id' => $id, 'externalId' => $externalId)
));
$this->assertTrue(
$response->isSuccessful(),
'Fixed customer ids'
);
$response = $client->customersGet($externalId);
$this->assertTrue(
$response->isSuccessful(),
'Got customer'
);
$this->assertEquals(
$id,
$response->customer['id'],
'Fixing of customer ids were right'
);
$this->assertEquals(
$externalId,
$response->customer['externalId'],
'Fixing of customer ids were right'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testCustomersUploadExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->customersUpload(array());
}
/**
* @group integration
*/
public function testCustomersUpload()
{
$client = static::getApiClient();
$externalIdA = 'upload-a-' . time();
$externalIdB = 'upload-b-' . time();
$response = $client->customersUpload(array(
array(
'externalId' => $externalIdA,
'firstName' => 'Aaa',
),
array(
'externalId' => $externalIdB,
'lastName' => 'Bbb',
),
));
$this->assertTrue(
$response->isSuccessful(),
'Got customer'
);
$this->assertEquals(
$externalIdA,
$response->uploadedCustomers[0]['externalId']
);
$this->assertEquals(
$externalIdB,
$response->uploadedCustomers[1]['externalId']
);
}
}

View File

@ -0,0 +1,286 @@
<?php
namespace RetailCrm\Tests;
use RetailCrm\Test\TestCase;
class ApiClientOrdersTest extends TestCase
{
const FIRST_NAME = 'Иннокентий';
/**
* @group integration
*/
public function testOrdersCreate()
{
$client = static::getApiClient();
$externalId = 'o-create-' . time();
$response = $client->ordersCreate(array(
'firstName' => self::FIRST_NAME,
'externalId' => $externalId,
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(201, $response->getStatusCode());
$this->assertTrue(is_int($response->getId()));
return array(
'id' => $response->getId(),
'externalId' => $externalId,
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersCreateExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->ordersCreate(array());
}
/**
* @group integration
* @depends testOrdersCreate
*/
public function testOrdersGet(array $ids)
{
$client = static::getApiClient();
$response = $client->ordersGet(678678678);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(404, $response->getStatusCode());
$this->assertFalse($response->success);
$response = $client->ordersGet($ids['id'], 'id');
$orderById = $response->order;
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->success);
$this->assertEquals(self::FIRST_NAME, $response->order['firstName']);
$response = $client->ordersGet($ids['externalId'], 'externalId');
$this->assertEquals($orderById['id'], $response->order['id']);
return $ids;
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersGetException()
{
$client = static::getApiClient();
$response = $client->ordersGet(678678678, 'asdf');
}
/**
* @group integration
* @depends testOrdersGet
*/
public function testOrdersEdit(array $ids)
{
$client = static::getApiClient();
$response = $client->ordersEdit(
array(
'id' => 22342134,
'lastName' => '12345',
),
'id'
);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(404, $response->getStatusCode());
$response = $client->ordersEdit(array(
'externalId' => $ids['externalId'],
'lastName' => '12345',
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->success);
$response = $client->ordersEdit(array(
'externalId' => time(),
'lastName' => '12345',
));
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(201, $response->getStatusCode());
$this->assertTrue($response->success);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersEditExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->ordersEdit(array(), 'asdf');
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersEditException()
{
$client = static::getApiClient();
$response = $client->ordersEdit(array('id' => 678678678), 'asdf');
}
/**
* @group integration
*/
public function testOrdersHistory()
{
$client = static::getApiClient();
$response = $client->ordersHistory();
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->success);
$this->assertTrue(
isset($response['orders']),
'API returns orders history'
);
$this->assertTrue(
isset($response['generatedAt']),
'API returns generatedAt in orders history'
);
}
/**
* @group integration
*/
public function testOrdersList()
{
$client = static::getApiClient();
$response = $client->ordersList();
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertTrue($response->isSuccessful());
$this->assertTrue(isset($response['orders']));
$response = $client->ordersList(array(), 1, 300);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertFalse(
$response->isSuccessful(),
'Pagination error'
);
$response = $client->ordersList(array('paymentStatus' => 'paid'), 1);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertTrue(
$response->isSuccessful(),
'API returns orders list'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersFixExternalIdsException()
{
$client = static::getApiClient();
$response = $client->ordersFixExternalIds(array());
}
/**
* @group integration
] */
public function testOrdersFixExternalIds()
{
$client = static::getApiClient();
$response = $client->ordersCreate(array(
'firstName' => 'Aaa',
));
$this->assertTrue(
$response->isSuccessful(),
'Order created'
);
$id = $response->id;
$externalId = 'asdf' . time();
$response = $client->ordersFixExternalIds(array(
array('id' => $id, 'externalId' => $externalId)
));
$this->assertTrue(
$response->isSuccessful(),
'Fixed order ids'
);
$response = $client->ordersGet($externalId);
$this->assertTrue(
$response->isSuccessful(),
'Got order'
);
$this->assertEquals(
$id,
$response->order['id'],
'Fixing of order ids were right'
);
$this->assertEquals(
$externalId,
$response->order['externalId'],
'Fixing of order ids were right'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testOrdersUploadExceptionEmpty()
{
$client = static::getApiClient();
$response = $client->ordersUpload(array());
}
/**
* @group integration
*/
public function testOrdersUpload()
{
$client = static::getApiClient();
$externalIdA = 'upload-a-' . time();
$externalIdB = 'upload-b-' . time();
$response = $client->ordersUpload(array(
array(
'externalId' => $externalIdA,
'firstName' => 'Aaa',
),
array(
'externalId' => $externalIdB,
'lastName' => 'Bbb',
),
));
$this->assertTrue(
$response->isSuccessful(),
'Got order'
);
$this->assertEquals(
$externalIdA,
$response->uploadedOrders[0]['externalId']
);
$this->assertEquals(
$externalIdB,
$response->uploadedOrders[1]['externalId']
);
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace RetailCrm\Tests;
use RetailCrm\Test\TestCase;
class ApiClientReferenceTest extends TestCase
{
/**
* @group integration
* @dataProvider getListDictionaries
*/
public function testList($name)
{
$client = static::getApiClient();
$method = $name . 'List';
$response = $client->$method();
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertTrue($response->isSuccessful());
$this->assertTrue(isset($response[$name]));
$this->assertTrue(is_array($response[$name]));
}
/**
* @group integration
* @dataProvider getEditDictionaries
* @expectedException \InvalidArgumentException
*/
public function testEditingException($name)
{
$client = static::getApiClient();
$method = $name . 'Edit';
$response = $client->$method(array());
}
/**
* @group integration
* @dataProvider getEditDictionaries
*/
public function testEditing($name)
{
$client = static::getApiClient();
$code = 'dict-' . strtolower($name) . '-' . time();
$method = $name . 'Edit';
$params = array(
'code' => $code,
'name' => 'Aaa',
);
if ($name == 'statuses') {
$params['group'] = 'new';
}
$response = $client->$method($params);
$this->assertEquals(201, $response->getStatusCode());
$response = $client->$method(array(
'code' => $code,
'name' => 'Bbb',
));
if ($response->getStatusCode() > 201) {
print_r($response);
}
$this->assertEquals(200, $response->getStatusCode());
}
public function getListDictionaries()
{
return array(
array('deliveryServices'),
array('deliveryTypes'),
array('orderMethods'),
array('orderTypes'),
array('paymentStatuses'),
array('paymentTypes'),
array('productStatuses'),
array('statusGroups'),
array('statuses'),
);
}
public function getEditDictionaries()
{
return array(
array('deliveryServices'),
array('deliveryTypes'),
array('orderMethods'),
array('orderTypes'),
array('paymentStatuses'),
array('paymentTypes'),
array('productStatuses'),
array('statuses'),
);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace RetailCrm\Tests;
use RetailCrm\Test\TestCase;
class ApiClientTest extends TestCase
{
/**
* @group unit
*/
public function testConstruct()
{
$client = static::getApiClient();
$this->assertInstanceOf('RetailCrm\ApiClient', $client);
}
/**
* @group integration
*/
public function testStatisticUpdate()
{
$client = static::getApiClient();
$response = $client->statisticUpdate();
$this->assertTrue($response->isSuccessful());
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace RetailCrm\Tests\Http;
use RetailCrm\Test\TestCase;
use RetailCrm\ApiClient;
use RetailCrm\Http\Client;
class ClientTest extends TestCase
{
/**
* @group unit
*/
public function testConstruct()
{
$client = new Client('https://asdf.df', array());
$this->assertInstanceOf('RetailCrm\Http\Client', $client);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testHttpRequiring()
{
$client = new Client('http://a.intarocrm.ru', array('apiKey' => '123'));
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testMakeRequestWrongMethod()
{
$client = new Client('https://asdf.df', array());
$client->makeRequest('/a', 'adsf');
}
/**
* @group integration
* @expectedException RetailCrm\Exception\CurlException
*/
public function testMakeRequestWrongUrl()
{
$client = new Client('https://asdf.df', array());
$client->makeRequest('/a', Client::METHOD_GET, array(), 1);
}
/**
* @group integration
*/
public function testMakeRequestSuccess()
{
$client = new Client('https://demo.intarocrm.ru/api/' . ApiClient::VERSION, array());
$response = $client->makeRequest('/orders', Client::METHOD_GET);
$this->assertInstanceOf('RetailCrm\Response\ApiResponse', $response);
$this->assertEquals(403, $response->getStatusCode());
}
}

View File

@ -0,0 +1,233 @@
<?php
namespace RetailCrm\Tests\Response;
use RetailCrm\Test\TestCase;
use RetailCrm\Response\ApiResponse;
class ApiResponseTest extends TestCase
{
/**
* @group unit
*/
public function testSuccessConstruct()
{
$response = new ApiResponse(200);
$this->assertInstanceOf(
'RetailCrm\Response\ApiResponse',
$response,
'Response object created'
);
$response = new ApiResponse(201, '{ "success": true }');
$this->assertInstanceOf(
'RetailCrm\Response\ApiResponse',
$response,
'Response object created'
);
}
/**
* @group unit
* @expectedException RetailCrm\Exception\InvalidJsonException
*/
public function testJsonInvalid()
{
$response = new ApiResponse(400, '{ "asdf": }');
}
/**
* @group unit
*/
public function testStatusCodeGetting()
{
$response = new ApiResponse(200);
$this->assertEquals(
200,
$response->getStatusCode(),
'Response object returns the right status code'
);
$response = new ApiResponse(460, '{ "success": false }');
$this->assertEquals(
460,
$response->getStatusCode(),
'Response object returns the right status code'
);
}
/**
* @group unit
*/
public function testIsSuccessful()
{
$response = new ApiResponse(200);
$this->assertTrue(
$response->isSuccessful(),
'Request was successful'
);
$response = new ApiResponse(460, '{ "success": false }');
$this->assertFalse(
$response->isSuccessful(),
'Request was failed'
);
}
/**
* @group unit
*/
public function testMagicCall()
{
$response = new ApiResponse(201, '{ "success": true }');
$this->assertEquals(
true,
$response->getSuccess(),
'Response object returns property value throw magic method'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testMagicCallException1()
{
$response = new ApiResponse(200);
$response->getSome();
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testMagicCallException2()
{
$response = new ApiResponse(201, '{ "success": true }');
$response->getSomeSuccess();
}
/**
* @group unit
*/
public function testMagicGet()
{
$response = new ApiResponse(201, '{ "success": true }');
$this->assertEquals(
true,
$response->success,
'Response object returns property value throw magic get'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testMagicGetException1()
{
$response = new ApiResponse(200);
$response->some;
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testMagicGetException2()
{
$response = new ApiResponse(201, '{ "success": true }');
$response->someSuccess;
}
/**
* @group unit
*/
public function testArrayGet()
{
$response = new ApiResponse(201, '{ "success": true }');
$this->assertEquals(
true,
$response['success'],
'Response object returns property value throw magic array get'
);
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testArrayGetException1()
{
$response = new ApiResponse(200);
$response['some'];
}
/**
* @group unit
* @expectedException \InvalidArgumentException
*/
public function testArrayGetException2()
{
$response = new ApiResponse(201, '{ "success": true }');
$response['someSuccess'];
}
/**
* @group unit
*/
public function testArrayIsset()
{
$response = new ApiResponse(201, '{ "success": true }');
$this->assertTrue(
isset($response['success']),
'Response object returns property existing'
);
$this->assertFalse(
isset($response['suess']),
'Response object returns property existing'
);
}
/**
* @group unit
* @expectedException \BadMethodCallException
*/
public function testArraySetException1()
{
$response = new ApiResponse(201, '{ "success": true }');
$response['success'] = 'a';
}
/**
* @group unit
* @expectedException \BadMethodCallException
*/
public function testArraySetException2()
{
$response = new ApiResponse(201, '{ "success": true }');
$response['sssssssuccess'] = 'a';
}
/**
* @group unit
* @expectedException \BadMethodCallException
*/
public function testArrayUnsetException1()
{
$response = new ApiResponse(201, '{ "success": true }');
unset($response['success']);
}
/**
* @group unit
* @expectedException \BadMethodCallException
*/
public function testArrayUnsetException2()
{
$response = new ApiResponse(201, '{ "success": true }');
unset($response['sssssssuccess']);
}
}

4
tests/bootstrap.php Normal file
View File

@ -0,0 +1,4 @@
<?php
$loader = require dirname(__DIR__) . '/vendor/autoload.php';
$loader->add('RetailCrm\\Test', __DIR__);