mirror of
https://github.com/retailcrm/legacy.git
synced 2024-11-21 21:06:02 +03:00
init
This commit is contained in:
commit
a11b98a479
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/retailcrm/data/config/settings.ini
|
||||
/retailcrm/data/upload/*.xml
|
||||
/retailcrm/data/upload/*.gz
|
||||
/retailcrm/data/logs/*/*.log
|
||||
|
||||
/retailcrm/bundle/handler/*.php
|
||||
/retailcrm/bundle/mail/*.txt
|
||||
/retailcrm/bundle/sql/*.sql
|
||||
/retailcrm/bundle/extend/*/*.php
|
46
CHANGELOG.md
Normal file
46
CHANGELOG.md
Normal file
@ -0,0 +1,46 @@
|
||||
v.1.0.0
|
||||
Структура модульная, под каждый "таск" тперь создается 2 файла: sql|txt + класс обработчик
|
||||
Внесено множество мелких улучшений по отображению сообшений об ошибках и правилам наследования
|
||||
Добавлена возможность кастомизации под конкреную интеграцию
|
||||
Query удален из проекта, заменен на Builder + Rule
|
||||
Init удален из проекта, заменен на Container (singleton)
|
||||
Вызов ApiClient осуществляется через RequestProxy (обвязка обрабатывающая исключения и логгируюшая проблемы)
|
||||
Пути к логам исключены из файла настроек, теперь они зашиты в контейнер
|
||||
Доработан модуль работы с почтой (в том числе под несколько ящиков)
|
||||
Добавлена возможность сделать дамп БД прямо из консольного приложения
|
||||
|
||||
v.0.3.0
|
||||
Добавлена обработка почтовых ящиков для создания заказов на основании писем
|
||||
Изменен конфигурационный файл, теперь инициализацию подключения к БД или почте можно деактивировать
|
||||
Внесены коррективы в класс Autoloader для нормальной работы с версией php 5.2.17 и ниже
|
||||
Обновлен api клиент до последней акутальной версии
|
||||
|
||||
v.0.2.3
|
||||
Добавлен класс валидации данных
|
||||
Добавлена очистка данных от мусора
|
||||
Добавлена автоматическая кодировка
|
||||
Добавлена разбивка ФИО
|
||||
Установка date.timezone если не заданна
|
||||
|
||||
v.0.2.2
|
||||
Обновление заказов
|
||||
Стабилизация проверки клиента на уникальность
|
||||
Обратная совместимость Autoloader для 5.2
|
||||
Перенос QueryInterface в директорию db
|
||||
Обновление методов Init
|
||||
|
||||
v.0.2.1
|
||||
Выгрузка словарей
|
||||
Новый autoloader
|
||||
Обновление ApiClient до актуальной версии
|
||||
Добавлены примеры для cms: NetCat, PHPShop, HostCMS
|
||||
|
||||
v.0.1.2
|
||||
Устранение ошибок в ApiHelper/checkCustomer
|
||||
|
||||
v.0.1.1
|
||||
|
||||
Выгрузка старых клиентов и заказов
|
||||
Выгрузка текущих заказов по cron
|
||||
Генерация ICML по cron
|
||||
Получение истории по cron
|
80
README.md
Normal file
80
README.md
Normal file
@ -0,0 +1,80 @@
|
||||
Legacy
|
||||
======
|
||||
|
||||
Микрофреймворк для устаревших платформ (php <= 5.2.17), либо, в случае отсутствия
|
||||
возможности создать модуль для конкретной платформы.
|
||||
|
||||
### Установка
|
||||
* Распаковать директорию retailcrm в корень проекта
|
||||
* На основе файла data/config/settings-dist.ini создать конфигурационный файл data/config/settings.ini
|
||||
* Создать необходимые sql файлы, файлы с критериями поиска писем и их обработчки (в случае их отсутствия скрипт даст подсказку)
|
||||
|
||||
### Настройка
|
||||
Скрипт выполняет определенные действия в зависимости от переданных параметров.
|
||||
Пример параметров можно увидеть, запустив скрипт без них:
|
||||
|
||||
```
|
||||
php app.php
|
||||
```
|
||||
|
||||
Обмен работает через вызов скрипта по cron, в частности производится:
|
||||
|
||||
1. Выгрузка новых заказов из магазина в CRM
|
||||
2. Выгрузка новых клиентов из магазина в CRM
|
||||
3. Получение изменений из CRM и запись их в БД сайта
|
||||
4. Выгрузка каталога товаров в ICML файл
|
||||
5. Выгрузка справочников (доставки, типы оплат, статусы заказов)
|
||||
6. Выгрузка заказов из почты
|
||||
|
||||
Для этого необходимо создать следующие записи:
|
||||
|
||||
```
|
||||
*/5 * * * * /path/to/php /path/to/retailcrm/app.php -e orders -l
|
||||
*/5 * * * * /path/to/php /path/to/retailcrm/app.php -e mail -m mail@example.com
|
||||
*/25 * * * * /path/to/php /path/to/retailcrm/app.php -e customers -l
|
||||
*/15 * * * * /path/to/php /path/to/retailcrm/app.php -e history
|
||||
* */6 * * * /path/to/php /path/to/retailcrm/app.php -e icml
|
||||
* 3 * * * /path/to/php /path/to/retailcrm/app.php -e references
|
||||
```
|
||||
|
||||
В случае, если для консольного окружения нет отдельного php.ini (чаще всего на FreeBSD),
|
||||
а подключение модулей (mysql.so, dom.so, xmlwriter.so) выполняется отельно, необходимо
|
||||
при запуске скрипта явно указать путь к php.ini, можно к тому, который используется
|
||||
при вызове php через libapache-mod-php (путь к нему покажет phpinfo()):
|
||||
|
||||
```
|
||||
*/5 * * * * /path/to/php -c /path/to/php.ini /path/to/retailcrm/app.php -e orders -l
|
||||
*/15 * * * * /path/to/php -c /path/to/php.ini /path/to/retailcrm/app.php -e history
|
||||
* */6 * * * /path/to/php -c /path/to/php.ini /path/to/retailcrm/app.php -e icml
|
||||
```
|
||||
|
||||
### Параметры
|
||||
|
||||
#### Общие параметры запуска
|
||||
|
||||
Общие параметры передаются с помощью ключа -e:
|
||||
|
||||
* icml - генерация icml файла
|
||||
* history - получение истории изменений из CRM для обновления данных в БД сайта
|
||||
* orders - выгрузка последних заказов (выгружаются заказы, сформированые с момента предыдущего запуска скрипта)
|
||||
* customers - выгрузка последних клиентов (выгружаются клиенты, не имеющие заказов, сформированые с момента предыдущего запуска скрипта)
|
||||
* references - выгрузка справочников (по расписанию можно выгружать все справочники, если они доступны)
|
||||
* mail - выгрузка заказов из почты (выгружаются заказы из писем)
|
||||
* dump - выгрузка дампа БД
|
||||
|
||||
#### Дополнительные параметры запуска
|
||||
|
||||
* Ручной запуск с передачей дополнительных параметров для выгрузки конкретного справочника:
|
||||
```
|
||||
/usr/bin/php -i /etc/cli/php.ini -f app.php -e reference -r delivery-types
|
||||
```
|
||||
* Выгрузка 1 заказа:
|
||||
```
|
||||
/usr/bin/php -i /etc/cli/php.ini -f app.php -e orders -p 12345
|
||||
```
|
||||
* Выгрузка нескольких клиентов:
|
||||
```
|
||||
/usr/bin/php -i /etc/cli/php.ini -f app.php -e customers -p 404,417-423
|
||||
```
|
||||
|
||||
|
1
retailcrm/.htaccess
Normal file
1
retailcrm/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
20
retailcrm/app.php
Normal file
20
retailcrm/app.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
if (
|
||||
function_exists('date_default_timezone_set')
|
||||
&&
|
||||
function_exists('date_default_timezone_get')
|
||||
) {
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
|
||||
require_once 'bootstrap.php';
|
||||
|
||||
$options = getopt('luce:m:p:r:h:');
|
||||
|
||||
if (isset($options['e'])) {
|
||||
$command = new Command($options);
|
||||
$command->run();
|
||||
} else {
|
||||
CommandHelper::runHelp();
|
||||
}
|
99
retailcrm/bootstrap.php
Normal file
99
retailcrm/bootstrap.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Rob Dunham
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple Recursive Autoloader
|
||||
*
|
||||
* A simple autoloader that loads class files recursively starting in the directory
|
||||
* where this class resides. Additional options can be provided to control the naming
|
||||
* convention of the class files.
|
||||
*
|
||||
* @package Autoloader
|
||||
* @license http://opensource.org/licenses/MIT MIT License
|
||||
* @author Rob Dunham <contact@robunham.info>
|
||||
* @author Alex Lushpai <lushpai@gmail.com>
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* File extension as a string. Defaults to ".php".
|
||||
*/
|
||||
protected static $fileExt = '.php';
|
||||
|
||||
/**
|
||||
* The top level directory where recursion will begin.
|
||||
*
|
||||
*/
|
||||
protected static $pathTop;
|
||||
|
||||
/**
|
||||
* Autoload function for registration with spl_autoload_register
|
||||
*
|
||||
* Looks recursively through project directory and loads class files based on
|
||||
* filename match.
|
||||
*
|
||||
* @param string $className
|
||||
*/
|
||||
public static function loader($className)
|
||||
{
|
||||
$directory = new RecursiveDirectoryIterator(self::$pathTop);
|
||||
$fileIterator = new RecursiveIteratorIterator($directory);
|
||||
$filename = $className . self::$fileExt;
|
||||
|
||||
foreach ($fileIterator as $file) {
|
||||
if (strtolower($file->getFilename()) === strtolower($filename) && $file->isReadable()) {
|
||||
include_once $file->getPathname();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $fileExt property
|
||||
*
|
||||
* @param string $fileExt The file extension used for class files. Default is "php".
|
||||
*/
|
||||
public static function setFileExt($fileExt)
|
||||
{
|
||||
self::$fileExt = $fileExt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $path property
|
||||
*
|
||||
* @param string $path The path representing the top level where recursion should
|
||||
* begin. Defaults to the current directory.
|
||||
*/
|
||||
public static function setPath($path)
|
||||
{
|
||||
self::$pathTop = $path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Autoloader::setPath(realpath(dirname(__FILE__)));
|
||||
Autoloader::setFileExt('.php');
|
||||
spl_autoload_register('Autoloader::loader');
|
0
retailcrm/bundle/extend/.gitkeep
Normal file
0
retailcrm/bundle/extend/.gitkeep
Normal file
0
retailcrm/bundle/extend/Builders/.gitkeep
Normal file
0
retailcrm/bundle/extend/Builders/.gitkeep
Normal file
0
retailcrm/bundle/extend/Components/.gitkeep
Normal file
0
retailcrm/bundle/extend/Components/.gitkeep
Normal file
0
retailcrm/bundle/extend/Helpers/.gitkeep
Normal file
0
retailcrm/bundle/extend/Helpers/.gitkeep
Normal file
0
retailcrm/bundle/extend/Vendor/.gitkeep
vendored
Normal file
0
retailcrm/bundle/extend/Vendor/.gitkeep
vendored
Normal file
0
retailcrm/bundle/handler/.gitkeep
Normal file
0
retailcrm/bundle/handler/.gitkeep
Normal file
0
retailcrm/bundle/mail/.gitkeep
Normal file
0
retailcrm/bundle/mail/.gitkeep
Normal file
0
retailcrm/bundle/sql/.gitkeep
Normal file
0
retailcrm/bundle/sql/.gitkeep
Normal file
1
retailcrm/data/config/.htaccess
Normal file
1
retailcrm/data/config/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
29
retailcrm/data/config/settings-dist.ini
Normal file
29
retailcrm/data/config/settings-dist.ini
Normal file
@ -0,0 +1,29 @@
|
||||
[general]
|
||||
domain=site.ru
|
||||
icml_file=retailcrm.xml
|
||||
shop_url=http://www.site.ru
|
||||
shop_name=Simple Shop
|
||||
support=integration@retailcrm.ru
|
||||
|
||||
[api]
|
||||
url=https://demo.retailcrm.ru
|
||||
key=api_key_value
|
||||
|
||||
[db]
|
||||
host=localhost
|
||||
user=db_user
|
||||
password=db_password
|
||||
dbname=db_name
|
||||
driver=mysql
|
||||
enabled=false
|
||||
|
||||
[mail]
|
||||
mail@example.com=login,password,imap.example.com,993,imap
|
||||
mail@example.org=login,password,pop.example.org,995,pop
|
||||
enabled=false
|
||||
|
||||
[amocrm]
|
||||
domain=example
|
||||
login=login
|
||||
key=key
|
||||
enabled=false
|
1
retailcrm/data/logs/.htaccess
Normal file
1
retailcrm/data/logs/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
1
retailcrm/data/logs/customer/.htaccess
Normal file
1
retailcrm/data/logs/customer/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
1
retailcrm/data/logs/error/.htaccess
Normal file
1
retailcrm/data/logs/error/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
1
retailcrm/data/logs/mail/.htaccess
Normal file
1
retailcrm/data/logs/mail/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
1
retailcrm/data/logs/order/.htaccess
Normal file
1
retailcrm/data/logs/order/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
1
retailcrm/data/upload/.htaccess
Normal file
1
retailcrm/data/upload/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
allow from all
|
1
retailcrm/src/.htaccess
Normal file
1
retailcrm/src/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
deny from All
|
20
retailcrm/src/Bulders/CategoriesBuilder.php
Normal file
20
retailcrm/src/Bulders/CategoriesBuilder.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class CategoriesBuilder extends Builder
|
||||
{
|
||||
|
||||
/**
|
||||
* getCategories
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCategories()
|
||||
{
|
||||
$query = $this->rule->getSQL('categories');
|
||||
$handler = $this->rule->getHandler('CategoriesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
|
||||
}
|
||||
}
|
99
retailcrm/src/Bulders/CustomersBuilder.php
Normal file
99
retailcrm/src/Bulders/CustomersBuilder.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
class CustomersBuilder extends Builder
|
||||
{
|
||||
|
||||
/**
|
||||
* Get all customers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomers()
|
||||
{
|
||||
$query = $this->rule->getSQL('customers');
|
||||
$handler = $this->rule->getHandler('CustomersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all new customers since last run
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersLast()
|
||||
{
|
||||
$lastSync = DataHelper::getDate($this->container->customersLog);
|
||||
|
||||
$query = $this->rule->getSQL('customers_last');
|
||||
$handler = $this->rule->getHandler('CustomersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':lastSync', $lastSync);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get new customers by id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersById($uidString)
|
||||
{
|
||||
$query = $this->rule->getSQL('customers_uid');
|
||||
$handler = $this->rule->getHandler('CustomersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':orderIds', $uids);
|
||||
$uids = DataHelper::explodeUids($uidString);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all updated customers since last run
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersUpdate()
|
||||
{
|
||||
$lastSync = DataHelper::getDate($this->container->customersUpdatesLog);
|
||||
|
||||
$query = $this->rule->getSQL('customers_update_last');
|
||||
$handler = $this->rule->getHandler('CustomersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':lastSync', $lastSync);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updated customer by id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersUpdateById($uidString)
|
||||
{
|
||||
$query = $this->rule->getSQL('customers_update_uid');
|
||||
$handler = $this->rule->getHandler('CustomersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':orderIds', $uids);
|
||||
$uids = DataHelper::explodeUids($uidString);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom update
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersCustomUpdate()
|
||||
{
|
||||
$query = $this->rule->getSQL('customers_update_custom');
|
||||
$handler = $this->rule->getHandler('CustomersCustomUpdateHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
}
|
26
retailcrm/src/Bulders/HistoryBuilder.php
Normal file
26
retailcrm/src/Bulders/HistoryBuilder.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class HistoryBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Update orders
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersHistory($orders)
|
||||
{
|
||||
$handler = $this->rule->getHandler('OrdersHistoryHandler');
|
||||
return $this->update($handler, $orders);
|
||||
}
|
||||
|
||||
/**
|
||||
* updateCustomers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildCustomersHistory($customers)
|
||||
{
|
||||
$handler = $this->rule->getHandler('CustomersHistoryHandler');
|
||||
return $this->update($handler, $customers);
|
||||
}
|
||||
}
|
19
retailcrm/src/Bulders/OffersBuilder.php
Normal file
19
retailcrm/src/Bulders/OffersBuilder.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class OffersBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* getOffers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOffers()
|
||||
{
|
||||
$query = $this->rule->getSQL('offers');
|
||||
$handler = $this->rule->getHandler('OffersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':shop_url', $this->container->shopUrl);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
}
|
98
retailcrm/src/Bulders/OrdersBuilder.php
Normal file
98
retailcrm/src/Bulders/OrdersBuilder.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
class OrdersBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Get all orders
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrders()
|
||||
{
|
||||
$query = $this->rule->getSQL('orders');
|
||||
$handler = $this->rule->getHandler('OrdersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all new orders since last run
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersLast()
|
||||
{
|
||||
$lastSync = DataHelper::getDate($this->container->ordersLog);
|
||||
|
||||
$query = $this->rule->getSQL('orders_last');
|
||||
$handler = $this->rule->getHandler('OrdersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':lastSync', $lastSync);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get new orders by id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersById($uidString)
|
||||
{
|
||||
$query = $this->rule->getSQL('orders_uid');
|
||||
$handler = $this->rule->getHandler('OrdersHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':orderIds', $uids);
|
||||
$uids = DataHelper::explodeUids($uidString);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all updated orders since last run
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersUpdate()
|
||||
{
|
||||
$lastSync = DataHelper::getDate($this->container->ordersUpdatesLog);
|
||||
|
||||
$query = $this->rule->getSQL('orders_update_last');
|
||||
$handler = $this->rule->getHandler('OrdersUpdateHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':lastSync', $lastSync);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updated orders by id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersUpdateById($uidString)
|
||||
{
|
||||
$uids = DataHelper::explodeUids($uidString);
|
||||
$query = $this->rule->getSQL('orders_update_uid');
|
||||
$handler = $this->rule->getHandler('OrdersUpdateHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
$this->sql->bindParam(':orderIds', $uids);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom update
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildOrdersCustomUpdate()
|
||||
{
|
||||
$query = $this->rule->getSQL('orders_update_custom');
|
||||
$handler = $this->rule->getHandler('OrdersCustomUpdateHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
}
|
50
retailcrm/src/Bulders/ReferencesBuilder.php
Normal file
50
retailcrm/src/Bulders/ReferencesBuilder.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class ReferencesBuilder extends Builder
|
||||
{
|
||||
public function buildDeliveryTypes()
|
||||
{
|
||||
$query = $this->rule->getSQL('delivery_types');
|
||||
$handler = $this->rule->getHandler('DeliveryTypesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
public function buildDeliveryServices()
|
||||
{
|
||||
$query = $this->rule->getSQL('delivery_services');
|
||||
$handler = $this->rule->getHandler('DeliveryServicesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
public function buildPaymentTypes()
|
||||
{
|
||||
$query = $this->rule->getSQL('payment_types');
|
||||
$handler = $this->rule->getHandler('PaymentTypesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
public function buildPaymentStatuses()
|
||||
{
|
||||
$query = $this->rule->getSQL('payment_statuses');
|
||||
$handler = $this->rule->getHandler('PaymentStatusesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
public function buildStatuses()
|
||||
{
|
||||
$query = $this->rule->getSQL('statuses');
|
||||
$handler = $this->rule->getHandler('StatusesHandler');
|
||||
$this->sql = $this->container->db->prepare($query);
|
||||
|
||||
return $this->build($handler);
|
||||
}
|
||||
|
||||
}
|
36
retailcrm/src/Components/Builder.php
Normal file
36
retailcrm/src/Components/Builder.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
abstract class Builder
|
||||
{
|
||||
protected $sql;
|
||||
protected $rule;
|
||||
protected $container;
|
||||
protected $logger;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->rule = new Rule();
|
||||
$this->logger = new Logger();
|
||||
$this->container = Container::getInstance();
|
||||
}
|
||||
|
||||
protected function build($handler)
|
||||
{
|
||||
try {
|
||||
$this->sql->execute();
|
||||
$result = $this->sql->fetchAll(PDO::FETCH_ASSOC);
|
||||
return $handler->prepare($result);
|
||||
} catch (PDOException $e) {
|
||||
$this->logger->write(
|
||||
'PDO: ' . $e->getMessage(),
|
||||
$this->container->errorLog
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function update($handler, $data)
|
||||
{
|
||||
return $handler->prepare($data);
|
||||
}
|
||||
}
|
266
retailcrm/src/Components/Command.php
Normal file
266
retailcrm/src/Components/Command.php
Normal file
@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
class Command
|
||||
{
|
||||
|
||||
private $run;
|
||||
private $uid;
|
||||
private $mail;
|
||||
private $ref;
|
||||
private $limit;
|
||||
private $update;
|
||||
private $container;
|
||||
|
||||
public function __construct($arguments)
|
||||
{
|
||||
$this->run = (isset($arguments['e'])) ? trim($arguments['e']) : false;
|
||||
$this->uid = (isset($arguments['p'])) ? trim($arguments['p']) : false;
|
||||
$this->ref = (isset($arguments['r'])) ? trim($arguments['r']) : false;
|
||||
$this->mail = (isset($arguments['m'])) ? trim($arguments['m']) : false;
|
||||
$this->history = isset($arguments['h']) ? trim($arguments['h']) : false;
|
||||
|
||||
$this->limit = isset($arguments['l']);
|
||||
$this->update = isset($arguments['u']);
|
||||
$this->custom = isset($arguments['c']);
|
||||
|
||||
$this->container = Container::getInstance();
|
||||
|
||||
$this->api = new RequestProxy(
|
||||
$this->container->settings['api']['url'],
|
||||
$this->container->settings['api']['key']
|
||||
);
|
||||
|
||||
$this->requestHelper = new ApiHelper($this->api);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
if (!$this->run) {
|
||||
CommandHelper::runHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
$command = 'run' . ucfirst($this->run);
|
||||
|
||||
return $this->$command();
|
||||
}
|
||||
|
||||
public function runDump()
|
||||
{
|
||||
$dbUser = $this->container->settings['db']['user'];
|
||||
$dbPass = $this->container->settings['db']['password'];
|
||||
$dbName = $this->container->settings['db']['dbname'];
|
||||
$dbHost = $this->container->settings['db']['host'];
|
||||
|
||||
$dumpfile = $this->container->saveDir . "dbdump.sql.gz";
|
||||
|
||||
$cmd = "mysqldump -u $dbUser --password=$dbPass --host=$dbHost $dbName | gzip --best > $dumpfile";
|
||||
passthru($cmd);
|
||||
}
|
||||
|
||||
public function runIcml()
|
||||
{
|
||||
$categories = new CategoriesBuilder();
|
||||
$offers = new OffersBuilder();
|
||||
$icml = new IcmlHelper($this->container->shopName, $this->container->icml);
|
||||
|
||||
$icml->generate($categories->buildCategories(), $offers->buildOffers());
|
||||
}
|
||||
|
||||
public function runOrders()
|
||||
{
|
||||
$builder = new OrdersBuilder();
|
||||
$orders = array();
|
||||
|
||||
if ($this->update) {
|
||||
if ($this->uid) {
|
||||
$orders = $builder->buildOrdersUpdateById($this->uid);
|
||||
} elseif ($this->custom) {
|
||||
$orders = $builder->buildOrdersCustomUpdate();
|
||||
} elseif ($this->limit) {
|
||||
$orders = $builder->buildOrdersUpdate();
|
||||
} else {
|
||||
CommandHelper::updateNotice();
|
||||
}
|
||||
|
||||
if (!empty($orders)) {
|
||||
$this->requestHelper->updateOrders($orders);
|
||||
}
|
||||
} else {
|
||||
$this->check = true;
|
||||
|
||||
if ($this->uid) {
|
||||
$orders = $builder->buildOrdersById($this->uid);
|
||||
} elseif ($this->limit) {
|
||||
$orders = $builder->buildOrdersLast();
|
||||
} else {
|
||||
$this->check = false;
|
||||
$orders = $builder->buildOrders();
|
||||
}
|
||||
|
||||
if (!empty($orders)) {
|
||||
$this->requestHelper->uploadOrders($orders, $this->check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function runCustomers()
|
||||
{
|
||||
$builder = new CustomersBuilder();
|
||||
$customers = array();
|
||||
|
||||
if ($this->update) {
|
||||
if ($this->uid) {
|
||||
$customers = $builder->buildCustomersUpdateById($this->uid);
|
||||
} elseif ($this->custom) {
|
||||
$customers = $builder->buildCustomersCustomUpdate();
|
||||
} elseif ($this->limit) {
|
||||
$customers = $builder->buildCustomersUpdate();
|
||||
} else {
|
||||
CommandHelper::updateNotice();
|
||||
}
|
||||
|
||||
if (!empty($customers)) {
|
||||
$this->requestHelper->updateCustomers($customers);
|
||||
}
|
||||
} else {
|
||||
if ($this->uid) {
|
||||
$customers = $builder->buildCustomersById($this->uid);
|
||||
} elseif ($this->limit) {
|
||||
$customers = $builder->buildCustomersLast();
|
||||
} else {
|
||||
$customers = $builder->buildCustomers();
|
||||
}
|
||||
|
||||
if (!empty($customers)) {
|
||||
$this->requestHelper->uploadCustomers($customers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function runHistory()
|
||||
{
|
||||
$builder = new HistoryBuilder();
|
||||
|
||||
if (!empty($this->history)) {
|
||||
switch ($this->history) {
|
||||
case 'orders':
|
||||
$orders = $this->requestHelper->ordersHistory();
|
||||
if(!empty($orders)) $builder->buildOrdersHistory($orders);
|
||||
break;
|
||||
case 'customers':
|
||||
/**
|
||||
* Waiting for v4
|
||||
* $customers = $this->requestHelper->ordersCustomers();
|
||||
* $builder->buildCustomersHistory($customers);
|
||||
*/
|
||||
echo "\e[0;36mNot implemented yet\e[0m\n";
|
||||
break;
|
||||
default:
|
||||
CommandHelper::refHelp('history');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$orders = $this->requestHelper->ordersHistory();
|
||||
if(!empty($orders)) $builder->buildOrdersHistory($orders);
|
||||
/**
|
||||
* Waiting for v4
|
||||
* $customers = $this->requestHelper->ordersCustomers();
|
||||
* $builder->buildCustomersHistory($customers);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public function runReferences()
|
||||
{
|
||||
$builder = new ReferencesBuilder();
|
||||
if (!empty($this->ref)) {
|
||||
$reference = array();
|
||||
switch ($this->ref) {
|
||||
case 'delivery-types':
|
||||
$reference = $builder->buildDeliveryTypes();
|
||||
$this->requestHelper->uploadDeliveryTypes($reference);
|
||||
break;
|
||||
case 'delivery-services':
|
||||
$reference = $builder->buildDeliveryServices();
|
||||
$this->requestHelper->uploadDeliveryServices($reference);
|
||||
break;
|
||||
case 'payment-types':
|
||||
$reference = $builder->buildPaymentTypes();
|
||||
$this->requestHelper->uploadPaymentTypes($reference);
|
||||
break;
|
||||
case 'payment-statuses':
|
||||
$reference = $builder->buildPaymentStatuses();
|
||||
$this->requestHelper->uploadDeliveryStatuses($reference);
|
||||
break;
|
||||
case 'statuses':
|
||||
$reference = $builder->buildStatuses();
|
||||
$this->requestHelper->uploadStatuses($reference);
|
||||
break;
|
||||
default:
|
||||
CommandHelper::refHelp('references');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$deliveryTypes = $builder->buildDeliveryTypes();
|
||||
$this->requestHelper->uploadDeliveryTypes($deliveryTypes);
|
||||
|
||||
$deliveryServices = $builder->buildDeliveryServices();
|
||||
$this->requestHelper->uploadDeliveryServices($deliveryServices);
|
||||
|
||||
$paymentTypes = $builder->buildPaymentTypes();
|
||||
$this->requestHelper->uploadPaymentTypes($paymentTypes);
|
||||
|
||||
$paymentStatuses = $builder->buildPaymentStatuses();
|
||||
$this->requestHelper->uploadDeliveryStatuses($paymentStatuses);
|
||||
|
||||
$statuses = $builder->buildStatuses();
|
||||
$this->requestHelper->uploadStatuses($statuses);
|
||||
}
|
||||
}
|
||||
|
||||
public function runMail()
|
||||
{
|
||||
if (empty($this->mail)) {
|
||||
CommandHelper::paramNotice('-m');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (filter_var($this->mail, FILTER_VALIDATE_EMAIL)) {
|
||||
$mailer = new Mail($this->mail);
|
||||
$data = $mailer->parse();
|
||||
|
||||
if (!empty($data)) {
|
||||
$this->requestHelper->uploadOrders($data, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function runAmo()
|
||||
{
|
||||
if (!isset($this->container->amocrm)) {
|
||||
CommandHelper::activateNotice('amocrm');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$amo = new AmoRestApi(
|
||||
$this->container->amocrm['domain'],
|
||||
$this->container->amocrm['login'],
|
||||
$this->container->amocrm['key']
|
||||
);
|
||||
|
||||
$rule = new Rule();
|
||||
|
||||
$handler = $rule->getHandler('AmoHandler');
|
||||
$data = $handler->prepare($amo);
|
||||
|
||||
if (!empty($data)) {
|
||||
if (!empty($data['customers'])) {
|
||||
$this->requestHelper->uploadCustomers($data['customers']);
|
||||
if (!empty($data['orders'])) {
|
||||
$this->requestHelper->uploadOrders($data['orders'], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
retailcrm/src/Components/Container.php
Normal file
120
retailcrm/src/Components/Container.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
class Container
|
||||
{
|
||||
private static $_instanse = null;
|
||||
|
||||
private $settings;
|
||||
private $support;
|
||||
private $db;
|
||||
private $logdir;
|
||||
private $savedir;
|
||||
private $ruledir;
|
||||
private $date;
|
||||
private $file;
|
||||
private $api;
|
||||
private $icml;
|
||||
private $mail;
|
||||
private $ordersLog;
|
||||
private $historyLog;
|
||||
private $errorLog;
|
||||
private $logformat;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$this->file = pathinfo(__FILE__);
|
||||
|
||||
if (
|
||||
!file_exists(
|
||||
$this->file['dirname'] . '/../../data/config/settings.ini'
|
||||
)
|
||||
) {
|
||||
CommandHelper::settingsNotice();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$this->settings = parse_ini_file(
|
||||
$this->file['dirname'] . '/../../data/config/settings.ini', true
|
||||
);
|
||||
|
||||
$this->support = $this->settings['general']['support'];
|
||||
|
||||
if ($this->settings['db']['enabled']) {
|
||||
$driver = $this->settings['db']['driver'];
|
||||
|
||||
if ($driver == 'mysql') {
|
||||
$charset = ';charset=utf8';
|
||||
} else {
|
||||
$charset = '';
|
||||
}
|
||||
|
||||
try {
|
||||
$this->db = new PDO(
|
||||
$driver .
|
||||
':host=' .
|
||||
$this->settings['db']['host'] .
|
||||
';dbname='.$this->settings['db']['dbname'] . $charset,
|
||||
$this->settings['db']['user'],
|
||||
$this->settings['db']['password']
|
||||
);
|
||||
|
||||
$this->db->exec("set names utf8");
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
} catch (PDOException $e) {
|
||||
CommandHelper::activateNotice('database');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($this->settings['mail']['enabled']) {
|
||||
$this->mail = $this->settings['mail'];
|
||||
}
|
||||
|
||||
if ($this->settings['amocrm']['enabled']) {
|
||||
$this->amocrm = $this->settings['amocrm'];
|
||||
}
|
||||
|
||||
// Paths
|
||||
$this->logDir = $this->file['dirname'] . '/../../data/logs/';
|
||||
$this->saveDir = $this->file['dirname'] . '/../../data/upload/';
|
||||
$this->icml = $this->saveDir . $this->settings['general']['icml_file'];
|
||||
$this->bundle = $this->file['dirname'] . '/../../bundle/';
|
||||
|
||||
// ICML
|
||||
$this->shopName = $this->settings['general']['shop_name'];
|
||||
$this->shopUrl = $this->settings['general']['shop_url'];
|
||||
$this->domain = $this->settings['general']['domain'];
|
||||
$this->date = date('Y-m-d H:i:s');
|
||||
|
||||
// Logs
|
||||
$this->logformat = "[$this->date][$this->domain] ";
|
||||
$this->errorLog = $this->logDir . 'error/error.log';
|
||||
$this->mailLog = $this->logDir . 'mail/mail.log';
|
||||
|
||||
$this->ordersLog = $this->logDir . 'order/order.log';
|
||||
$this->ordersUpdatesLog = $this->logDir . 'order/update.log';
|
||||
$this->ordersHistoryLog = $this->logDir . 'order/history.log';
|
||||
|
||||
$this->customersLog = $this->logDir . 'customer/customer.log';
|
||||
$this->customersUpdatesLog = $this->logDir . 'customer/update.log';
|
||||
$this->customersHistoryLog = $this->logDir . 'customer/history.log';
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if (!isset($this->$name)) {
|
||||
throw new InvalidArgumentException("Property \"$name\" not found");
|
||||
}
|
||||
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
public static function getInstance() {
|
||||
if (null === self::$_instanse) {
|
||||
self::$_instanse = new self();
|
||||
}
|
||||
|
||||
return self::$_instanse;
|
||||
}
|
||||
}
|
111
retailcrm/src/Components/Logger.php
Normal file
111
retailcrm/src/Components/Logger.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
class Logger
|
||||
{
|
||||
private $rotate;
|
||||
private $push;
|
||||
private $files;
|
||||
|
||||
public function __construct($rotate = true, $push = true, $files = 5)
|
||||
{
|
||||
$this->rotate = $rotate;
|
||||
$this->push = $push;
|
||||
$this->files = $files;
|
||||
|
||||
$this->container = Container::getInstance();
|
||||
}
|
||||
|
||||
public function write($data, $file)
|
||||
{
|
||||
// message prefix with current time
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
$data = "[$timestamp]" . $data;
|
||||
|
||||
if(!file_exists($file)) {
|
||||
touch($file);
|
||||
}
|
||||
|
||||
// if filesize more than 5 Mb rotate it
|
||||
if ($this->rotate && filesize($file) > 5242880) {
|
||||
$this->rotate($file);
|
||||
}
|
||||
|
||||
error_log($data, 3, $file);
|
||||
|
||||
if ($this->push) {
|
||||
$this->push($data);
|
||||
}
|
||||
}
|
||||
|
||||
public function put($data, $file)
|
||||
{
|
||||
file_put_contents($file, $data);
|
||||
}
|
||||
|
||||
private function rotate($file)
|
||||
{
|
||||
$path = pathinfo($file);
|
||||
$rotate = implode('', array(
|
||||
$path['dirname'],
|
||||
'/',
|
||||
$path['filename'],
|
||||
date('YmdHis'),
|
||||
'.',
|
||||
$path['extension']
|
||||
));
|
||||
|
||||
copy($file, $rotate);
|
||||
$this->clean($file);
|
||||
|
||||
$files = glob($path['dirname'] . '/' . "*.log");
|
||||
|
||||
if (0 === $this->files) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count($files) > $this->files) {
|
||||
natsort($files);
|
||||
foreach (array_slice($files, $this->files) as $log) {
|
||||
if (is_writable($log)) {
|
||||
unlink($log);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function clean($file)
|
||||
{
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Push log message to external source (default: mail)
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $types
|
||||
*
|
||||
* @todo add mq, db, socket, http
|
||||
*/
|
||||
private function push($message, $type = 'mail')
|
||||
{
|
||||
$methodName = 'push' . ucfirst($type);
|
||||
|
||||
if (!method_exists($this, $methodName)) {
|
||||
throw new InvalidArgumentException("Method \"$methodName\" not found");
|
||||
} else {
|
||||
$this->$methodName($message);
|
||||
}
|
||||
}
|
||||
|
||||
private function pushMail($message)
|
||||
{
|
||||
$domain = $this->container->domain;
|
||||
$recipient = $this->container->support;
|
||||
$subject = 'Legacy notification';
|
||||
$headers = 'From: noreply@retailcrm.ru' . "\r\n" .
|
||||
'X-Mailer: PHP/' . phpversion();
|
||||
$message = "New log message from $domain:\n\n$message";
|
||||
|
||||
mail($recipient, $subject, $message, $headers);
|
||||
}
|
||||
}
|
76
retailcrm/src/Components/Mail.php
Normal file
76
retailcrm/src/Components/Mail.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
class Mail
|
||||
{
|
||||
|
||||
protected $mailBox;
|
||||
protected $mailSettings;
|
||||
|
||||
public function __construct($mailBox) {
|
||||
$this->container = Container::getInstance();
|
||||
$this->rule = new Rule();
|
||||
|
||||
$this->mailBox = $mailBox;
|
||||
|
||||
if (is_array($this->container->mail)) {
|
||||
if(isset($this->container->mail[$mailBox])) {
|
||||
$this->mailSettings = explode(
|
||||
',',
|
||||
$this->container->mail[$mailBox]
|
||||
);
|
||||
} else {
|
||||
CommandHelper::settingsFailure($mailBox);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
CommandHelper::activateNotice('mail');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function parse()
|
||||
{
|
||||
$server = new Server(
|
||||
$this->mailSettings[2],
|
||||
$this->mailSettings[3],
|
||||
$this->mailSettings[4]
|
||||
);
|
||||
|
||||
$server->setAuthentication(
|
||||
$this->mailSettings[0],
|
||||
$this->mailSettings[1]
|
||||
);
|
||||
|
||||
$mailCriteria = $this->clean($this->mailBox, 'criteria');
|
||||
$mailHandler = $this->clean($this->mailBox, 'handler');
|
||||
|
||||
$criteria = $this->rule->getCriteria($mailCriteria);
|
||||
$handler = $this->rule->getHandler($mailHandler);
|
||||
error_reporting(E_ERROR | E_PARSE);
|
||||
$messages = $server->search($criteria);
|
||||
|
||||
return $handler->prepare($messages);
|
||||
}
|
||||
|
||||
private function clean($mail, $type) {
|
||||
if ($type == 'criteria') {
|
||||
$string = preg_replace('/[\@\.\,\-]/', '_', $mail);
|
||||
return strtolower($string);
|
||||
}
|
||||
|
||||
if ($type == 'handler') {
|
||||
$string = preg_replace('/[\@\.\,\-]/', '_', $mail);
|
||||
$string = explode('_', $string);
|
||||
$string = array_map("ucfirst", $string);
|
||||
$string = implode('', $string);
|
||||
|
||||
if (is_int(substr($string, 0, 1))) {
|
||||
$string = 'Numbered' . $string;
|
||||
}
|
||||
|
||||
return $string . 'Handler';
|
||||
}
|
||||
}
|
||||
}
|
52
retailcrm/src/Components/RequestProxy.php
Normal file
52
retailcrm/src/Components/RequestProxy.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
class RequestProxy
|
||||
{
|
||||
private $api;
|
||||
private $logger;
|
||||
private $container;
|
||||
|
||||
public function __construct($url, $key)
|
||||
{
|
||||
$this->api = new ApiClient($url,$key);
|
||||
$this->logger = new Logger();
|
||||
$this->container = Container::getInstance();
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
try {
|
||||
$response = call_user_func_array(array($this->api, $method), $arguments);
|
||||
|
||||
if ($response->isSuccessful()) {
|
||||
return $response;
|
||||
} else {
|
||||
$this->logger->write(
|
||||
"[$method] " . $response->getErrorMsg() . "\n",
|
||||
$this->container->errorLog
|
||||
);
|
||||
|
||||
if (isset($response['errors'])) {
|
||||
foreach ($response['errors'] as $error) {
|
||||
$this->logger->write(
|
||||
"[$method] $error \n",
|
||||
$this->container->errorLog
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} catch (CurlException $e) {
|
||||
$this->logger->write(
|
||||
"[$method] " . $e->getMessage() . "\n",
|
||||
$this->container->errorLog
|
||||
);
|
||||
} catch (InvalidJsonException $e) {
|
||||
$this->logger->write(
|
||||
"[$method] " . $e->getMessage() . "\n",
|
||||
$this->container->errorLog
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
54
retailcrm/src/Components/Rule.php
Normal file
54
retailcrm/src/Components/Rule.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
class Rule
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->container = Container::getInstance();
|
||||
}
|
||||
|
||||
public function getSQL($sqlFile)
|
||||
{
|
||||
$file = $this->container->bundle . 'sql/' . $sqlFile . '.sql';
|
||||
|
||||
if (!file_exists($file)) {
|
||||
CommandHelper::implementationNotice($sqlFile, '.sql file');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return file_get_contents($file);
|
||||
}
|
||||
|
||||
public function getCriteria($criteriaFile)
|
||||
{
|
||||
$file = $this->container->bundle . 'mail/' . $criteriaFile . '.txt';
|
||||
|
||||
if (!file_exists($file)) {
|
||||
CommandHelper::implementationNotice($criteriaFile, '.txt file');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$criteria = file_get_contents($file);
|
||||
return trim($criteria);
|
||||
}
|
||||
|
||||
public function getHandler($handlerClass)
|
||||
{
|
||||
|
||||
if (!class_exists($handlerClass)) {
|
||||
CommandHelper::implementationNotice($handlerClass, ' class');
|
||||
exit(1);
|
||||
} else {
|
||||
$handler = new $handlerClass;
|
||||
}
|
||||
|
||||
if (!in_array('HandlerInterface', class_implements($handler))) {
|
||||
CommandHelper::implementationError($handlerClass, 'HandlerInterface');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
}
|
264
retailcrm/src/Helpers/ApiHelper.php
Normal file
264
retailcrm/src/Helpers/ApiHelper.php
Normal file
@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
class ApiHelper
|
||||
{
|
||||
|
||||
private $api;
|
||||
private $logger;
|
||||
private $container;
|
||||
|
||||
public function __construct($api)
|
||||
{
|
||||
$this->api = $api;
|
||||
$this->logger = new Logger();
|
||||
$this->container = Container::getInstance();
|
||||
}
|
||||
|
||||
public function uploadOrders($orders, $check = true)
|
||||
{
|
||||
$timemark = date('Y-m-d H:i:s');
|
||||
|
||||
if ($check) {
|
||||
$orders = $this->prepareOrders($orders);
|
||||
}
|
||||
|
||||
$splitOrders = array_chunk($orders, 50);
|
||||
|
||||
foreach ($splitOrders as $orders) {
|
||||
$this->api->ordersUpload($orders);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
|
||||
$this->logger->put($timemark, $this->container->ordersLog);
|
||||
}
|
||||
|
||||
public function updateOrders($orders)
|
||||
{
|
||||
$timemark = date('Y-m-d H:i:s');
|
||||
foreach ($orders as $order) {
|
||||
$this->api->ordersEdit($order);
|
||||
echo "\033[0;36m" . $order['externalId'] . " updated\e[0m\n";
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
|
||||
$this->logger->put($timemark, $this->container->ordersUpdatesLog);
|
||||
}
|
||||
|
||||
public function ordersHistory()
|
||||
{
|
||||
$response = $this->api->ordersHistory(
|
||||
new DateTime(
|
||||
DataHelper::getDate($this->container->ordersHistoryLog)
|
||||
)
|
||||
);
|
||||
|
||||
if (!is_null($response)) {
|
||||
$this->logger->put(
|
||||
$response->getGeneratedAt(),
|
||||
$this->container->ordersHistoryLog
|
||||
);
|
||||
return $response['orders'];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadCustomers($customers)
|
||||
{
|
||||
$timemark = date('Y-m-d H:i:s');
|
||||
$splitCustomers = array_chunk($customers, 50);
|
||||
|
||||
foreach ($splitCustomers as $customers) {
|
||||
$this->api->customersUpload($customers);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
|
||||
$this->logger->put($timemark, $this->container->customersLog);
|
||||
}
|
||||
|
||||
public function updateCustomers($customers)
|
||||
{
|
||||
$timemark = date('Y-m-d H:i:s');
|
||||
foreach ($customers as $customer) {
|
||||
$this->api->ordersEdit($customer);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
|
||||
$this->logger->put($timemark, $this->container->customersUpdateLog);
|
||||
}
|
||||
|
||||
// For future
|
||||
public function customersHistory()
|
||||
{
|
||||
$response = $this->api->customersHistory(
|
||||
new DateTime(
|
||||
DataHelper::getDate($this->container->customersHistoryLog)
|
||||
)
|
||||
);
|
||||
|
||||
if (!is_null($response)) {
|
||||
$this->logger(
|
||||
$response->getGeneratedAt(),
|
||||
$this->container->customersHistoryLog
|
||||
);
|
||||
return $response['customers'];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
private function prepareOrders($orders)
|
||||
{
|
||||
foreach ($orders as $idx => $order) {
|
||||
|
||||
$customer = array();
|
||||
|
||||
$customer['externalId'] = $order['customerId'];
|
||||
|
||||
if (isset($order['firstName'])) {
|
||||
$customer['firstName'] = $order['firstName'];
|
||||
}
|
||||
|
||||
if (isset($order['lastName'])) {
|
||||
$customer['lastName'] = $order['lastName'];
|
||||
}
|
||||
|
||||
if (isset($order['patronymic'])) {
|
||||
$customer['patronymic'] = $order['patronymic'];
|
||||
}
|
||||
|
||||
if (!empty($order['delivery']['address'])) {
|
||||
$customer['address'] = $order['delivery']['address'];
|
||||
}
|
||||
|
||||
if (isset($order['phone'])) {
|
||||
$customer['phones'][]['number'] = $order['phone'];
|
||||
}
|
||||
|
||||
if (isset($order['email'])) {
|
||||
$customer['email'] = $order['email'];
|
||||
}
|
||||
|
||||
$checkResult = $this->checkCustomers($customer);
|
||||
|
||||
if ($checkResult === false) {
|
||||
unset($orders[$idx]["customerId"]);
|
||||
} else {
|
||||
$orders[$idx]["customerId"] = $checkResult;
|
||||
}
|
||||
}
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
private function checkCustomers($customer)
|
||||
{
|
||||
|
||||
$criteria = array(
|
||||
'name' => (isset($customer['phones'][0]['number'])) ? $customer['phones'][0]['number'] : $customer['lastName'],
|
||||
'email' => (isset($customer['email'])) ? $customer['email'] : ''
|
||||
);
|
||||
|
||||
$search = $this->api->customersList($criteria);
|
||||
|
||||
if (!is_null($search)) {
|
||||
if(empty($search['customers'])) {
|
||||
if(!is_null($this->api->customersEdit($customer))) {
|
||||
return $customer["externalId"];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$_externalId = null;
|
||||
|
||||
foreach ($search['customers'] as $_customer) {
|
||||
if (!empty($_customer['externalId'])) {
|
||||
$_externalId = $_customer['externalId'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($_externalId)) {
|
||||
$customerFix = array(
|
||||
'id' => $search['customers'][0]['id'],
|
||||
'externalId' => $customer['externalId']
|
||||
);
|
||||
$response = $this->api->customersFixExternalIds(
|
||||
array($customerFix)
|
||||
);
|
||||
$_externalId = $customer['externalId'];
|
||||
};
|
||||
|
||||
return $_externalId;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export deliveries
|
||||
*
|
||||
* @param array $deliveries
|
||||
*/
|
||||
public function uploadDeliveryTypes($deliveryTypes)
|
||||
{
|
||||
foreach ($deliveryTypes as $type) {
|
||||
$this->api->deliveryTypesEdit($type);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export deliveries
|
||||
*
|
||||
* @param array $deliveries
|
||||
*/
|
||||
public function uploadDeliveryServices($deliveryServices)
|
||||
{
|
||||
foreach ($deliveryServices as $service) {
|
||||
$this->api->deliveryServicesEdit($service);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export payments
|
||||
*
|
||||
* @param array $payments
|
||||
*/
|
||||
public function uploadPaymentTypes($payments)
|
||||
{
|
||||
foreach ($payments as $payment) {
|
||||
$this->api->paymentTypesEdit($payment);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export payment statuses
|
||||
*
|
||||
* @param array $paymentStatuses
|
||||
*/
|
||||
public function uploadPaymentStatuses($paymentStatuses)
|
||||
{
|
||||
foreach ($paymentStatuses as $status) {
|
||||
$this->api->paymentStatusesEdit($status);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export statuses
|
||||
*
|
||||
* @param unknown_type $statuses
|
||||
*/
|
||||
public function uploadStatuses($statuses)
|
||||
{
|
||||
foreach ($statuses as $status) {
|
||||
$this->api->statusesEdit($status);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
76
retailcrm/src/Helpers/CommandHelper.php
Normal file
76
retailcrm/src/Helpers/CommandHelper.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
class CommandHelper
|
||||
{
|
||||
public static function runHelp()
|
||||
{
|
||||
echo "\n\033[35;2;18mUsage:\033[0m\n";
|
||||
echo " /usr/bin/php [-i /etc/php5/cli/php.ini] -f app.php -e command [-l] [-u] [-p ids] [-r reference] [-h history] [-m mail@example.com]\n";
|
||||
echo "\n\033[35;2;18mCommands:\033[0m\n";
|
||||
echo " icml\t\tGenerate icml export file\n";
|
||||
echo " history\tGet data from crm\n";
|
||||
echo " orders\tExport orders to crm\n";
|
||||
echo " customers\tExport customers to crm\n";
|
||||
echo " references\tExport references to crm\n";
|
||||
echo " mail\t\tExport orders from mailbox\n";
|
||||
echo " amo\t\tExport customers & orders from amoCRM\n";
|
||||
echo " dump\t\tCreate mysql dump\n";
|
||||
echo "\n\033[35;2;18mArguments:\033[0m\n";
|
||||
echo " -l\t\tExport orders or customers created from last run\n";
|
||||
echo " -u\t\tExport orders or customers updated from last run\n";
|
||||
echo " -c\t\tCustom export for orders or customers\n";
|
||||
echo " -m\t\tMail address (for mail command)\n";
|
||||
echo " -p\t\tPass set of ids or single id for export customer or order by this ids\n";
|
||||
echo " -r\t\tExport references, if type is set only this reference will be exported\n";
|
||||
echo " -h\t\tHistory type, if type is set only this history will be recieved\n";
|
||||
}
|
||||
|
||||
public static function updateNotice()
|
||||
{
|
||||
echo "\033[0;31mFull update is not allowed, please select one of the following flags: limit, set of identifiers or a specific id\033[0m\n";
|
||||
}
|
||||
|
||||
public static function implementationNotice($name, $type)
|
||||
{
|
||||
echo "\033[0;36mThis function is not implemented. You need to create $name$type\033[0m\n";
|
||||
}
|
||||
|
||||
public static function implementationError($name, $iface)
|
||||
{
|
||||
echo "\033[0;31m$name class must implement $iface\033[0m\n";
|
||||
}
|
||||
|
||||
public static function settingsNotice()
|
||||
{
|
||||
echo "\033[0;31msettings.ini doesn't exist\033[0m\n";
|
||||
}
|
||||
|
||||
public static function activateNotice($param)
|
||||
{
|
||||
echo "\033[0;31mActivate \"$param\" section in settings.ini or check your connection settings\033[0m\n";
|
||||
}
|
||||
|
||||
public static function paramNotice($param)
|
||||
{
|
||||
echo "\033[0;31mParameter \"$param\" is mandatory\033[0m\n";
|
||||
}
|
||||
|
||||
public static function settingsFailure($param)
|
||||
{
|
||||
echo "\033[0;31mKey \"$param\" doesn't not exist in settings.ini\033[0m\n";
|
||||
}
|
||||
|
||||
public static function refHelp($ref)
|
||||
{
|
||||
switch($ref) {
|
||||
case 'references':
|
||||
echo "\033[0;36mAvailable values: delivery-types, delivery-services, payment-types, payment-statuses, statuses\033[0m\n";
|
||||
break;
|
||||
case 'history':
|
||||
echo "\033[0;36mAvailable values: orders, customers\033[0m\n";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
79
retailcrm/src/Helpers/DataHelper.php
Normal file
79
retailcrm/src/Helpers/DataHelper.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
class DataHelper
|
||||
{
|
||||
public static function getDate($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
$result = file_get_contents($file);
|
||||
} else {
|
||||
$result = date(
|
||||
'Y-m-d H:i:s',
|
||||
strtotime('-1 days', strtotime(date('Y-m-d H:i:s')))
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function filterRecursive($haystack)
|
||||
{
|
||||
foreach ($haystack as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$haystack[$key] = self::filterRecursive($haystack[$key]);
|
||||
}
|
||||
|
||||
if (is_null($haystack[$key]) || $haystack[$key] === '' || count($haystack[$key]) == 0) {
|
||||
unset($haystack[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $haystack;
|
||||
}
|
||||
|
||||
public static function explodeFIO($string)
|
||||
{
|
||||
$result = array();
|
||||
$parse = (!$string) ? false : explode(" ", $string, 3);
|
||||
|
||||
switch (count($parse)) {
|
||||
case 1:
|
||||
$result['firstName'] = $parse[0];
|
||||
$result['lastName'] = '';
|
||||
$result['patronymic'] = '';
|
||||
break;
|
||||
case 2:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
$result['patronymic'] = '';
|
||||
break;
|
||||
case 3:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
$result['patronymic'] = $parse[2];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function explodeUids($uids)
|
||||
{
|
||||
$uids = explode(',', $uids);
|
||||
$ranges = array();
|
||||
|
||||
foreach ($uids as $idx => $uid) {
|
||||
if (strpos($uid, '-')) {
|
||||
$range = explode('-', $uid);
|
||||
$ranges = array_merge($ranges, range($range[0], $range[1]));
|
||||
unset($uids[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
$uids = implode(',', array_merge($uids, $ranges));
|
||||
|
||||
return $uids;
|
||||
}
|
||||
}
|
137
retailcrm/src/Helpers/IcmlHelper.php
Normal file
137
retailcrm/src/Helpers/IcmlHelper.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
class IcmlHelper
|
||||
{
|
||||
protected $shop;
|
||||
protected $file;
|
||||
|
||||
protected $properties;
|
||||
protected $params;
|
||||
|
||||
protected $document;
|
||||
protected $categories;
|
||||
protected $offers;
|
||||
|
||||
public function __construct($shop, $file)
|
||||
{
|
||||
$this->shop = $shop;
|
||||
$this->file = $file;
|
||||
|
||||
$this->properties = array(
|
||||
'name',
|
||||
'productName',
|
||||
'price',
|
||||
'purchasePrice',
|
||||
'vendor',
|
||||
'picture',
|
||||
'url',
|
||||
'xmlId',
|
||||
'productActivity'
|
||||
);
|
||||
|
||||
$this->params = array(
|
||||
'article' => 'Артикул',
|
||||
'color' => 'Цвет',
|
||||
'weight' => 'Вес',
|
||||
'size' => 'Размер',
|
||||
);
|
||||
}
|
||||
|
||||
public function generate($categories, $offers)
|
||||
{
|
||||
$string = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<yml_catalog date="'.date('Y-m-d H:i:s').'">
|
||||
<shop>
|
||||
<name>'.$this->shop.'</name>
|
||||
<categories/>
|
||||
<offers/>
|
||||
</shop>
|
||||
</yml_catalog>
|
||||
';
|
||||
|
||||
$xml = new SimpleXMLElement(
|
||||
$string,
|
||||
LIBXML_NOENT |LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE
|
||||
);
|
||||
|
||||
$this->document = new DOMDocument();
|
||||
$this->document->preserveWhiteSpace = false;
|
||||
$this->document->formatOutput = true;
|
||||
$this->document->loadXML($xml->asXML());
|
||||
|
||||
$this->categories = $this->document
|
||||
->getElementsByTagName('categories')->item(0);
|
||||
$this->offers = $this->document
|
||||
->getElementsByTagName('offers')->item(0);
|
||||
|
||||
$this->addCategories($categories);
|
||||
$this->addOffers($offers);
|
||||
|
||||
$this->document->saveXML();
|
||||
$this->document->save($this->file);
|
||||
}
|
||||
|
||||
private function addCategories($categories)
|
||||
{
|
||||
foreach($categories as $category) {
|
||||
$e = $this->categories->appendChild(
|
||||
$this->document->createElement(
|
||||
'category', $category['name']
|
||||
)
|
||||
);
|
||||
|
||||
$e->setAttribute('id', $category['id']);
|
||||
|
||||
if ($category['parentId'] > 0) {
|
||||
$e->setAttribute('parentId', $category['parentId']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addOffers($offers)
|
||||
{
|
||||
foreach ($offers as $offer) {
|
||||
|
||||
$e = $this->offers->appendChild(
|
||||
$this->document->createElement('offer')
|
||||
);
|
||||
|
||||
$e->setAttribute('id', $offer['id']);
|
||||
$e->setAttribute('productId', $offer['productId']);
|
||||
|
||||
if (!empty($offer['quantity'])) {
|
||||
$e->setAttribute('quantity', (int) $offer['quantity']);
|
||||
} else {
|
||||
$e->setAttribute('quantity', 0);
|
||||
}
|
||||
|
||||
foreach ($offer['categoryId'] as $categoryId) {
|
||||
$e->appendChild(
|
||||
$this->document->createElement('categoryId', $categoryId)
|
||||
);
|
||||
}
|
||||
|
||||
$offerKeys = array_keys($offer);
|
||||
|
||||
foreach ($offerKeys as $key) {
|
||||
if (in_array($key, $this->properties)) {
|
||||
$e->appendChild(
|
||||
$this->document->createElement($key)
|
||||
)->appendChild(
|
||||
$this->document->createTextNode($offer[$key])
|
||||
);
|
||||
}
|
||||
|
||||
if (in_array($key, array_keys($this->params))) {
|
||||
$param = $this->document->createElement('param');
|
||||
$param->setAttribute('code', $key);
|
||||
$param->setAttribute('name', $this->params[$key]);
|
||||
$param->appendChild(
|
||||
$this->document->createTextNode($offer[$key])
|
||||
);
|
||||
$e->appendChild($param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6
retailcrm/src/Interfaces/HandlerInterface.php
Normal file
6
retailcrm/src/Interfaces/HandlerInterface.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
interface HandlerInterface
|
||||
{
|
||||
public function prepare($data);
|
||||
}
|
765
retailcrm/src/Vendor/AmoCrm/AmoRestApi.php
vendored
Normal file
765
retailcrm/src/Vendor/AmoCrm/AmoRestApi.php
vendored
Normal file
@ -0,0 +1,765 @@
|
||||
<?php
|
||||
/**
|
||||
* AmoRestApi
|
||||
*
|
||||
* Copyright (c) 2015, Dmitry Mamontov <d.slonyara@gmail.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Dmitry Mamontov nor the names of his
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package amo-restapi
|
||||
* @author Dmitry Mamontov <d.slonyara@gmail.com>
|
||||
* @copyright 2015 Dmitry Mamontov <d.slonyara@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
|
||||
* @since File available since Release 1.0.0
|
||||
*/
|
||||
/**
|
||||
* AmoRestApi - The main class
|
||||
*
|
||||
* @author Dmitry Mamontov <d.slonyara@gmail.com>
|
||||
* @copyright 2015 Dmitry Mamontov <d.slonyara@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
|
||||
* @version Release: 1.0.2
|
||||
* @link https://github.com/dmamontov/amo-restapi/
|
||||
* @since Class available since Release 1.0.2
|
||||
*/
|
||||
|
||||
class AmoRestApi
|
||||
{
|
||||
/*
|
||||
* URL fro RestAPI
|
||||
*/
|
||||
const URL = 'https://%s.amocrm.ru/private/api/v2/json/';
|
||||
|
||||
/*
|
||||
* Auth URL fro RestAPI
|
||||
*/
|
||||
const AUTH_URL = 'https://%s.amocrm.ru/private/api/';
|
||||
|
||||
/*
|
||||
* Methods
|
||||
*/
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
|
||||
/**
|
||||
* Login access to API
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $login;
|
||||
|
||||
/**
|
||||
* Hash
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* Sub domain
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $subDomain;
|
||||
|
||||
/**
|
||||
* Curl instance
|
||||
*/
|
||||
protected $curl;
|
||||
|
||||
/**
|
||||
* Current account info
|
||||
*/
|
||||
protected $accountInfo;
|
||||
|
||||
/**
|
||||
* Accounts custom fields
|
||||
*/
|
||||
protected $customFields;
|
||||
|
||||
/**
|
||||
* Accounts leads statues info
|
||||
*/
|
||||
protected $leadsStatuses;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @param string $subDomain
|
||||
* @param string $login
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function __construct($subDomain, $login, $key)
|
||||
{
|
||||
$this->subDomain = $subDomain;
|
||||
$this->login = $login;
|
||||
$this->key = $key;
|
||||
|
||||
$auth = $this->curlRequest(
|
||||
sprintf(self::AUTH_URL . 'auth.php?type=json', $subDomain),
|
||||
self::METHOD_POST,
|
||||
array('USER_LOGIN' => $login, 'USER_HASH' => $key)
|
||||
);
|
||||
|
||||
if ($auth['auth'] !== true) {
|
||||
throw new Exception('Authorization error.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Account Info
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getAccountInfo()
|
||||
{
|
||||
if ($this->accountInfo) {
|
||||
return $this->accountInfo;
|
||||
}
|
||||
|
||||
$request = $this->curlRequest(sprintf(self::URL . 'accounts/current', $this->subDomain));
|
||||
|
||||
if (is_array($request) && isset($request['account'])) {
|
||||
$this->accountInfo = $request['account'];
|
||||
return $this->accountInfo;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Contacts
|
||||
* @param array $contacts
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setContacts($contacts = null)
|
||||
{
|
||||
if (is_null($contacts)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Prepare request
|
||||
$request['request']['contacts'] = $contacts;
|
||||
$requestJson = json_encode($request);
|
||||
|
||||
$headers = array('Content-Type: application/json');
|
||||
|
||||
return $this->curlRequest(sprintf(self::URL . 'contacts/set', $this->subDomain), self::METHOD_POST, $requestJson, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Contacts List
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param string $query
|
||||
* @param string $responsible
|
||||
* @param string $type
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getContactsList(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
$query = null,
|
||||
$responsible = null,
|
||||
$type = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['id'] = $ids;
|
||||
}
|
||||
|
||||
if (is_null($query) === false) {
|
||||
$parameters['query'] = $query;
|
||||
}
|
||||
|
||||
if (is_null($responsible) === false) {
|
||||
$parameters['responsible_user_id'] = $responsible;
|
||||
}
|
||||
|
||||
if (is_null($type) === false) {
|
||||
$parameters['type'] = $type;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'contacts/list', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Contacts Links
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getContactsLinks(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['contacts_link'] = $ids;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'contacts/links', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Leads
|
||||
* @param array $leads
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setLeads($leads = null)
|
||||
{
|
||||
if (is_null($leads)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Prepare request
|
||||
$request['request']['leads'] = $leads;
|
||||
$requestJson = json_encode($request);
|
||||
$headers = array('Content-Type: application/json');
|
||||
|
||||
//Do request
|
||||
$response = $this->curlRequest(sprintf(self::URL . 'leads/set', $this->subDomain), self::METHOD_POST, $requestJson, $headers);
|
||||
|
||||
//Parse leads ids from response and return along with last modified time
|
||||
if (isset($response['leads']['add']) && is_array($response['leads']['add'])) {
|
||||
$added_leads = array();
|
||||
foreach ($response['leads']['add'] as $key => $lead_info) {
|
||||
$added_leads[ $key ]['id'] = $lead_info['id'];
|
||||
$added_leads[ $key ]['last_modified'] = $response['server_time'];
|
||||
}
|
||||
|
||||
return $added_leads;
|
||||
} elseif (isset($response['leads']['update'])) {
|
||||
return $response;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Leads List
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param string $query
|
||||
* @param string $responsible
|
||||
* @param mixed $status
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getLeadsList(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
$query = null,
|
||||
$responsible = null,
|
||||
$status = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['id'] = $ids;
|
||||
}
|
||||
|
||||
if (is_null($query) === false) {
|
||||
$parameters['query'] = $query;
|
||||
}
|
||||
|
||||
if (is_null($responsible) === false) {
|
||||
$parameters['responsible_user_id'] = $responsible;
|
||||
}
|
||||
|
||||
if (is_null($status) === false) {
|
||||
$parameters['status'] = $status;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'leads/list', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Company
|
||||
* @param array $company
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setCompany($company = null)
|
||||
{
|
||||
if (is_null($company)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->curlRequest(sprintf(self::URL . 'company/list', $this->subDomain), self::METHOD_POST, $company);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Company List
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param string $query
|
||||
* @param string $responsible
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getCompanyList(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
$query = null,
|
||||
$responsible = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['id'] = $ids;
|
||||
}
|
||||
|
||||
if (is_null($query) === false) {
|
||||
$parameters['query'] = $query;
|
||||
}
|
||||
|
||||
if (is_null($responsible) === false) {
|
||||
$parameters['responsible_user_id'] = $responsible;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'company/list', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Tasks
|
||||
* @param array $tasks
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setTasks($tasks = null)
|
||||
{
|
||||
if (is_null($tasks)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Prepare request
|
||||
$request['request']['tasks'] = $tasks;
|
||||
$requestJson = json_encode($request);
|
||||
$headers = array('Content-Type: application/json');
|
||||
return $this->curlRequest(sprintf(self::URL . 'tasks/set', $this->subDomain), self::METHOD_POST, $requestJson, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tasks List
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param string $query
|
||||
* @param string $responsible
|
||||
* @param string $type
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getTasksList(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
$query = null,
|
||||
$responsible = null,
|
||||
$type = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['id'] = $ids;
|
||||
}
|
||||
|
||||
if (is_null($query) === false) {
|
||||
$parameters['query'] = $query;
|
||||
}
|
||||
|
||||
if (is_null($responsible) === false) {
|
||||
$parameters['responsible_user_id'] = $responsible;
|
||||
}
|
||||
|
||||
if (is_null($type) === false) {
|
||||
$parameters['type'] = $type;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'tasks/list', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Notes
|
||||
* @param array $notes
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setNotes($notes = null)
|
||||
{
|
||||
if (is_null($notes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->curlRequest(sprintf(self::URL . 'notes/set', $this->subDomain), self::METHOD_POST, $notes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Notes List
|
||||
* @param int $limitRows
|
||||
* @param int $limitOffset
|
||||
* @param mixed $ids
|
||||
* @param string $element_id
|
||||
* @param string $type
|
||||
* @param DateTime $dateModified
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function getNotesList(
|
||||
$limitRows = null,
|
||||
$limitOffset = null,
|
||||
$ids = null,
|
||||
$element_id = null,
|
||||
$type = null,
|
||||
DateTime $dateModified = null
|
||||
) {
|
||||
$headers = null;
|
||||
if (is_null($dateModified) === false) {
|
||||
$headers = array('if-modified-since: ' . $dateModified->format('D, d M Y H:i:s'));
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_rows'] = $limitRows;
|
||||
if (is_null($limitRows) === false) {
|
||||
$parameters['limit_offset'] = $limitOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($ids) === false) {
|
||||
$parameters['id'] = $ids;
|
||||
}
|
||||
|
||||
if (is_null($responsible) === false) {
|
||||
$parameters['responsible_user_id'] = $responsible;
|
||||
}
|
||||
|
||||
if (is_null($element_id) === false) {
|
||||
$parameters['element_id'] = $element_id;
|
||||
}
|
||||
|
||||
if (is_null($type) === false) {
|
||||
$parameters['type'] = $type;
|
||||
}
|
||||
|
||||
return $this->curlRequest(
|
||||
sprintf(self::URL . 'notes/list', $this->subDomain),
|
||||
self::METHOD_GET,
|
||||
count($parameters) > 0 ? http_build_query($parameters) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Fields
|
||||
* @param array $fields
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function setFields($fields = null)
|
||||
{
|
||||
if (is_null($fields)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->curlRequest(sprintf(self::URL . 'fields/set', $this->subDomain), self::METHOD_POST, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution of the request
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param integer $timeout
|
||||
* @return mixed
|
||||
* @access protected
|
||||
*/
|
||||
protected function curlRequest($url, $method = 'GET', $parameters = null, $headers = null, $cookie = '/tmp/cookie.txt', $timeout = 30)
|
||||
{
|
||||
if ($method == self::METHOD_GET && is_null($parameters) == false) {
|
||||
$url .= "?$parameters";
|
||||
}
|
||||
|
||||
// Get curl handler or initiate it
|
||||
if (!$this->curl) {
|
||||
$this->curl = curl_init();
|
||||
}
|
||||
|
||||
//Set general arguments
|
||||
curl_setopt($this->curl, CURLOPT_USERAGENT, 'amoCRM-API-client/1.0');
|
||||
curl_setopt($this->curl, CURLOPT_URL, $url);
|
||||
curl_setopt($this->curl, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($this->curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($this->curl, CURLOPT_COOKIEFILE, $cookie);
|
||||
curl_setopt($this->curl, CURLOPT_COOKIEJAR, $cookie);
|
||||
|
||||
// Reset some arguments, in order to avoid use some from previous request
|
||||
curl_setopt($this->curl, CURLOPT_POST, false);
|
||||
|
||||
if (is_null($headers) === false && count($headers) > 0) {
|
||||
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
|
||||
} else {
|
||||
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array());
|
||||
}
|
||||
|
||||
if ($method == self::METHOD_POST && is_null($parameters) === false) {
|
||||
curl_setopt($this->curl, CURLOPT_POST, true);
|
||||
|
||||
//Encode parameters if them already not encoded in json
|
||||
if ($this->isJson($parameters) == false) {
|
||||
$parameters = http_build_query($parameters);
|
||||
}
|
||||
|
||||
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $parameters);
|
||||
}
|
||||
|
||||
$response = curl_exec($this->curl);
|
||||
$statusCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
$errno = curl_errno($this->curl);
|
||||
$error = curl_error($this->curl);
|
||||
|
||||
if ($errno) {
|
||||
throw new Exception($error, $errno);
|
||||
}
|
||||
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if ($statusCode >= 400) {
|
||||
throw new Exception($result['message'], $statusCode);
|
||||
}
|
||||
|
||||
return isset($result['response']) && count($result['response']) == 0 ? true : $result['response'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if passed argument is JSON
|
||||
* @param $string
|
||||
* @return bool
|
||||
*/
|
||||
protected function isJson($string)
|
||||
{
|
||||
if (is_string($string) == false) {
|
||||
return false;
|
||||
}
|
||||
json_decode($string);
|
||||
return (json_last_error() == JSON_ERROR_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accounts custom fields and store in self::customFields
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getCustomFields()
|
||||
{
|
||||
if ($this->customFields) {
|
||||
return $this->customFields;
|
||||
}
|
||||
|
||||
$account = $this->getAccountInfo();
|
||||
$this->customFields = $account['custom_fields'];
|
||||
|
||||
return $this->customFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting custom fields id
|
||||
* @param $fieldName
|
||||
* @param string $fieldSection (possible values contacts or companies)
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCustomFieldID($fieldName, $fieldSection = 'contacts')
|
||||
{
|
||||
$customFields = $this->getCustomFields();
|
||||
if (is_array($customFields) && isset($customFields[$fieldSection]) && is_array($customFields[$fieldSection])) {
|
||||
foreach ($customFields[$fieldSection] as $customFieldDetails) {
|
||||
if ($fieldName === $customFieldDetails['code']) {
|
||||
return $customFieldDetails['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of possible leads statuses
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLeadsStatuses()
|
||||
{
|
||||
if ($this->leadsStatuses) {
|
||||
return $this->leadsStatuses;
|
||||
}
|
||||
|
||||
$account = $this->getAccountInfo();
|
||||
$this->leadsStatuses = $account['leads_statuses'];
|
||||
|
||||
return $this->leadsStatuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lead status id by name
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLeadStatusID($name)
|
||||
{
|
||||
$leadsStatuses = $this->getLeadsStatuses();
|
||||
if (is_array($leadsStatuses)) {
|
||||
foreach ($leadsStatuses as $leadsStatus) {
|
||||
if ($name === $leadsStatus['name']) {
|
||||
return $leadsStatus['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do some actions when instance destroyed
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
//Close curl session
|
||||
curl_close($this->curl);
|
||||
}
|
||||
}
|
212
retailcrm/src/Vendor/Fetch/Attachment.php
vendored
Normal file
212
retailcrm/src/Vendor/Fetch/Attachment.php
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
class Attachment
|
||||
{
|
||||
|
||||
/**
|
||||
* This is the structure object for the piece of the message body that the attachment is located it.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $structure;
|
||||
|
||||
/**
|
||||
* This is the unique identifier for the message this attachment belongs to.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $messageId;
|
||||
|
||||
/**
|
||||
* This is the ImapResource.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $imapStream;
|
||||
|
||||
/**
|
||||
* This is the id pointing to the section of the message body that contains the attachment.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $partId;
|
||||
|
||||
/**
|
||||
* This is the attachments filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* This is the size of the attachment.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* This stores the data of the attachment so it doesn't have to be retrieved from the server multiple times. It is
|
||||
* only populated if the getData() function is called and should not be directly used.
|
||||
*
|
||||
* @internal
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* This function takes in an ImapMessage, the structure object for the particular piece of the message body that the
|
||||
* attachment is located at, and the identifier for that body part. As a general rule you should not be creating
|
||||
* instances of this yourself, but rather should get them from an ImapMessage class.
|
||||
*
|
||||
* @param Message $message
|
||||
* @param stdClass $structure
|
||||
* @param string $partIdentifier
|
||||
*/
|
||||
public function __construct(Message $message, $structure, $partIdentifier = null)
|
||||
{
|
||||
$this->messageId = $message->getUid();
|
||||
$this->imapStream = $message->getImapBox()->getImapStream();
|
||||
$this->structure = $structure;
|
||||
|
||||
if (isset($partIdentifier))
|
||||
$this->partId = $partIdentifier;
|
||||
|
||||
$parameters = Message::getParametersFromStructure($structure);
|
||||
|
||||
if (isset($parameters['filename'])) {
|
||||
$this->filename = $parameters['filename'];
|
||||
} elseif (isset($parameters['name'])) {
|
||||
$this->filename = $parameters['name'];
|
||||
}
|
||||
|
||||
$this->size = $structure->bytes;
|
||||
|
||||
$this->mimeType = Message::typeIdToString($structure->type);
|
||||
|
||||
if (isset($structure->subtype))
|
||||
$this->mimeType .= '/' . strtolower($structure->subtype);
|
||||
|
||||
$this->encoding = $structure->encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the data of the attachment. Combined with getMimeType() it can be used to directly output
|
||||
* data to a browser.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if (!isset($this->data)) {
|
||||
$messageBody = isset($this->partId) ?
|
||||
imap_fetchbody($this->imapStream, $this->messageId, $this->partId, FT_UID)
|
||||
: imap_body($this->imapStream, $this->messageId, FT_UID);
|
||||
|
||||
$messageBody = Message::decode($messageBody, $this->encoding);
|
||||
$this->data = $messageBody;
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the filename of the attachment, or false if one isn't given.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName()
|
||||
{
|
||||
return (isset($this->filename)) ? $this->filename : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the mimetype of the attachment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the size of the attachment.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the object that contains the structure of this attachment.
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getStructure()
|
||||
{
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function saves the attachment to the passed directory, keeping the original name of the file.
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function saveToDirectory($path)
|
||||
{
|
||||
$path = rtrim($path, '/') . '/';
|
||||
|
||||
if (is_dir($path))
|
||||
return $this->saveAs($path . $this->getFileName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function saves the attachment to the exact specified location.
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAs($path)
|
||||
{
|
||||
$dirname = dirname($path);
|
||||
if (file_exists($path)) {
|
||||
if (!is_writable($path))
|
||||
return false;
|
||||
} elseif (!is_dir($dirname) || !is_writable($dirname)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($filePointer = fopen($path, 'w')) == false)
|
||||
return false;
|
||||
|
||||
switch ($this->encoding) {
|
||||
case 3:
|
||||
case 'base64':
|
||||
$streamFilter = stream_filter_append($filePointer, 'convert.base64-decode', STREAM_FILTER_WRITE);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 'quoted-printable':
|
||||
$streamFilter = stream_filter_append($filePointer, 'convert.quoted-printable', STREAM_FILTER_WRITE);
|
||||
break;
|
||||
|
||||
default:
|
||||
$streamFilter = null;
|
||||
}
|
||||
|
||||
$result = imap_savebody($this->imapStream, $filePointer, $this->messageId, $this->partId ?: 1, FT_UID);
|
||||
|
||||
if ($streamFilter) {
|
||||
stream_filter_remove($streamFilter);
|
||||
}
|
||||
|
||||
fclose($filePointer);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
726
retailcrm/src/Vendor/Fetch/Message.php
vendored
Normal file
726
retailcrm/src/Vendor/Fetch/Message.php
vendored
Normal file
@ -0,0 +1,726 @@
|
||||
<?php
|
||||
|
||||
class Message
|
||||
{
|
||||
/**
|
||||
* This is the connection/mailbox class that the email came from.
|
||||
*
|
||||
* @var Server
|
||||
*/
|
||||
protected $imapConnection;
|
||||
|
||||
/**
|
||||
* This is the unique identifier for the message. This corresponds to the imap "uid", which we use instead of the
|
||||
* sequence number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $uid;
|
||||
|
||||
/**
|
||||
* This is a reference to the Imap stream generated by 'imap_open'.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $imapStream;
|
||||
|
||||
/**
|
||||
* This as an object which contains header information for the message.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $headers;
|
||||
|
||||
/**
|
||||
* This is an object which contains various status messages and other information about the message.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $messageOverview;
|
||||
|
||||
/**
|
||||
* This is an object which contains information about the structure of the message body.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $structure;
|
||||
|
||||
/**
|
||||
* This is an array with the index being imap flags and the value being a boolean specifying whether that flag is
|
||||
* set or not.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $status = array();
|
||||
|
||||
/**
|
||||
* This is an array of the various imap flags that can be set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $flagTypes = array('recent', 'flagged', 'answered', 'deleted', 'seen', 'draft');
|
||||
|
||||
/**
|
||||
* This holds the plantext email message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $plaintextMessage;
|
||||
|
||||
/**
|
||||
* This holds the html version of the email.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $htmlMessage;
|
||||
|
||||
/**
|
||||
* This is the date the email was sent.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $date;
|
||||
|
||||
/**
|
||||
* This is the subject of the email.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $subject;
|
||||
|
||||
/**
|
||||
* This is the size of the email.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* This is an array containing information about the address the email came from.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $from;
|
||||
|
||||
/**
|
||||
* This is an array of arrays that contains information about the addresses the email was sent to.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* This is an array of arrays that contains information about the addresses the email was cc'd to.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cc;
|
||||
|
||||
/**
|
||||
* This is an array of arrays that contains information about the addresses the email was bcc'd to.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $bcc;
|
||||
|
||||
/**
|
||||
* This is an array of arrays that contain information about the addresses that should receive replies to the email.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $replyTo;
|
||||
|
||||
/**
|
||||
* This is an array of ImapAttachments retrieved from the message.
|
||||
*
|
||||
* @var Attachment[]
|
||||
*/
|
||||
protected $attachments = array();
|
||||
|
||||
/**
|
||||
* Contains the mailbox that the message resides in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $mailbox;
|
||||
|
||||
/**
|
||||
* This value defines the encoding we want the email message to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $charset = 'UTF-8';
|
||||
|
||||
/**
|
||||
* This value defines the flag set for encoding if the mb_convert_encoding
|
||||
* function can't be found, and in this case iconv encoding will be used.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $charsetFlag = '//TRANSLIT';
|
||||
|
||||
/**
|
||||
* These constants can be used to easily access available flags
|
||||
*/
|
||||
const FLAG_RECENT = 'recent';
|
||||
const FLAG_FLAGGED = 'flagged';
|
||||
const FLAG_ANSWERED = 'answered';
|
||||
const FLAG_DELETED = 'deleted';
|
||||
const FLAG_SEEN = 'seen';
|
||||
const FLAG_DRAFT = 'draft';
|
||||
|
||||
/**
|
||||
* This constructor takes in the uid for the message and the Imap class representing the mailbox the
|
||||
* message should be opened from. This constructor should generally not be called directly, but rather retrieved
|
||||
* through the apprioriate Imap functions.
|
||||
*
|
||||
* @param int $messageUniqueId
|
||||
* @param Server $mailbox
|
||||
*/
|
||||
public function __construct($messageUniqueId, Server $connection)
|
||||
{
|
||||
$this->imapConnection = $connection;
|
||||
$this->mailbox = $connection->getMailBox();
|
||||
$this->uid = $messageUniqueId;
|
||||
$this->imapStream = $this->imapConnection->getImapStream();
|
||||
if($this->loadMessage() !== true)
|
||||
throw new RuntimeException('Message with ID ' . $messageUniqueId . ' not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the message class is loaded. It loads general information about the message from the
|
||||
* imap server.
|
||||
*
|
||||
*/
|
||||
protected function loadMessage()
|
||||
{
|
||||
|
||||
/* First load the message overview information */
|
||||
|
||||
if(!is_object($messageOverview = $this->getOverview()))
|
||||
|
||||
return false;
|
||||
|
||||
$this->subject = isset($messageOverview->subject) ? $messageOverview->subject : null;
|
||||
$this->subject = self::decodeHeader($this->subject);
|
||||
$this->date = strtotime($messageOverview->date);
|
||||
$this->size = $messageOverview->size;
|
||||
|
||||
foreach (self::$flagTypes as $flag)
|
||||
$this->status[$flag] = ($messageOverview->$flag == 1);
|
||||
|
||||
/* Next load in all of the header information */
|
||||
|
||||
$headers = $this->getHeaders();
|
||||
|
||||
if (isset($headers->to))
|
||||
$this->to = $this->processAddressObject($headers->to);
|
||||
|
||||
if (isset($headers->cc))
|
||||
$this->cc = $this->processAddressObject($headers->cc);
|
||||
|
||||
if (isset($headers->bcc))
|
||||
$this->bcc = $this->processAddressObject($headers->bcc);
|
||||
|
||||
$this->from = $this->processAddressObject($headers->from);
|
||||
$this->replyTo = isset($headers->reply_to) ? $this->processAddressObject($headers->reply_to) : $this->from;
|
||||
|
||||
/* Finally load the structure itself */
|
||||
|
||||
$structure = $this->getStructure();
|
||||
|
||||
if (!isset($structure->parts)) {
|
||||
// not multipart
|
||||
$this->processStructure($structure);
|
||||
} else {
|
||||
// multipart
|
||||
foreach ($structure->parts as $id => $part)
|
||||
$this->processStructure($part, $id + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns an object containing information about the message. This output is similar to that over the
|
||||
* imap_fetch_overview function, only instead of an array of message overviews only a single result is returned. The
|
||||
* results are only retrieved from the server once unless passed true as a parameter.
|
||||
*
|
||||
* @param bool $forceReload
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getOverview($forceReload = false)
|
||||
{
|
||||
if ($forceReload || !isset($this->messageOverview)) {
|
||||
// returns an array, and since we just want one message we can grab the only result
|
||||
$results = imap_fetch_overview($this->imapStream, $this->uid, FT_UID);
|
||||
$this->messageOverview = array_shift($results);
|
||||
}
|
||||
|
||||
return $this->messageOverview;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns an object containing the headers of the message. This is done by taking the raw headers
|
||||
* and running them through the imap_rfc822_parse_headers function. The results are only retrieved from the server
|
||||
* once unless passed true as a parameter.
|
||||
*
|
||||
* @param bool $forceReload
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getHeaders($forceReload = false)
|
||||
{
|
||||
if ($forceReload || !isset($this->headers)) {
|
||||
// raw headers (since imap_headerinfo doesn't use the unique id)
|
||||
$rawHeaders = imap_fetchheader($this->imapStream, $this->uid, FT_UID);
|
||||
|
||||
// convert raw header string into a usable object
|
||||
$headerObject = imap_rfc822_parse_headers($rawHeaders);
|
||||
|
||||
// to keep this object as close as possible to the original header object we add the udate property
|
||||
$headerObject->udate = strtotime($headerObject->date);
|
||||
|
||||
$this->headers = $headerObject;
|
||||
}
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns an object containing the structure of the message body. This is the same object thats
|
||||
* returned by imap_fetchstructure. The results are only retrieved from the server once unless passed true as a
|
||||
* parameter.
|
||||
*
|
||||
* @param bool $forceReload
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getStructure($forceReload = false)
|
||||
{
|
||||
if ($forceReload || !isset($this->structure)) {
|
||||
$this->structure = imap_fetchstructure($this->imapStream, $this->uid, FT_UID);
|
||||
}
|
||||
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the message body of the email. By default it returns the plaintext version. If a plaintext
|
||||
* version is requested but not present, the html version is stripped of tags and returned. If the opposite occurs,
|
||||
* the plaintext version is given some html formatting and returned. If neither are present the return value will be
|
||||
* false.
|
||||
*
|
||||
* @param bool $html Pass true to receive an html response.
|
||||
* @return string|bool Returns false if no body is present.
|
||||
*/
|
||||
public function getMessageBody($html = false)
|
||||
{
|
||||
if ($html) {
|
||||
if (!isset($this->htmlMessage) && isset($this->plaintextMessage)) {
|
||||
$output = nl2br($this->plaintextMessage);
|
||||
|
||||
return $output;
|
||||
|
||||
} elseif (isset($this->htmlMessage)) {
|
||||
return $this->htmlMessage;
|
||||
}
|
||||
} else {
|
||||
if (!isset($this->plaintextMessage) && isset($this->htmlMessage)) {
|
||||
$output = preg_replace('/\<br(\s*)?\/?\>/i', PHP_EOL, trim($this->htmlMessage) );
|
||||
$output = strip_tags($output);
|
||||
|
||||
return $output;
|
||||
} elseif (isset($this->plaintextMessage)) {
|
||||
return $this->plaintextMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns either an array of email addresses and names or, optionally, a string that can be used in
|
||||
* mail headers.
|
||||
*
|
||||
* @param string $type Should be 'to', 'cc', 'bcc', 'from', or 'reply-to'.
|
||||
* @param bool $asString
|
||||
* @return array|string|bool
|
||||
*/
|
||||
public function getAddresses($type, $asString = false)
|
||||
{
|
||||
$type = ( $type == 'reply-to' ) ? 'replyTo' : $type;
|
||||
$addressTypes = array('to', 'cc', 'bcc', 'from', 'replyTo');
|
||||
|
||||
if (!in_array($type, $addressTypes) || !isset($this->$type) || count($this->$type) < 1)
|
||||
return false;
|
||||
|
||||
if (!$asString) {
|
||||
if ($type == 'from')
|
||||
return $this->from[0];
|
||||
|
||||
return $this->$type;
|
||||
} else {
|
||||
$outputString = '';
|
||||
foreach ($this->$type as $address) {
|
||||
if (isset($set))
|
||||
$outputString .= ', ';
|
||||
if (!isset($set))
|
||||
$set = true;
|
||||
|
||||
$outputString .= isset($address['name']) ?
|
||||
$address['name'] . ' <' . $address['address'] . '>'
|
||||
: $address['address'];
|
||||
}
|
||||
|
||||
return $outputString;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the date, as a timestamp, of when the email was sent.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDate()
|
||||
{
|
||||
return isset($this->date) ? $this->date : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the subject of the message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSubject()
|
||||
{
|
||||
return isset($this->subject) ? $this->subject : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function marks a message for deletion. It is important to note that the message will not be deleted form the
|
||||
* mailbox until the Imap->expunge it run.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return imap_delete($this->imapStream, $this->uid, FT_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns Imap this message came from.
|
||||
*
|
||||
* @return Server
|
||||
*/
|
||||
public function getImapBox()
|
||||
{
|
||||
return $this->imapConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in a structure and identifier and processes that part of the message. If that portion of the
|
||||
* message has its own subparts, those are recursively processed using this function.
|
||||
*
|
||||
* @param stdClass $structure
|
||||
* @param string $partIdentifier
|
||||
*/
|
||||
protected function processStructure($structure, $partIdentifier = null)
|
||||
{
|
||||
$parameters = self::getParametersFromStructure($structure);
|
||||
|
||||
if (isset($structure->parts)) { // multipart: iterate through each part
|
||||
foreach ($structure->parts as $partIndex => $part) {
|
||||
$partId = $partIndex + 1;
|
||||
|
||||
if (isset($partIdentifier))
|
||||
$partId = $partIdentifier . '.' . $partId;
|
||||
|
||||
$this->processStructure($part, $partId);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($parameters['name']) || isset($parameters['filename']) && $parameters['filename']) {
|
||||
$attachment = new Attachment($this, $structure, $partIdentifier);
|
||||
$this->attachments[] = $attachment;
|
||||
} elseif ($structure->type == 0 || $structure->type == 1) {
|
||||
$messageBody = isset($partIdentifier) ?
|
||||
imap_fetchbody($this->imapStream, $this->uid, $partIdentifier, FT_UID)
|
||||
: imap_body($this->imapStream, $this->uid, FT_UID);
|
||||
|
||||
$messageBody = self::decode($messageBody, $structure->encoding);
|
||||
|
||||
if (!empty($parameters['charset']) && $parameters['charset'] !== self::$charset) {
|
||||
$mb_converted = false;
|
||||
//if (function_exists('mb_convert_encoding')) {
|
||||
// try {
|
||||
// $messageBody = mb_convert_encoding($messageBody, self::$charset, $parameters['charset']);
|
||||
// $mb_converted = true;
|
||||
// } catch (Exception $e) {
|
||||
// // @TODO Handle exception
|
||||
// }
|
||||
//}
|
||||
if ( ! $mb_converted) {
|
||||
try {
|
||||
$messageBody = iconv($parameters['charset'], self::$charset . self::$charsetFlag, $messageBody);
|
||||
} catch (Exception $e) {
|
||||
// @TODO Handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strtolower($structure->subtype) === 'plain' || ($structure->type == 1 && strtolower($structure->subtype) !== 'alternative')) {
|
||||
if (isset($this->plaintextMessage)) {
|
||||
$this->plaintextMessage .= PHP_EOL . PHP_EOL;
|
||||
} else {
|
||||
$this->plaintextMessage = '';
|
||||
}
|
||||
|
||||
$this->plaintextMessage .= trim($messageBody);
|
||||
} else {
|
||||
if (isset($this->htmlMessage)) {
|
||||
$this->htmlMessage .= '<br><br>';
|
||||
} else {
|
||||
$this->htmlMessage = '';
|
||||
}
|
||||
|
||||
$this->htmlMessage .= $messageBody;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in the message data and encoding type and returns the decoded data.
|
||||
*
|
||||
* @param string $data
|
||||
* @param int|string $encoding
|
||||
* @return string
|
||||
*/
|
||||
public static function decode($data, $encoding)
|
||||
{
|
||||
if (!is_numeric($encoding)) {
|
||||
$encoding = strtolower($encoding);
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case $encoding === 'quoted-printable':
|
||||
case $encoding === 4:
|
||||
return quoted_printable_decode($data);
|
||||
|
||||
case $encoding === 'base64':
|
||||
case $encoding === 3:
|
||||
return base64_decode($data);
|
||||
|
||||
default:
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public static function decodeHeader($header, $outEncoding = null)
|
||||
{
|
||||
if ($header === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$outEncoding) {
|
||||
$outEncoding = self::$charset;
|
||||
}
|
||||
|
||||
$header = imap_mime_header_decode($header);
|
||||
|
||||
$decoded = '';
|
||||
for ($i = 0; $i < count($header); $i++) {
|
||||
if ($header[$i]->charset != 'default') {
|
||||
$decoded .= iconv($header[$i]->charset, $outEncoding . self::$charsetFlag, $header[$i]->text);
|
||||
} else {
|
||||
$decoded .= $header[$i]->text;
|
||||
}
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the body type that an imap integer maps to.
|
||||
*
|
||||
* @param int $id
|
||||
* @return string
|
||||
*/
|
||||
public static function typeIdToString($id)
|
||||
{
|
||||
switch ($id) {
|
||||
case 0:
|
||||
return 'text';
|
||||
|
||||
case 1:
|
||||
return 'multipart';
|
||||
|
||||
case 2:
|
||||
return 'message';
|
||||
|
||||
case 3:
|
||||
return 'application';
|
||||
|
||||
case 4:
|
||||
return 'audio';
|
||||
|
||||
case 5:
|
||||
return 'image';
|
||||
|
||||
case 6:
|
||||
return 'video';
|
||||
|
||||
default:
|
||||
case 7:
|
||||
return 'other';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a section structure and returns its parameters as an associative array.
|
||||
*
|
||||
* @param stdClass $structure
|
||||
* @return array
|
||||
*/
|
||||
public static function getParametersFromStructure($structure)
|
||||
{
|
||||
$parameters = array();
|
||||
if (isset($structure->parameters))
|
||||
foreach ($structure->parameters as $parameter)
|
||||
$parameters[strtolower($parameter->attribute)] = $parameter->value;
|
||||
|
||||
if (isset($structure->dparameters))
|
||||
foreach ($structure->dparameters as $parameter)
|
||||
$parameters[strtolower($parameter->attribute)] = $parameter->value;
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in an array of the address objects generated by the message headers and turns them into an
|
||||
* associative array.
|
||||
*
|
||||
* @param array $addresses
|
||||
* @return array
|
||||
*/
|
||||
protected function processAddressObject($addresses)
|
||||
{
|
||||
$outputAddresses = array();
|
||||
if (is_array($addresses))
|
||||
foreach ($addresses as $address) {
|
||||
if (!isset($address->mailbox) || !isset($address->host)) {
|
||||
continue;
|
||||
}
|
||||
$currentAddress = array();
|
||||
$currentAddress['address'] = $address->mailbox . '@' . $address->host;
|
||||
if (isset($address->personal))
|
||||
$currentAddress['name'] = self::decodeHeader($address->personal);
|
||||
$outputAddresses[] = $currentAddress;
|
||||
}
|
||||
|
||||
return $outputAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the unique id that identifies the message on the server.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getUid()
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the attachments a message contains. If a filename is passed then just that ImapAttachment
|
||||
* is returned, unless
|
||||
*
|
||||
* @param null|string $filename
|
||||
* @return array|bool|Attachment[]
|
||||
*/
|
||||
public function getAttachments($filename = null)
|
||||
{
|
||||
if (!isset($this->attachments) || count($this->attachments) < 1)
|
||||
return false;
|
||||
|
||||
if (!isset($filename))
|
||||
return $this->attachments;
|
||||
|
||||
$results = array();
|
||||
foreach ($this->attachments as $attachment) {
|
||||
if ($attachment->getFileName() == $filename)
|
||||
$results[] = $attachment;
|
||||
}
|
||||
|
||||
switch (count($results)) {
|
||||
case 0:
|
||||
return false;
|
||||
|
||||
case 1:
|
||||
return array_shift($results);
|
||||
|
||||
default:
|
||||
return $results;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks to see if an imap flag is set on the email message.
|
||||
*
|
||||
* @param string $flag Recent, Flagged, Answered, Deleted, Seen, Draft
|
||||
* @return bool
|
||||
*/
|
||||
public function checkFlag($flag = 'flagged')
|
||||
{
|
||||
return (isset($this->status[$flag]) && $this->status[$flag] === true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to enable or disable a flag on the imap message.
|
||||
*
|
||||
* @param string $flag Flagged, Answered, Deleted, Seen, Draft
|
||||
* @param bool $enable
|
||||
* @throws InvalidArgumentException
|
||||
* @return bool
|
||||
*/
|
||||
public function setFlag($flag, $enable = true)
|
||||
{
|
||||
if (!in_array($flag, self::$flagTypes) || $flag == 'recent')
|
||||
throw new InvalidArgumentException('Unable to set invalid flag "' . $flag . '"');
|
||||
|
||||
$imapifiedFlag = '\\' . ucfirst($flag);
|
||||
|
||||
if ($enable === true) {
|
||||
$this->status[$flag] = true;
|
||||
|
||||
return imap_setflag_full($this->imapStream, $this->uid, $imapifiedFlag, ST_UID);
|
||||
} else {
|
||||
unset($this->status[$flag]);
|
||||
|
||||
return imap_clearflag_full($this->imapStream, $this->uid, $imapifiedFlag, ST_UID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to move a mail to the given mailbox.
|
||||
*
|
||||
* @param $mailbox
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function moveToMailBox($mailbox)
|
||||
{
|
||||
$currentBox = $this->imapConnection->getMailBox();
|
||||
$this->imapConnection->setMailBox($this->mailbox);
|
||||
|
||||
$returnValue = imap_mail_copy($this->imapStream, $this->uid, $mailbox, CP_UID | CP_MOVE);
|
||||
imap_expunge($this->imapStream);
|
||||
|
||||
$this->mailbox = $mailbox;
|
||||
|
||||
$this->imapConnection->setMailBox($currentBox);
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
428
retailcrm/src/Vendor/Fetch/Server.php
vendored
Normal file
428
retailcrm/src/Vendor/Fetch/Server.php
vendored
Normal file
@ -0,0 +1,428 @@
|
||||
<?php
|
||||
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* When SSL isn't compiled into PHP we need to make some adjustments to prevent soul crushing annoyances.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $sslEnable = true;
|
||||
|
||||
/**
|
||||
* These are the flags that depend on ssl support being compiled into imap.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $sslFlags = array('ssl', 'validate-cert', 'novalidate-cert', 'tls', 'notls');
|
||||
|
||||
/**
|
||||
* This is used to prevent the class from putting up conflicting tags. Both directions- key to value, value to key-
|
||||
* are checked, so if "novalidate-cert" is passed then "validate-cert" is removed, and vice-versa.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $exclusiveFlags = array('validate-cert' => 'novalidate-cert', 'tls' => 'notls');
|
||||
|
||||
/**
|
||||
* This is the domain or server path the class is connecting to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serverPath;
|
||||
|
||||
/**
|
||||
* This is the name of the current mailbox the connection is using.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $mailbox = '';
|
||||
|
||||
/**
|
||||
* This is the username used to connect to the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* This is the password used to connect to the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* This is an array of flags that modify how the class connects to the server. Examples include "ssl" to enforce a
|
||||
* secure connection or "novalidate-cert" to allow for self-signed certificates.
|
||||
*
|
||||
* @link http://us.php.net/manual/en/function.imap-open.php
|
||||
* @var array
|
||||
*/
|
||||
protected $flags = array();
|
||||
|
||||
/**
|
||||
* This is the port used to connect to the server
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* This is the set of options, represented by a bitmask, to be passed to the server during connection.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $options = 0;
|
||||
|
||||
/**
|
||||
* This is the resource connection to the server. It is required by a number of imap based functions to specify how
|
||||
* to connect.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $imapStream;
|
||||
|
||||
/**
|
||||
* This is the name of the service currently being used. Imap is the default, although pop3 and nntp are also
|
||||
* options
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $service = 'imap';
|
||||
|
||||
/**
|
||||
* This constructor takes the location and service thats trying to be connected to as its arguments.
|
||||
*
|
||||
* @param string $serverPath
|
||||
* @param null|int $port
|
||||
* @param null|string $service
|
||||
*/
|
||||
public function __construct($serverPath, $port = 143, $service = 'imap')
|
||||
{
|
||||
$this->serverPath = $serverPath;
|
||||
|
||||
$this->port = $port;
|
||||
|
||||
switch ($port) {
|
||||
case 143:
|
||||
$this->setFlag('novalidate-cert');
|
||||
break;
|
||||
|
||||
case 993:
|
||||
$this->setFlag('ssl');
|
||||
break;
|
||||
}
|
||||
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the username and password used to connect to the server.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
public function setAuthentication($username, $password)
|
||||
{
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the mailbox to connect to.
|
||||
*
|
||||
* @param string $mailbox
|
||||
* @return bool
|
||||
*/
|
||||
public function setMailBox($mailbox = '')
|
||||
{
|
||||
if (!$this->hasMailBox($mailbox)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->mailbox = $mailbox;
|
||||
if (isset($this->imapStream)) {
|
||||
$this->setImapStream();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getMailBox()
|
||||
{
|
||||
return $this->mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets or removes flag specifying connection behavior. In many cases the flag is just a one word
|
||||
* deal, so the value attribute is not required. However, if the value parameter is passed false it will clear that
|
||||
* flag.
|
||||
*
|
||||
* @param string $flag
|
||||
* @param null|string|bool $value
|
||||
*/
|
||||
public function setFlag($flag, $value = null)
|
||||
{
|
||||
if (!self::$sslEnable && in_array($flag, self::$sslFlags))
|
||||
return;
|
||||
|
||||
if (isset(self::$exclusiveFlags[$flag])) {
|
||||
$kill = self::$exclusiveFlags[$flag];
|
||||
} elseif ($index = array_search($flag, self::$exclusiveFlags)) {
|
||||
$kill = $index;
|
||||
}
|
||||
|
||||
if (isset($kill) && false !== $index = array_search($kill, $this->flags))
|
||||
unset($this->flags[$index]);
|
||||
|
||||
$index = array_search($flag, $this->flags);
|
||||
if (isset($value) && $value !== true) {
|
||||
if ($value == false && $index !== false) {
|
||||
unset($this->flags[$index]);
|
||||
} elseif ($value != false) {
|
||||
$match = preg_grep('/' . $flag . '/', $this->flags);
|
||||
if (reset($match)) {
|
||||
$this->flags[key($match)] = $flag . '=' . $value;
|
||||
} else {
|
||||
$this->flags[] = $flag . '=' . $value;
|
||||
}
|
||||
}
|
||||
} elseif ($index === false) {
|
||||
$this->flags[] = $flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This funtion is used to set various options for connecting to the server.
|
||||
*
|
||||
* @param int $bitmask
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setOptions($bitmask = 0)
|
||||
{
|
||||
if (!is_numeric($bitmask))
|
||||
throw new RuntimeException('Function requires numeric argument.');
|
||||
|
||||
$this->options = $bitmask;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets the current saved imap resource and returns it.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getImapStream()
|
||||
{
|
||||
if (!isset($this->imapStream))
|
||||
$this->setImapStream();
|
||||
|
||||
return $this->imapStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in all of the connection date (server, port, service, flags, mailbox) and creates the string
|
||||
* thats passed to the imap_open function.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServerString()
|
||||
{
|
||||
$mailboxPath = $this->getServerSpecification();
|
||||
|
||||
if (isset($this->mailbox))
|
||||
$mailboxPath .= $this->mailbox;
|
||||
|
||||
return $mailboxPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server specification, without adding any mailbox.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getServerSpecification()
|
||||
{
|
||||
$mailboxPath = '{' . $this->serverPath;
|
||||
|
||||
if (isset($this->port))
|
||||
$mailboxPath .= ':' . $this->port;
|
||||
|
||||
if ($this->service != 'imap')
|
||||
$mailboxPath .= '/' . $this->service;
|
||||
|
||||
foreach ($this->flags as $flag) {
|
||||
$mailboxPath .= '/' . $flag;
|
||||
}
|
||||
|
||||
$mailboxPath .= '}';
|
||||
|
||||
return $mailboxPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates or reopens an imapStream when called.
|
||||
*
|
||||
*/
|
||||
protected function setImapStream()
|
||||
{
|
||||
if (isset($this->imapStream)) {
|
||||
if (!imap_reopen($this->imapStream, $this->getServerString(), $this->options, 1))
|
||||
throw new RuntimeException(imap_last_error());
|
||||
} else {
|
||||
$imapStream = imap_open($this->getServerString(), $this->username, $this->password, $this->options, 1);
|
||||
|
||||
if ($imapStream === false)
|
||||
throw new RuntimeException(imap_last_error());
|
||||
|
||||
$this->imapStream = $imapStream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the number of messages that the current mailbox contains.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numMessages()
|
||||
{
|
||||
return imap_num_msg($this->getImapStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns an array of ImapMessage object for emails that fit the criteria passed. The criteria string
|
||||
* should be formatted according to the imap search standard, which can be found on the php "imap_search" page or in
|
||||
* section 6.4.4 of RFC 2060
|
||||
*
|
||||
* @link http://us.php.net/imap_search
|
||||
* @link http://www.faqs.org/rfcs/rfc2060
|
||||
* @param string $criteria
|
||||
* @param null|int $limit
|
||||
* @return array An array of ImapMessage objects
|
||||
*/
|
||||
public function search($criteria = 'ALL', $limit = null)
|
||||
{
|
||||
if ($results = imap_search($this->getImapStream(), $criteria, SE_UID)) {
|
||||
if (isset($limit) && count($results) > $limit)
|
||||
$results = array_slice($results, 0, $limit);
|
||||
|
||||
$messages = array();
|
||||
|
||||
foreach ($results as $messageId)
|
||||
$messages[] = new Message($messageId, $this);
|
||||
|
||||
return $messages;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the recently received emails as an array of ImapMessage objects.
|
||||
*
|
||||
* @param null|int $limit
|
||||
* @return array An array of ImapMessage objects for emails that were recently received by the server.
|
||||
*/
|
||||
public function getRecentMessages($limit = null)
|
||||
{
|
||||
return $this->search('Recent', $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the emails in the current mailbox as an array of ImapMessage objects.
|
||||
*
|
||||
* @param null|int $limit
|
||||
* @return Message[]
|
||||
*/
|
||||
public function getMessages($limit = null)
|
||||
{
|
||||
$numMessages = $this->numMessages();
|
||||
|
||||
if (isset($limit) && is_numeric($limit) && $limit < $numMessages)
|
||||
$numMessages = $limit;
|
||||
|
||||
if ($numMessages < 1)
|
||||
return array();
|
||||
|
||||
$stream = $this->getImapStream();
|
||||
$messages = array();
|
||||
for ($i = 1; $i <= $numMessages; $i++) {
|
||||
$uid = imap_uid($stream, $i);
|
||||
$messages[] = new Message($uid, $this);
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the emails in the current mailbox as an array of ImapMessage objects
|
||||
* ordered by some ordering
|
||||
*
|
||||
* @see http://php.net/manual/en/function.imap-sort.php
|
||||
* @param int $orderBy
|
||||
* @param bool $reverse
|
||||
* @param int $limit
|
||||
* @return Message[]
|
||||
*/
|
||||
public function getOrdered($orderBy, $reverse, $limit)
|
||||
{
|
||||
$msgIds = imap_sort($this->getImapStream(), $orderBy, $reverse ? 1 : 0, SE_UID);
|
||||
|
||||
return array_map(array($this, 'getMessageByUid'), array_slice($msgIds, 0, $limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested email or false if it is not found.
|
||||
*
|
||||
* @param int $uid
|
||||
* @return Message|bool
|
||||
*/
|
||||
public function getMessageByUid($uid)
|
||||
{
|
||||
try {
|
||||
$message = new Fetch\Message($uid, $this);
|
||||
|
||||
return $message;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function removes all of the messages flagged for deletion from the mailbox.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function expunge()
|
||||
{
|
||||
return imap_expunge($this->getImapStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given mailbox exists.
|
||||
*
|
||||
* @param $mailbox
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMailBox($mailbox)
|
||||
{
|
||||
return (boolean) imap_getmailboxes(
|
||||
$this->getImapStream(),
|
||||
$this->getServerString(),
|
||||
$this->getServerSpecification() . $mailbox
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given mailbox.
|
||||
*
|
||||
* @param $mailbox
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function createMailBox($mailbox)
|
||||
{
|
||||
return imap_createmailbox($this->getImapStream(), $this->getServerSpecification() . $mailbox);
|
||||
}
|
||||
}
|
4170
retailcrm/src/Vendor/MoySklad/MSRestApi.php
vendored
Normal file
4170
retailcrm/src/Vendor/MoySklad/MSRestApi.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
811
retailcrm/src/Vendor/RetailCrm/ApiClient.php
vendored
Normal file
811
retailcrm/src/Vendor/RetailCrm/ApiClient.php
vendored
Normal file
@ -0,0 +1,811 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* retailCRM API client class
|
||||
*/
|
||||
class ApiClient
|
||||
{
|
||||
const VERSION = 'v3';
|
||||
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Site code
|
||||
*/
|
||||
protected $siteCode;
|
||||
|
||||
/**
|
||||
* Client creating
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $apiKey
|
||||
* @param string $siteCode
|
||||
* @return mixed
|
||||
*/
|
||||
public function __construct($url, $apiKey, $site = null)
|
||||
{
|
||||
if ('/' != substr($url, strlen($url) - 1, 1)) {
|
||||
$url .= '/';
|
||||
}
|
||||
|
||||
$url = $url . 'api/' . self::VERSION;
|
||||
|
||||
$this->client = new Client($url, array('apiKey' => $apiKey));
|
||||
$this->siteCode = $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a order
|
||||
*
|
||||
* @param array $order
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersCreate(array $order, $site = null)
|
||||
{
|
||||
if (!sizeof($order)) {
|
||||
throw new InvalidArgumentException('Parameter `order` must contains a data');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest("/orders/create", Client::METHOD_POST, $this->fillSite($site, array(
|
||||
'order' => json_encode($order)
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a order
|
||||
*
|
||||
* @param array $order
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersEdit(array $order, $by = 'externalId', $site = null)
|
||||
{
|
||||
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,
|
||||
$this->fillSite($site, array(
|
||||
'order' => json_encode($order),
|
||||
'by' => $by,
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload array of the orders
|
||||
*
|
||||
* @param array $orders
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersUpload(array $orders, $site = null)
|
||||
{
|
||||
if (!sizeof($orders)) {
|
||||
throw new InvalidArgumentException('Parameter `orders` must contains array of the orders');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest("/orders/upload", Client::METHOD_POST, $this->fillSite($site, array(
|
||||
'orders' => json_encode($orders),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order by id or externalId
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $by (default: 'externalId')
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersGet($id, $by = 'externalId', $site = null)
|
||||
{
|
||||
$this->checkIdParameter($by);
|
||||
|
||||
return $this->client->makeRequest("/orders/$id", Client::METHOD_GET, $this->fillSite($site, 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)
|
||||
* @param bool $skipMyChanges (default: true)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersHistory(
|
||||
DateTime $startDate = null,
|
||||
DateTime $endDate = null,
|
||||
$limit = 100,
|
||||
$offset = 0,
|
||||
$skipMyChanges = true
|
||||
) {
|
||||
$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;
|
||||
}
|
||||
if ($skipMyChanges) {
|
||||
$parameters['skipMyChanges'] = (bool) $skipMyChanges;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns statuses of the orders
|
||||
*
|
||||
* @param array $ids (default: array())
|
||||
* @param array $externalIds (default: array())
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersStatuses(array $ids = array(), array $externalIds = array())
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
if (sizeof($ids)) {
|
||||
$parameters['ids'] = $ids;
|
||||
}
|
||||
if (sizeof($externalIds)) {
|
||||
$parameters['externalIds'] = $externalIds;
|
||||
}
|
||||
|
||||
return $this->client->makeRequest('/orders/statuses', 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),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orders assembly history
|
||||
*
|
||||
* @param array $filter (default: array())
|
||||
* @param int $page (default: null)
|
||||
* @param int $limit (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function ordersPacksHistory(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/packs/history', Client::METHOD_GET, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a customer
|
||||
*
|
||||
* @param array $customer
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function customersCreate(array $customer, $site = null)
|
||||
{
|
||||
if (!sizeof($customer)) {
|
||||
throw new InvalidArgumentException('Parameter `customer` must contains a data');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest("/customers/create", Client::METHOD_POST, $this->fillSite($site, array(
|
||||
'customer' => json_encode($customer)
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a customer
|
||||
*
|
||||
* @param array $customer
|
||||
* @param string $by (default: 'externalId')
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function customersEdit(array $customer, $by = 'externalId', $site = null)
|
||||
{
|
||||
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,
|
||||
$this->fillSite(
|
||||
$site,
|
||||
array(
|
||||
'customer' => json_encode($customer),
|
||||
'by' => $by
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload array of the customers
|
||||
*
|
||||
* @param array $customers
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function customersUpload(array $customers, $site = null)
|
||||
{
|
||||
if (!sizeof($customers)) {
|
||||
throw new InvalidArgumentException('Parameter `customers` must contains array of the customers');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest("/customers/upload", Client::METHOD_POST, $this->fillSite($site, array(
|
||||
'customers' => json_encode($customers),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer by id or externalId
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $by (default: 'externalId')
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function customersGet($id, $by = 'externalId', $site = null)
|
||||
{
|
||||
$this->checkIdParameter($by);
|
||||
|
||||
return $this->client->makeRequest("/customers/$id", Client::METHOD_GET, $this->fillSite($site, 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),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get purchace prices & stock balance
|
||||
*
|
||||
* @param array $filter (default: array())
|
||||
* @param int $page (default: null)
|
||||
* @param int $limit (default: null)
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function storeInventories(array $filter = array(), $page = null, $limit = null, $site = 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('/store/inventories', Client::METHOD_GET, $this->fillSite($site, $parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload store inventories
|
||||
*
|
||||
* @param array $offers
|
||||
* @param string $site (default: null)
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function storeInventoriesUpload(array $offers, $site = null)
|
||||
{
|
||||
if (!sizeof($offers)) {
|
||||
throw new InvalidArgumentException('Parameter `offers` must contains array of the customers');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest(
|
||||
"/store/inventories/upload",
|
||||
Client::METHOD_POST,
|
||||
$this->fillSite($site, array('offers' => json_encode($offers)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sites list
|
||||
*
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function sitesList()
|
||||
{
|
||||
return $this->client->makeRequest('/reference/sites', Client::METHOD_GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stores list
|
||||
*
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function storesList()
|
||||
{
|
||||
return $this->client->makeRequest('/reference/stores', Client::METHOD_GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit deliveryService
|
||||
*
|
||||
* @param array $data delivery service data
|
||||
* @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
|
||||
*
|
||||
* @param array $data delivery type data
|
||||
* @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
|
||||
*
|
||||
* @param array $data order method data
|
||||
* @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
|
||||
*
|
||||
* @param array $data order type data
|
||||
* @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
|
||||
*
|
||||
* @param array $data payment status data
|
||||
* @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
|
||||
*
|
||||
* @param array $data payment type data
|
||||
* @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
|
||||
*
|
||||
* @param array $data product status data
|
||||
* @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
|
||||
*
|
||||
* @param array $data status data
|
||||
* @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)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit site
|
||||
*
|
||||
* @param array $data site data
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function sitesEdit(array $data)
|
||||
{
|
||||
if (!isset($data['code'])) {
|
||||
throw new InvalidArgumentException('Data must contain "code" parameter.');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest(
|
||||
'/reference/sites/' . $data['code'] . '/edit',
|
||||
Client::METHOD_POST,
|
||||
array(
|
||||
'site' => json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit store
|
||||
*
|
||||
* @param array $data site data
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function storesEdit(array $data)
|
||||
{
|
||||
if (!isset($data['code'])) {
|
||||
throw new InvalidArgumentException('Data must contain "code" parameter.');
|
||||
}
|
||||
|
||||
if (!isset($data['name'])) {
|
||||
throw new InvalidArgumentException('Data must contain "name" parameter.');
|
||||
}
|
||||
|
||||
return $this->client->makeRequest(
|
||||
'/reference/stores/' . $data['code'] . '/edit',
|
||||
Client::METHOD_POST,
|
||||
array(
|
||||
'store' => json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update CRM basic statistic
|
||||
*
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function statisticUpdate()
|
||||
{
|
||||
return $this->client->makeRequest('/statistic/update', Client::METHOD_GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current site
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSite()
|
||||
{
|
||||
return $this->siteCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set site
|
||||
*
|
||||
* @param string $site
|
||||
* @return void
|
||||
*/
|
||||
public function setSite($site)
|
||||
{
|
||||
$this->siteCode = $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill params by site value
|
||||
*
|
||||
* @param string $site
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
protected function fillSite($site, array $params)
|
||||
{
|
||||
if ($site) {
|
||||
$params['site'] = $site;
|
||||
} elseif ($this->siteCode) {
|
||||
$params['site'] = $this->siteCode;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
5
retailcrm/src/Vendor/RetailCrm/Exception/CurlException.php
vendored
Normal file
5
retailcrm/src/Vendor/RetailCrm/Exception/CurlException.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class CurlException extends RuntimeException
|
||||
{
|
||||
}
|
5
retailcrm/src/Vendor/RetailCrm/Exception/InvalidJsonException.php
vendored
Normal file
5
retailcrm/src/Vendor/RetailCrm/Exception/InvalidJsonException.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class InvalidJsonException extends DomainException
|
||||
{
|
||||
}
|
114
retailcrm/src/Vendor/RetailCrm/Http/Client.php
vendored
Normal file
114
retailcrm/src/Vendor/RetailCrm/Http/Client.php
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HTTP client
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
|
||||
protected $url;
|
||||
protected $defaultParameters;
|
||||
protected $retry;
|
||||
|
||||
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;
|
||||
$this->retry = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make HTTP request
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $method (default: 'GET')
|
||||
* @param array $parameters (default: array())
|
||||
* @param int $timeout
|
||||
* @param bool $verify
|
||||
* @param bool $debug
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function makeRequest(
|
||||
$path,
|
||||
$method,
|
||||
array $parameters = array(),
|
||||
$timeout = 30,
|
||||
$verify = false,
|
||||
$debug = false
|
||||
) {
|
||||
$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);
|
||||
|
||||
$url = $this->url . $path;
|
||||
|
||||
if (self::METHOD_GET === $method && sizeof($parameters)) {
|
||||
$url .= '?' . http_build_query($parameters);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify);
|
||||
|
||||
if (!$debug) {
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT_MS, (int) $timeout + ($this->retry * 2000));
|
||||
}
|
||||
|
||||
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 && in_array($errno, array(6, 7, 28, 34, 35)) && $this->retry < 3) {
|
||||
$errno = null;
|
||||
$error = null;
|
||||
$this->retry += 1;
|
||||
$this->makeRequest(
|
||||
$path,
|
||||
$method,
|
||||
$parameters,
|
||||
$timeout,
|
||||
$verify,
|
||||
$debug
|
||||
);
|
||||
}
|
||||
|
||||
if ($errno) {
|
||||
throw new CurlException($error, $errno);
|
||||
}
|
||||
|
||||
return new ApiResponse($statusCode, $responseBody);
|
||||
}
|
||||
|
||||
public function getRetry()
|
||||
{
|
||||
return $this->retry;
|
||||
}
|
||||
}
|
122
retailcrm/src/Vendor/RetailCrm/Response/ApiResponse.php
vendored
Normal file
122
retailcrm/src/Vendor/RetailCrm/Response/ApiResponse.php
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new BadMethodCallException('This activity not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new BadMethodCallException('This call not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->response[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (!isset($this->response[$offset])) {
|
||||
throw new InvalidArgumentException("Property \"$offset\" not found");
|
||||
}
|
||||
|
||||
return $this->response[$offset];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user