diff --git a/README.md b/README.md index 815dd21..0ad4287 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Обёртка для простого взаимодействия с Api AmoCRM -Текущая версия: 6.0.9.3 +Текущая версия: 7.0 ## Подключение @@ -27,7 +27,7 @@ getMessage()); } @@ -36,9 +36,9 @@ try { ## Возможности * Создание полного бэкапа црм, даже при отсутствии такой опции в тарифе -* Поиск контакта по телефону или почте. Даный метод можно использовать для поиска дублей. -* Поиск по произвольному запросу среди Контактов, Компаний и Сделок -* Получение списка любых сущностей с различной фильтрации +* Поиск контакта по телефону или почте. Даный метод можно использовать для поиска дублей +* Поиск по произвольному запросу среди Контактов, Компаний, Сделок, Примечаний и Задач +* Получение списка любых сущностей с различной фильтрацией * Создание, изменение и удаление контактов, сделок, компаний, заметок и задач * Прикрепление к контактам, сделкам и компаниям файлов, заметок и задач * Удобная работа с доп полями, без знания их id @@ -48,58 +48,49 @@ try { ## В ближайших плана * Возможность развёртования бэкапа * Добавлени возможности работы с новыми сущностями (Покупатели и тп) +* Добавление валидации к заданиям значений в пользовательским полям ## Благодарности -* Владислав Алаторцев — За уникальные методы работы без возможности создания файла для хранения куки, -прикрепления файлов и удаления сущностей +* Владислав Алаторцев — За уникальные методы прикрепления файлов и удаления сущностей а так же работе без возможности +создания файла для хранения куки +* Роман Маслеников — За поиски и исправление багов # Описание методов основных классов ## Класс AmoCRM * **AmoCRM::VERSION** — Текущая версия обёртки -* **AmoCRM::clearPhone($phone)** — Статичный метод отчистки телефона от лишних символов -* **new AmoCRM($domain, $userLogin, $userHash)** — Создане главного объекта класса AmoCRM. -Пытается произвести авторизацию. -* **isAuthorization()** — Проверяет текущую авторизацию -* **searchContact($phone, $email)** — Производит поиск по контактам. При этом не учитывает формат телефона (телефоны -начинающиеся с 7 или 8 считает разными). Возвращяет нумерованый массив из объектов класса Contact, где ключём будет -являть id контакта -* **searchCompany($query)** — Производит поиск по компаниям по произвольной строке. Возвращяет нумерованый массив из -объектов класса Company, где ключом будет являть id компании -* **searchLead($query)** — Производит поиск по сделкам по произвольной строке. Возвращяет нумерованый массив из -объектов класса Lead, где ключом будет являть id сделки +* **searchContactsByPhoneAndEmail($phone, $email)** — Поиск по контактам без учета формата телефона. +Телефоны начинающиеся с 7 или 8 считает разными. Возвращяет массив из объектов Contact, где ключи id контактов + +Поиск по Контактам, Компаниям, Сделкам, Задачам и Примечаниям ко всем сущностям отдельно +* searchContacts/searchCompanies/searchLeads/searchTasks +* getContactNotes/getCompanyNotes/getLeadNotes/getTaskNotes +**($query = null, $limit = 0,$offset = 0, $responsibleUsersIdOrName = array(), DateTime $modifiedSince = null, +$isRaw = false)** — Поиск по заданным сущностям. Все поля не обязательны. Если ничего не задано, то вернется полный +список всех сущностей. +$query - текст запроса. +$limit - количество сущностей в ответе. 0 = без ограничения +$offset - пропуск количества сущностей от начала +$responsibleUsersIdOrName - ответственные юзеры (имя или id). Если несколько то в массиве +$modifiedSince - измененный после даты и время заданным объектом DateTime +$isRaw - флаг получить "сырые" данные. Массивом как при обычном запросе к апи Важно!!! Все списки сортируются от самого ранее изменённого. Сортировку поменять нельзя =( -$limit = 0 — Отсутствие ограничения. - -Параметры: $query - произвольная строка, $limit - лимит количества объектов в результате, $offset - отступ от начала -списка, $responsibleUsersIdOrName - один элемент или массив ответственных (принимает как id так и имена или часть имени), -$modifiedSince - дата и время после которых контакт был изменён, $isRaw - если true то возвращает массив сырых данных, -а не массив объектов - -* **getContactsList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), -\DateTime $modifiedSince = null, $isRaw = false)** — Производит поиск по контактам и возвращает массив объектов -класса Contact -* **getLeadsList(--/так же/--)** — Производит поиск по сделкам и возвращает массив объектов класса Lead -* **getCompanyList(--/так же/--)** — Производит поиск по компаниям и возвращает массив объектов класса Company -* **getTasksList(--/так же/--)** — Производит поиск по задачам и возвращает массив объектов класса Task -* **getNotesContactList(--/так же/--)** — Производит поиск по заметкам у контатов и возвращает массив объектов класса Note -* **getNotesLeadList(--/так же/--)** — Производит поиск по заметкам у сделок и возвращает массив объектов класса Note -* **getNotesCompanyList(--/так же/--)** — Производит поиск по заметкам у компаний и возвращает массив объектов класса Note -* **getNotesTaskList(--/так же/--)** — Производит поиск по заметкам у задач(результат задачи) и возвращает массив объектов -класса Note - -## Абстрактный класс Base + +* **backup($directory)** — Создаёт полный бэкап всей црм в директории $directory. Возможны проблемы с лимитом памяти + +## Абстрактный класс BaseEntity На этом классе базируются все другие основные классы. Все методы присутствующие в нём можно использовать в других классах. * **__construct($id = null)** — Метод вызываемый при создании экземпляра класса. Можно передать id нужной сущность и тогда произойдёт загрузка данный из црм. Если не передавать id то будет создан пустой объект +* **getRaw()** — Получить сырые данные на основе сущности * **save()** — Сохраняет текущую сущность в црм * **delete()** — Удаляет текущую сущность в црм * **getId()** — Возвращает id сущность -* **getName()** — Возвращает наименование сущность +* **getName()** — Возвращает имя сущности * **setName($name)** — Изменяет имя на $name * **getResponsibleUserId()** — Возвращает id ответственного за сущность * **getResponsibleUserName()** — Возвращает имя ответственного за сущность @@ -112,63 +103,50 @@ $modifiedSince - дата и время после которых контакт * **getCreatedUserId()** — Возвращает id человека создавшего сущность * **getCreatedUserName()** — Возвращает имя человека создавшего сущность * **getLeadsId()** — Возвращает массив из id прикреплённых сделок +* **getLeads()** — Возвращает массив объектов Lead прикреплённых сделок * **addLead($lead)** — Прикрепляет к сущность сделку * **delLead($lead)** — Открепляет сделку от сущность * **getContactsId()** — Возвращает массив из id прикреплённых контактов +* **getContacts()** — Возвращает массив объектов Contact прикреплённых контактов * **addContactId($contact)** — Прикрепляет к сущность контакт * **delContactId($contact)** — Открепляет контакт от сущность * **getCompanyId()** — Возвращает id компании к которой привязана сущность -* **setCompany($company = null)** — Устанавливает компанию к которой будет привязана сущность +* **getCompany()** — Возвращает объект Company компании к которой привязана сущность +* **setCompany($company)** — Устанавливает компанию к которой будет привязана сущность * **getTags()** — Возвращает ассоциативный массив тэгов id => name * **addTag($tag)** — Добавляет тэг к сущности * **delTag($tag)** — Удаляет тэг у сущности * **getPhones()** — Возвращает нумерованый массив телефонов -* **addPhone($phone, $enum = 'OTHER')** — Добавляет телефон к сущности, не обязательны пораметр тип телефона, -по умолчанию "Другой". Проверяет имеется ли уже такой телефон у сущности и не добавляет дубликат - -Возможные варианты: WORK - Рабочий, WORKDD - Прямой, MOB - Мобильный, FAX - Факс, HOME - Домашний, OTHER - Другой -* **delPhone($phone)** — Удаляет телфон у сущности. Не учитывает формат телефона. Учитывает начинается телефон с 7 или 8 +* **addPhone($phone, $enum = CustomField::PHONE_OTHER)** — Добавляет телефон к сущности, не обязательны пораметр тип +телефона, по умолчанию "Другой". Проверяет имеется ли уже такой телефон у сущности и не добавляет дубликат. Возможные +варианты типов телефона находятся в константах CustomField::PHONE__ +* **delPhone($phone)** — Удаляет телефон у сущности. Не учитывает формат телефона. Учитывает начинается телефон с 7 или 8 * **getEmails()** — Возвращает нумерованый массив email'ов -* **addEmails($email, $enum = 'OTHER')** — Добавляет почту к сущности, не обязательны пораметр тип почты, по умолчанию -"Другой". Проверяет имеется ли уже такая почта у контакт и не добавляет дубликат - -Возможные варианты: WORK - Рабочая, PRIV - Личная, OTHER - Другая +* **addEmails($email, $enum = CustomField::EMAIL_OTHER)** — Добавляет почту к сущности, не обязательны пораметр тип +почты, по умолчанию "Другой". Проверяет имеется ли уже такая почта у контакт и не добавляет дубликат. Возможные варианты +типов почт находятся в константах CustomField::Email_ * **delEmail($email)** — Удаляет почту у сущности -* **addCustomField($name, $type)** — Создаёт кастомное поле у текущей сущности с именем $name и типом $type. - -Типы: -1. Обыное текстовое поле -2. Текстовое поля с возможностью записывать только цифры -3. Поле обозначающее только наличие или отсутствие свойства (например: "да"/"нет") -4. Поле типа список с возможностью выбора одного элемента -5. Поле типа список c возможностью выбора нескольких элементов списка -6. Поле типа дата в формате (Год-Мес-День Час:Мин:Сек) -7. Обычное текстовое поле предназначенное URL адресов -8. и 9. Поле содержащее большое количество текста -10. Поле типа переключатель -11. Поле короткой записи адреса -12. Поле адрес (в интерфейсе является набором из нескольких полей) -13. Поле типа дата поиск по которому осуществляется без учета года т.е. день рождение. -Формат (Год-Мес-День Час:Мин:Сек). Возвращает id поля -* **delCustomField($nameOrId)** — Удаляет кастомное поле у текущей сущности, принимает как id поля так и его имя -* **getCustomFieldValue($nameOrId)** — Возвращает значение кастомного поля в виде строки. Принимает его имя или id. -Если значений несколько, то они должны перечисляться через точку с запятоу (;) -* **getCustomFieldsValue()** — Возвращает все значения кастомных полей в виде ассоциативного массива -(имя поля => его значение). Если у поля несколько значений, то они перечесляются через точку с запятоу (;) -* **setCustomField($customFieldNameOrId, $value = null)** — Задаёт значение кастомного поля. Первым аргументов можно -передать как id поля, так и его название в црм. Если не передавать значение ($value) или задать его пустым, то при -сохранении поле в црм так же будет очищено. В поле типа мультисписок значения вносятся с разделителем точка с -запятой (;) т.е. "первое; второе; третье" +* **addCustomField($name, $type = CustomField::TYPE_TEXT, $enums = array())** — Создаёт кастомное поле у текущего типа +сущности с именем $name типом $type и если необходимо вариантами $enums. Возвращает id созданого поля. Типы полей +храняться в CustomField::TYPE_ +* **delCustomField($nameOrId)** — Удаляет кастомное поле у текущего типа сущности, принимает как id поля так и его имя +* **getCustomFieldValueStr($nameOrId)** — Возвращает значение кастомного поля в виде строки. Принимает его имя или id. +Разделитель значений точка с запятоу (;) +* **getCustomFieldValueArray($nameOrId)** — Возвращает значение кастомного поля в виде массива. Принимает его имя или id +* **setCustomFieldValue($customFieldNameOrId, $value, $subtype = null)** — Задаёт значение кастомного поля. +Первым аргументов можно передать как id поля, так и его название в црм. Если не передавать значение ($value) или задать +его пустым, то при сохранении поле в црм так же будет очищено. В поле типа мультисписок значения вносятся массивом. Для +типа адрес так же требуеться $subtype типы которого храняться в Value::SUBTYPE_ * **addNote($text)** — Добавляет примичание для текущей сущности -* **addSystemNote($text, $serviceName)** — Добавляет системное(нестираемое) примечание для текущей сущности -* **addTask($text, $responsibleUserIdOrName = null, $completeTill, $typeId = 3)** — Добавляет задачу для текущей +* **addNoteSystem($text, $serviceName)** — Добавляет системное(не удаляемое) примечание для текущей сущности +* **addNoteSmsOut($text, $phone)** — Добавляет примечание для текущей сущности типа Исходящее смс (на номер $phone) +* **addNoteSmsIn($text, $phone)** — Добавляет примечание для текущей сущности типа Входящее смс (с номера $phone) +* **addTask($text, $responsibleUserIdOrName = null, DateTime $completeTill = null, $typeId = 3)** — Добавляет задачу для текущей сущности. $text - текст задачи. $responsibleUserIdOrName(не обязательный) - ответственный, принимает как id так и имя, если не установлен то ответственный тот же что и у текущей сущность. $completeTill(не обязательный) - дата и время, в виде объекта класса DateTime, до которого нужно завершить задачу, если не указан то время устанавливается текущее. -$typeId(не обязательный) - тип задачи см. варианты в црм, принимает только имя типа, если не установлен принимает -тип 3 - письмо. +$typeId(не обязательный) - тип задачи см. варианты в црм, если не установлен принимает тип 3 - письмо. * **addFile($pathToFile)** — прикрепляет файл к сущность (Сделка, Контакт или Компания). $pathToFile - путь до файла -* **backup($directory)** — Создаёт полный бэкап всей црм в директории $directory. Возможны проблемы с лимитом памяти ## Классы Contact и Company @@ -183,9 +161,12 @@ $typeId(не обязательный) - тип задачи см. вариан * **getPipelineName()** — Возвращает название воронки * **getStatusId()** — Возвращает id статуса * **getStatusName()** — Возвращает название статуса -* **setPipelineAndStatus($idOrNamePipeline, $idOrNameStatus)** — Задаёт воронку и статус. Принимает id либо название +* **setPipeline($idOrNamePipeline)** — Задаёт воронку. Принимает id либо название +* **setStatus($idOrNameStatus, $idOrNamePipeline = null)** — Задаёт статус в воронке $idOrNamePipeline, если не указано +в текущей. Принимает id либо название из црм, как воронки так и статуса * **getMainContactId()** — Возвращает id основного контакта +* **getMainContact()** — Возвращает объект Contact основного контакта * **setMainContact($contact)** — Задаёт основной контакт * **isClosed()** — Возвращает true если сделка закрыта и false в противном случае @@ -216,7 +197,7 @@ $companies - необязательный параметр, массив объ * **save()** — Сохраняет "неразобранное" в црм -## Классы хэлперы Config, Info, CustomField, Value, Note и Task +## Классы хэлперы Config, CustomField, Value, Note и Task Созданы как вспомогательные по этому описывать их не буду) # Примеры @@ -226,7 +207,7 @@ $companies - необязательный параметр, массив объ searchContact('79998887766', 'test@test.ru'); //Ищем контакт по телефону и почте + $contacts = $amo->searchContactsByPhoneAndEmail('79998887766', 'test@test.ru'); //Ищем контакт по телефону и почте $contact = current($contacts); //Берём первый найденый контакт $contact->setName("{$contact->getName()} лучший") //Меняем имя дописывая в текущее строчку ->addPhone('78889998887766', 'MOB') //Добавляем мобильный телефон @@ -282,18 +263,18 @@ try { $amo = new \DrillCoder\AmoCRM_Wrap\AmoCRM('test', 'test@test.com', '8a66666666b3494179da07abc74bfd49'); $lead = new \DrillCoder\AmoCRM_Wrap\Lead(); $lead->setName("Заявка с формы '$form'") - ->setCustomField('roistat', isset($_COOKIE['roistat_visit']) ? $_COOKIE['roistat_visit'] : null) - ->setCustomField('roistat-marker', isset($_COOKIE['roistat_marker']) ? $_COOKIE['roistat_marker'] : 'Прямой визит') - ->setCustomField('Форма захвата', $form) - ->setCustomField('utm_source', $_COOKIE['utm_source']) - ->setCustomField('utm_medium', $_COOKIE['utm_medium']) - ->setCustomField('utm_campaign', $_COOKIE['utm_campaign']) - ->setCustomField('utm_term', $_COOKIE['utm_term']) - ->setCustomField('utm_content', $_COOKIE['utm_content']) + ->setCustomFieldValue('roistat', isset($_COOKIE['roistat_visit']) ? $_COOKIE['roistat_visit'] : null) + ->setCustomFieldValue('roistat-marker', isset($_COOKIE['roistat_marker']) ? $_COOKIE['roistat_marker'] : 'Прямой визит') + ->setCustomFieldValue('Форма захвата', $form) + ->setCustomFieldValue('utm_source', $_COOKIE['utm_source']) + ->setCustomFieldValue('utm_medium', $_COOKIE['utm_medium']) + ->setCustomFieldValue('utm_campaign', $_COOKIE['utm_campaign']) + ->setCustomFieldValue('utm_term', $_COOKIE['utm_term']) + ->setCustomFieldValue('utm_content', $_COOKIE['utm_content']) ->setResponsibleUser($responsibleUserId) ->save() ->addNote($comment); - $contacts = $amo->searchContact($phone, $email); + $contacts = $amo->searchContactsByPhoneAndEmail($phone, $email); if (!empty($contacts)) { $contact = current($contacts); } else { diff --git a/autoload.php b/autoload.php index 3816d59..adfd131 100644 --- a/autoload.php +++ b/autoload.php @@ -12,29 +12,28 @@ * @param string $class */ function ($class) { - $ns = 'DrillCoder\AmoCRM_Wrap'; $prefixes = array( - "{$ns}\\" => array( + 'DrillCoder\AmoCRM_Wrap\\' => array( __DIR__ . '/src', __DIR__ . '/tests', ), ); foreach ($prefixes as $prefix => $dirs) { - $prefix_len = strlen($prefix); - if (substr($class, 0, $prefix_len) !== $prefix) { + $prefix_len = mb_strlen($prefix); + if (mb_strpos($class, $prefix) !== 0) { continue; } - $class = substr($class, $prefix_len); + $class = mb_substr($class, $prefix_len); $part = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'; foreach ($dirs as $dir) { $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); $file = $dir . DIRECTORY_SEPARATOR . $part; if (is_readable($file)) { require $file; + return; } } } - }); - - + } +); \ No newline at end of file diff --git a/composer.json b/composer.json index 557a3c0..3449045 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "drillcoder/amocrm_wrap", "description": "Обёртка для простого взаимодействия с Api AmoCRM", - "version": "6.0.9.3", + "version": "7.0", "keywords": [ "drillcoder", "amo", @@ -18,8 +18,8 @@ ], "license": "MIT", "require": { - "php": ">=5.3.0", - "ext-curl": "*", + "php": ">=5.3", + "ext-curl": ">=7.34", "ext-json": "*", "ext-mbstring": "*" }, diff --git a/src/AmoCRM.php b/src/AmoCRM.php index de103a5..0ddbc84 100644 --- a/src/AmoCRM.php +++ b/src/AmoCRM.php @@ -9,129 +9,129 @@ namespace DrillCoder\AmoCRM_Wrap; +use DateTime; use DrillCoder\AmoCRM_Wrap\Helpers\Config; -use DrillCoder\AmoCRM_Wrap\Helpers\Info; +use stdClass; /** * Class Amo * @package DrillCoder\AmoCRM_Wrap - * @version Version 6.0.9.3 + * + * @version Version 7.0 */ -class AmoCRM +class AmoCRM extends Base { /** * Wrap Version */ - const VERSION = '6.0.9.3'; + const VERSION = '7.0'; + + /** + * @var int + */ + private static $phoneFieldId; + + /** + * @var int + */ + private static $emailFieldId; + + /** + * @var array + */ + private static $phoneEnums = array(); + + /** + * + * @var array + */ + private static $emailEnums = array(); + + /** + * @var array + */ + private static $users = array(); + /** - * @var string + * @var array */ - private static $domain; + private static $contactCustomFields = array(); + + /** + * @var array + */ + private static $contactCustomFieldsEnums = array(); + + /** + * @var array + */ + private static $leadCustomFields = array(); + + /** + * @var array + */ + private static $leadCustomFieldsEnums = array(); + + /** + * @var array + */ + private static $companyCustomFields = array(); + /** - * @var string + * @var array */ - private static $userLogin; + private static $companyCustomFieldsEnums = array(); + /** - * @var string + * @var array */ - private static $userAPIKey; + private static $pipelinesName = array(); + /** - * @var bool + * @var array */ - private static $authorization; + private static $pipelinesStatusesName = array(); + /** - * @var Info + * @var array */ - private static $info; + private static $pipelinesStatusesColor = array(); + + /** + * @var array + */ + private static $taskTypes = array(); /** - * Amo constructor. * @param string $domain * @param string $userLogin * @param string $userAPIKey + * * @throws AmoWrapException */ public function __construct($domain, $userLogin, $userAPIKey) { - self::$domain = $domain; - self::$userLogin = $userLogin; - self::$userAPIKey = $userAPIKey; - self::$authorization = true; - $user = array( + Base::$domain = $domain; + Base::$userLogin = $userLogin; + Base::$userAPIKey = $userAPIKey; + + $userData = array( 'USER_LOGIN' => $userLogin, 'USER_HASH' => $userAPIKey ); - $res = self::cUrl('private/api/auth.php?type=json', $user); - self::$authorization = $res->response->auth; - if (self::$authorization) { - $res = AmoCRM::cUrl('api/v2/account?with=custom_fields,users,pipelines,task_types'); - self::$info = new Info($res->_embedded); + $result = Base::cUrl('private/api/auth.php?type=json', $userData); + if ($result !== null && isset($result->response->auth) && $result->response->auth) { + Base::$authorization = $result->response->auth; } else { - throw new AmoWrapException('Данные для авторизации не верны'); + throw new AmoWrapException('Не удалось авторизоваться'); } - } - /** - * @param string $url - * @param array $data - * @param \DateTime|null $modifiedSince - * @param bool $ajax - * @return mixed|null - * @throws AmoWrapException - */ - public static function cUrl($url, $data = array(), \DateTime $modifiedSince = null, $ajax = false) - { - if (self::$authorization) { - $url = 'https://' . self::$domain . '.amocrm.ru/' . $url; - $isUnsorted = stripos($url, 'incoming_leads') !== false; - if ($isUnsorted) { - $url .= '&login=' . self::$userLogin . '&api_key=' . self::$userAPIKey; - } else { - if (strripos($url, '?') === false) { - $url .= '?'; - } - $url .= '&USER_LOGIN=' . self::$userLogin . '&USER_HASH=' . self::$userAPIKey; - } - $curl = curl_init(); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_HEADER, false); - curl_setopt($curl, CURLOPT_USERAGENT, 'amoCRM-API-client/1.0'); - curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); - $headers = array(); - if (!empty($data)) { - curl_setopt($curl, CURLOPT_POST, true); - if ($ajax) { - $headers[] = 'X-Requested-With: XMLHttpRequest'; - } else { - if ($isUnsorted) { - $data = http_build_query($data); - } else { - $headers[] = 'Content-Type: application/json'; - $data = json_encode($data); - } - } - curl_setopt($curl, CURLOPT_POSTFIELDS, $data); - } - if (!empty($modifiedSince)) { - $headers[] = 'IF-MODIFIED-SINCE: ' . $modifiedSince->format(\DateTime::RFC1123); - } - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); - $out = curl_exec($curl); - curl_close($curl); - $response = json_decode($out); - if ($response !== null) { - if (isset($response->response->error)) { - throw new AmoWrapException($response->response->error); - } - return $response; - } + $result = Base::cUrl('api/v2/account?with=custom_fields,users,pipelines,task_types'); + if ($result !== null && isset($result->_embedded)) { + self::loadInfo($result->_embedded); } else { - throw new AmoWrapException('Требуется авторизация'); + throw new AmoWrapException('Не удалось получить данные аккаунта'); } - return null; } /** @@ -139,385 +139,720 @@ public static function cUrl($url, $data = array(), \DateTime $modifiedSince = nu */ public static function isAuthorization() { - return self::$authorization; + return Base::$authorization; } /** - * @return Info - * @throws AmoWrapException + * @return int */ - public static function getInfo() + public static function getPhoneFieldId() { - if (self::$info !== null) { - return self::$info; - } + return self::$phoneFieldId; + } - throw new AmoWrapException('Требуется авторизация'); + /** + * @return int + */ + public static function getEmailFieldId() + { + return self::$emailFieldId; } /** - * @param $phone - * @param $email - * @return Contact[] - * @throws AmoWrapException + * @return array */ - public function searchContact($phone, $email = null) + public static function getPhoneEnums() { - $link = 'api/v2/contacts/?query='; - $contacts = array(); - if (!empty($phone)) { - $phone = self::clearPhone($phone); - $linkPhone = $link . $phone; - $res = self::cUrl($linkPhone); - if ($res !== null) { - foreach ($res->_embedded->items as $raw) { - $contact = new Contact(); - $contact->loadInRaw($raw); - if (in_array($phone, $contact->getPhones())) { - $contacts[$contact->getId()] = $contact; - } - } - } - } - if (!empty($email)) { - $linkEmail = $link . $email; - $res = self::cUrl($linkEmail); - if ($res !== null) { - foreach ($res->_embedded->items as $raw) { - $contact = new Contact(); - $contact->loadInRaw($raw); - if (in_array($email, $contact->getEmails())) { - $contacts[$contact->getId()] = $contact; - } - } - } - } - return $contacts; + return self::$phoneEnums; } /** - * @param string $phone - * @return integer + * @return array + */ + public static function getEmailEnums() + { + return self::$emailEnums; + } + + /** + * @return array + */ + public static function getUsers() + { + return self::$users; + } + + /** + * @return array + */ + public static function getPipelinesName() + { + return self::$pipelinesName; + } + + /** + * @param int $pipelineId + * + * @return array + */ + public static function getStatusesName($pipelineId) + { + return self::$pipelinesStatusesName[$pipelineId]; + } + + /** + * @param string $type + * + * @return array */ - public static function clearPhone($phone) + public static function getCustomFields($type) { - return preg_replace("/[^0-9]/", '', $phone); + $attribute = "{$type}CustomFields"; + + return self::$$attribute; } /** - * @param string $query - * @return Company[] + * @param string $type + * + * @return array + */ + public static function getCustomFieldsEnums($type) + { + $attribute = "{$type}CustomFieldsEnums"; + + return self::$$attribute; + } + + /** + * @param int|string $pipelineIdOrName + * + * @return int * @throws AmoWrapException */ - public function searchCompany($query) + public static function searchPipelineId($pipelineIdOrName) { - $res = AmoCRM::cUrl("api/v2/companies?query=$query"); - $companies = array(); - if ($res !== null) { - foreach ($res->_embedded->items as $raw) { - $company = new Company(); - $company->loadInRaw($raw); - $companies[$company->getId()] = $company; + if (isset(self::$pipelinesName[$pipelineIdOrName])) { + return $pipelineIdOrName; + } + + foreach (self::$pipelinesName as $id => $name) { + if (mb_stripos($name, $pipelineIdOrName) !== false) { + return $id; } } - return $companies; + + throw new AmoWrapException('Воронка не найден'); } /** - * @param string $query - * @return Lead[] + * @param int|string $pipelineIdOrName + * @param int|string $statusIdOrName + * + * @return int + * * @throws AmoWrapException */ - public function searchLead($query) + public static function searchStatusId($pipelineIdOrName, $statusIdOrName) { - $res = AmoCRM::cUrl("api/v2/leads?query=$query"); - $leads = array(); - if ($res !== null) { - foreach ($res->_embedded->items as $raw) { - $lead = new Lead(); - $lead->loadInRaw($raw); - $leads[$lead->getId()] = $lead; + $pipelineId = self::searchPipelineId($pipelineIdOrName); + + if (isset(self::$pipelinesStatusesName[$pipelineId][$statusIdOrName])) { + return $statusIdOrName; + } + + foreach (self::$pipelinesStatusesName[$pipelineId] as $id => $name) { + if (mb_stripos($name, $statusIdOrName) !== false) { + return $id; } } - return $leads; + + throw new AmoWrapException('Статус не найден'); } /** - * @param string $directory + * @param int|string $pipelineIdOrName + * @param int|string $statusIdOrName + * + * @return string + * * @throws AmoWrapException */ - public function backup($directory) + public static function searchStatusColor($pipelineIdOrName, $statusIdOrName) { - $this->createBackupFile($directory, 'contacts.backup', $this->getContactsList(null, 0, - 0, array(), null, true)); - $this->createBackupFile($directory, 'leads.backup', $this->getLeadsList(null, 0, 0, - array(), null, true)); - $this->createBackupFile($directory, 'company.backup', $this->getCompanyList(null, 0, 0, - array(), null, true)); - $this->createBackupFile($directory, 'tasks.backup', $this->getTasksList(null, 0, 0, - array(), null, true)); - $this->createBackupFile($directory, 'notes-contacts.backup', $this->getNotesContactList(null, - 0, 0, array(), null, true)); - $this->createBackupFile($directory, 'notes-leads.backup', $this->getNotesLeadList(null, 0, - 0, array(), null, true)); - $this->createBackupFile($directory, 'notes-company.backup', $this->getNotesCompanyList(null, - 0, 0, array(), null, true)); - $this->createBackupFile($directory, 'notes-tasks.backup', $this->getNotesTaskList(null, 0, - 0, array(), null, true)); + $pipelineId = self::searchPipelineId($pipelineIdOrName); + $statusId = self::searchStatusId($pipelineId, $statusIdOrName); + + return self::$pipelinesStatusesColor[$pipelineId][$statusId]; } /** - * @param string $directory - * @param string $nameFile - * @param mixed $var + * @param int|string $userIdOrName + * + * @return int + * + * @throws AmoWrapException */ - private function createBackupFile($directory, $nameFile, $var) + public static function searchUserId($userIdOrName) { - if (!is_dir($directory)) { - mkdir($directory, 0777, true); + if (isset(self::$users[$userIdOrName])) { + return $userIdOrName; } - $f = fopen("$directory/$nameFile", 'w+'); - fwrite($f, serialize($var)); - fclose($f); + + foreach (self::$users as $id => $name) { + if (mb_stripos($name, $userIdOrName) !== false) { + return $id; + } + } + + throw new AmoWrapException('Пользователь не найден'); } /** - * @param null $query - * @param int $limit - * @param int $offset - * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Contact[]|\stdClass[] + * @param $taskIdOrName + * + * @return int + * * @throws AmoWrapException */ - public function getContactsList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public static function searchTaskType($taskIdOrName) { - return $this->getList('Contact', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + if (isset(self::$taskTypes[$taskIdOrName])) { + return $taskIdOrName; + } + + foreach (self::$taskTypes as $id => $name) { + if (mb_stripos($name, $taskIdOrName) !== false) { + return $id; + } + } + + throw new AmoWrapException('Не удалось найти тип задачи'); } /** - * @param string $type - * @param string $query - * @param integer $limit - * @param integer $offset - * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Company[]|Contact[]|Lead[]|\stdClass[] + * @param string $phone + * @param string $email + * + * @return Contact[] + * * @throws AmoWrapException */ - private function getList($type, $query, $limit, $offset, $responsibleUsersIdOrName, \DateTime $modifiedSince, $isRaw) + public function searchContactsByPhoneAndEmail($phone, $email = null) { - $offset = (int)$offset; - $limit = (int)$limit; - switch ($type) { - case 'Company': - $className = $type; - $typeForUrlType = 'company'; - break; - case 'Contact': - $className = $type; - $typeForUrlType = 'contact'; - break; - case 'Lead': - $className = $type; - break; - case 'Note-Contact': - $className = 'Note'; - $typeForUrlType = 'contact'; - break; - case 'Note-Lead': - $className = 'Note'; - $typeForUrlType = 'lead'; - break; - case 'Note-Company': - $className = 'Note'; - $typeForUrlType = 'company'; - break; - case 'Note-Task': - $className = 'Note'; - $typeForUrlType = 'task'; - break; - case 'Task': - $className = $type; - break; - } - if (isset($className)) { - $typeObj = "DrillCoder\\AmoCRM_Wrap\\$className"; - $config = new Config(); - $typeForUrl = $config->{strtolower($className)}['url']; - $url = "api/v2/$typeForUrl?"; - if (!empty($query)) { - $url .= "&query=$query"; - } - if (!empty($typeForUrlType)) { - $url .= "&type=$typeForUrlType"; - } - if (!empty($responsibleUsersIdOrName)) { - if (is_array($responsibleUsersIdOrName)) { - foreach ($responsibleUsersIdOrName as $responsibleUserIdOrName) { - $responsibleUserId = AmoCRM::$info->getUserIdFromIdOrName($responsibleUserIdOrName); - $url .= "&responsible_user_id[]=$responsibleUserId"; + $resultContacts = array(); + + $phone = Base::onlyNumbers($phone); + $contacts = $this->searchContacts($phone); + if (count($contacts) > 0) { + foreach ($contacts as $contact) { + foreach ($contact->getPhones() as $value) { + if (mb_strpos(Base::onlyNumbers($value), Base::onlyNumbers($phone)) !== false) { + $resultContacts[$contact->getId()] = $contact; } - } else { - $responsibleUserId = AmoCRM::$info->getUserIdFromIdOrName($responsibleUsersIdOrName); - $url .= "&responsible_user_id=$responsibleUserId"; } } - $totalCount = $limit; - $isNext = true; - $result = array(); - $i = 0; - while ($isNext) { - $i++; - if ($i > 15) - break; - if ($totalCount > 500 || $limit == 0) { - $requestLimit = 500; - } else { - $requestLimit = $totalCount; - } - $res = AmoCRM::cUrl($url . "&limit_rows=$requestLimit&limit_offset=$offset", null, $modifiedSince); - if ($res === null) { - break; - } else { - $result = array_merge($result, $res->_embedded->items); - if ($limit != 0) { - $totalCount -= count($res->_embedded->items); - if ($totalCount <= 0) { - break; - } + } + + $contacts = $this->searchContacts($email); + if (count($contacts) > 0) { + foreach ($contacts as $contact) { + foreach ($contact->getEmails() as $value) { + if (mb_strpos($value, $email) !== false) { + $resultContacts[$contact->getId()] = $contact; } - $offset += 500; - } - } - if ($isRaw) { - return $result; - } else { - $baseObjects = array(); - foreach ($result as $baseRaw) { - /** @var Company|Contact|Lead|Note|Task $baseObj */ - $baseObj = new $typeObj(); - $baseObj->loadInRaw($baseRaw); - $baseObjects[] = $baseObj; } - return $baseObjects; } } - return array(); + + return $resultContacts; } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param string|null $query + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Lead[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Contact[]|stdClass[] + * * @throws AmoWrapException */ - public function getLeadsList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function searchContacts( + $query = null, + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Lead', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Contact', + $query, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param string|null $query + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Company[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Company[]|stdClass[] + * * @throws AmoWrapException */ - public function getCompanyList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function searchCompanies( + $query = null, + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Company', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Company', + $query, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param string|null $query + * @param string|int|null $pipelineIdOrName + * @param array|string|int $statuses + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Task[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Lead[]|stdClass[] + * * @throws AmoWrapException */ - public function getTasksList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function searchLeads( + $query = null, + $pipelineIdOrName = null, + $statuses = array(), + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Task', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Lead', + $query, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw, + $pipelineIdOrName, + $statuses + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param string|null $query + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Note[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Task[]|stdClass[] + * * @throws AmoWrapException */ - public function getNotesContactList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function searchTasks( + $query = null, + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Note-Contact', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Task', + $query, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Note[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Note[]|stdClass[] + * * @throws AmoWrapException */ - public function getNotesLeadList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function getContactNotes( + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Note-Lead', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Note-Contact', + null, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Note[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Note[]|stdClass[] + * * @throws AmoWrapException */ - public function getNotesCompanyList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function getCompanyNotes( + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) { - return $this->getList('Note-Company', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + return $this->search( + 'Note-Company', + null, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); } /** - * @param null $query - * @param int $limit - * @param int $offset + * @param int $limit + * @param int $offset * @param array|string|int $responsibleUsersIdOrName - * @param \DateTime|null $modifiedSince - * @param bool $isRaw - * @return Note[]|\stdClass[] + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Note[]|stdClass[] + * + * @throws AmoWrapException + */ + public function getLeadNotes( + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) + { + return $this->search( + 'Note-Lead', + null, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); + } + + /** + * @param int $limit + * @param int $offset + * @param array|string|int $responsibleUsersIdOrName + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * + * @return Note[]|stdClass[] + * + * @throws AmoWrapException + */ + public function getTaskNotes( + $limit = 0, + $offset = 0, + $responsibleUsersIdOrName = array(), + DateTime $modifiedSince = null, + $isRaw = false + ) + { + return $this->search( + 'Note-Task', + null, + $limit, + $offset, + $responsibleUsersIdOrName, + $modifiedSince, + $isRaw + ); + } + + /** + * @param string $directory + * + * @throws AmoWrapException + */ + public function backup($directory) + { + $this->createBackupFile( + $directory, + 'contacts.backup', + $this->searchContacts(null, 0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'company.backup', + $this->searchCompanies(null, 0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'leads.backup', + $this->searchLeads(null, null, null, 0, 0, null, null, true) + ); + $this->createBackupFile( + $directory, + 'tasks.backup', + $this->searchTasks(null, 0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'notes-contacts.backup', + $this->getContactNotes(0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'notes-company.backup', + $this->getCompanyNotes(0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'notes-leads.backup', + $this->getLeadNotes(0, 0, array(), null, true) + ); + $this->createBackupFile( + $directory, + 'notes-tasks.backup', + $this->getTaskNotes(0, 0, array(), null, true) + ); + } + + /** + * @param string $directory + * @param string $nameFile + * @param mixed $data + * + * @throws AmoWrapException + */ + private function createBackupFile($directory, $nameFile, $data) + { + if (!mkdir($directory, 0777, true) && !is_dir($directory)) { + throw new AmoWrapException("Директория '$directory' не может быть создана"); + } + $f = fopen("$directory/$nameFile", 'wb+'); + fwrite($f, serialize($data)); + fclose($f); + } + + /** + * @param string $entityName + * @param string $query + * @param integer $limit + * @param integer $offset + * @param array|string|int $responsibleUsers + * @param DateTime|null $modifiedSince + * @param bool $isRaw + * @param int|string|null $pipelineIdOrName + * @param array $statuses + * + * @return Company[]|Contact[]|Lead[]|Task[]|Note[]|stdClass[] + * * @throws AmoWrapException */ - public function getNotesTaskList($query = null, $limit = 0, $offset = 0, $responsibleUsersIdOrName = array(), - \DateTime $modifiedSince = null, $isRaw = false) + public function search( + $entityName, + $query = null, + $limit = 0, + $offset = 0, + $responsibleUsers = array(), + DateTime $modifiedSince = null, + $isRaw = false, + $pipelineIdOrName = null, + $statuses = array() + ) { - return $this->getList('Note-Task', $query, $limit, $offset, $responsibleUsersIdOrName, $modifiedSince, $isRaw); + $offset = (int)$offset; + $limit = (int)$limit; + + if ($responsibleUsers === null) { + $responsibleUsers = array(); + } elseif (!is_array($responsibleUsers)) { + $responsibleUsers = array($responsibleUsers); + } + + if ($statuses === null) { + $statuses = array(); + } elseif (!is_array($statuses)) { + $statuses = array($statuses); + } + + $options = explode('-', $entityName); + $className = $options[0]; + $type = isset($options[1]) ? mb_strtolower($options[1]) : null; + + $entityFulName = __NAMESPACE__ . "\\$className"; + $attribute = mb_strtolower($className); + + $url = 'api/v2/' . (Config::$$attribute)['url'] . '?'; + if ($query !== null) { + $url .= "&query=$query"; + } + if ($type !== null) { + $url .= "&type=$type"; + } + + if ($pipelineIdOrName !== null && count($statuses) > 0) { + foreach ($statuses as $statusIdOrName) { + $statusId = self::searchStatusId($pipelineIdOrName, $statusIdOrName); + $url .= "&status[]=$statusId"; + } + } + + if (count($responsibleUsers) > 0) { + foreach ($responsibleUsers as $responsibleUserIdOrName) { + $responsibleUserId = self::searchUserId($responsibleUserIdOrName); + $url .= "&responsible_user_id[]=$responsibleUserId"; + } + } + + $totalCount = $limit; + $results = array(); + + while (true) { + if ($totalCount > 500 || $limit === 0) { + $limitRows = 500; + } else { + $limitRows = $totalCount; + } + + $res = Base::cUrl($url . "&limit_rows=$limitRows&limit_offset=$offset", array(), $modifiedSince); + if ($res === null) { + break; + } + + $results[] = $res->_embedded->items; + if ($limit !== 0) { + $totalCount -= count($res->_embedded->items); + if ($totalCount <= 0) { + break; + } + } + $offset += 500; + } + + $resultRaw = array(); + if ($isRaw) { + foreach ($results as $result) { + foreach ($result as $baseRaw) { + if ($isRaw) { + $resultRaw[] = $baseRaw; + } + } + } + + return $resultRaw; + } + + $entities = array(); + foreach ($results as $result) { + foreach ($result as $baseRaw) { + /** @var BaseEntity $entity */ + $entity = new $entityFulName(); + $entity->loadInRaw($baseRaw); + $entities[] = $entity; + } + } + + return $entities; + } + + /** + * @param stdClass $data + */ + private static function loadInfo($data) + { + foreach ($data->users as $user) { + self::$users[$user->id] = $user->name; + } + foreach ($data->custom_fields->contacts as $field) { + self::$contactCustomFields[$field->id] = $field->name; + if ($field->name === 'Телефон' && $field->is_system) { + self::$phoneFieldId = $field->id; + self::$phoneEnums = array_flip(json_decode(json_encode($field->enums), true)); + } + if ($field->name === 'Email' && $field->is_system) { + self::$emailFieldId = $field->id; + self::$emailEnums = array_flip(json_decode(json_encode($field->enums), true)); + } + if ($field->field_type === 4 || $field->field_type === 5) { + self::$contactCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); + } + } + foreach ($data->custom_fields->leads as $field) { + self::$leadCustomFields[$field->id] = $field->name; + if ($field->field_type === 4 || $field->field_type === 5) { + self::$leadCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); + } + } + foreach ($data->custom_fields->companies as $field) { + self::$companyCustomFields[$field->id] = $field->name; + if ($field->field_type === 4 || $field->field_type === 5) { + self::$companyCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); + } + } + foreach ($data->pipelines as $pipeline) { + self::$pipelinesName[$pipeline->id] = $pipeline->name; + foreach ($pipeline->statuses as $status) { + self::$pipelinesStatusesName[$pipeline->id][$status->id] = $status->name; + self::$pipelinesStatusesColor[$pipeline->id][$status->id] = $status->color; + } + } + foreach ($data->task_types as $type) { + self::$taskTypes[$type->id] = $type->name; + } } } \ No newline at end of file diff --git a/src/AmoWrapException.php b/src/AmoWrapException.php index aba6965..9420a05 100644 --- a/src/AmoWrapException.php +++ b/src/AmoWrapException.php @@ -15,11 +15,4 @@ */ class AmoWrapException extends \Exception { - /** - * @param string $message - */ - public function __construct($message) - { - $this->message = $message; - } } \ No newline at end of file diff --git a/src/Base.php b/src/Base.php index 6c0e951..da4e98a 100644 --- a/src/Base.php +++ b/src/Base.php @@ -2,15 +2,15 @@ /** * Created by PhpStorm. * User: DrillCoder - * Date: 12.09.17 - * Time: 11:55 + * Date: 2019-01-04 + * Time: 01:13 */ namespace DrillCoder\AmoCRM_Wrap; +use DateTime; use DrillCoder\AmoCRM_Wrap\Helpers\Config; -use DrillCoder\AmoCRM_Wrap\Helpers\CustomField; -use DrillCoder\AmoCRM_Wrap\Helpers\Value; +use stdClass; /** * Class Base @@ -18,1017 +18,94 @@ */ abstract class Base { - /** - * @var int - */ - protected $id; - /** - * @var string - */ - protected $name; - /** - * @var Value[] - */ - protected $phones = array(); - /** - * @var Value[] - */ - protected $emails = array(); - /** - * @var int - */ - protected $createdUserId; - /** - * @var \DateTime - */ - protected $dateCreate; - /** - * @var \DateTime - */ - protected $dateUpdate; - /** - * @var int - */ - protected $userIdUpdate; - /** - * @var int - */ - protected $responsibleUserId; - /** - * @var int - */ - protected $companyId; - /** - * @var int[] - */ - protected $leadsId = array(); - /** - * @var int[] - */ - protected $contactsId = array(); - /** - * @var string[] - */ - protected $tags = array(); - /** - * @var CustomField[] - */ - protected $customFields = array(); - /** - * @var int|string - */ - protected $type; - /** - * @var int - */ - protected $elementId; - /** - * @var int - */ - protected $elementType; /** * @var string */ - protected $text; - /** - * @var array - */ - protected $unlink; - /** - * @var array - */ - protected $config; - - /** - * Base constructor. - * @param int|null $amoId - * @throws AmoWrapException - */ - public function __construct($amoId = null) - { - $classNameArray = explode('\\', get_class($this)); - $className = strtolower(array_pop($classNameArray)); - $config = new Config(); - $this->config = $config->$className; - if (AmoCRM::isAuthorization()) { - if (!empty($amoId)) { - $amoId = (int)$amoId; - $this->loadInAmoId($amoId); - } - } - } - - /** - * @param int $id - * @return Base|Company|Contact|Lead|Note|Task - * @throws AmoWrapException - */ - protected function loadInAmoId($id) - { - if (!empty($id)) { - $typeUrl = $this->config['url']; - $link = "api/v2/$typeUrl?id=$id"; - if ($this->config['info'] == 'Note') { - $type = null; - switch ($this->elementType) { - case 1: - $type = 'contact'; - break; - case 2: - $type = 'lead'; - break; - case 3: - $type = 'company'; - break; - } - $link .= "&type=$type"; - } - $res = AmoCRM::cUrl($link); - if (!empty($res->_embedded->items[0])) { - return $this->loadInRaw($res->_embedded->items[0]); - } - } - throw new AmoWrapException('Не удалось загрузить сущность'); - } - - /** - * @param \stdClass|array $stdClass - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function loadInRaw($stdClass) - { - $stdClass = json_decode(json_encode($stdClass)); - if (!empty($stdClass->id)) { - $this->id = (int)$stdClass->id; - if (isset($stdClass->name)) - $this->name = $stdClass->name; - $this->createdUserId = (int)$stdClass->created_by; - $dateCreate = new \DateTime(); - $dateCreate->setTimestamp($stdClass->created_at); - $this->dateCreate = $dateCreate; - $dateUpdate = new \DateTime(); - $dateUpdate->setTimestamp($stdClass->updated_at); - $this->dateUpdate = $dateUpdate; - $this->responsibleUserId = (int)$stdClass->responsible_user_id; - $this->userIdUpdate = isset($stdClass->updated_by) ? (int)$stdClass->updated_by : null; - $this->companyId = isset($stdClass->company->id) ? (int)$stdClass->company->id : null; - $this->leadsId = isset($stdClass->leads->id) ? $stdClass->leads->id : null; - $this->contactsId = isset($stdClass->contacts->id) ? $stdClass->contacts->id : null; - if (isset($stdClass->tags) && is_array($stdClass->tags)) { - foreach ($stdClass->tags as $tag) { - $this->tags[$tag->id] = $tag->name; - } - } - if (isset($stdClass->custom_fields) && is_array($stdClass->custom_fields)) { - foreach ($stdClass->custom_fields as $custom_field) { - $customField = CustomField::loadInRaw($custom_field); - if ($customField->getIsSystem() && $customField->getName() == 'Телефон') { - $this->phones = $customField->getValues(); - } elseif ($customField->getIsSystem() && $customField->getName() == 'Email') { - $this->emails = $customField->getValues(); - } else { - $this->customFields[$customField->getId()] = $customField; - } - } - } - return $this; - } - throw new AmoWrapException('Не удалось загрузить сущность из сырых данных'); - } - - /** - * @return array - * @throws AmoWrapException - */ - public function getRaw() - { - return Base::getRawBase($this->getExtraRaw()); - } - - /** - * @param array $data - * @return array - * @throws AmoWrapException - */ - public function getRawBase($data = array()) - { - if (!empty($this->name)) { - $data['name'] = $this->name; - } - if (!empty($this->responsibleUserId)) { - $data['responsible_user_id'] = $this->responsibleUserId; - } - if (!empty($this->companyId)) { - $data['company_id'] = $this->companyId; - } - if (!empty($this->leadsId)) { - $data['leads_id'] = $this->leadsId; - } - if (!empty($this->contactsId)) { - $data['contacts_id'] = $this->contactsId; - } - $data['tags'] = implode(',', $this->tags); - if (!empty($this->unlink)) { - $data['unlink'] = $this->unlink; - } - if (empty($this->id)) { - $data['created_by'] = 0; - } else { - $data['id'] = $this->id; - $data['updated_at'] = date('U'); - $data['updated_by'] = 0; - } - $customFields = $this->customFields; - if (!empty($this->phones)) { - $idPhoneEnums = AmoCRM::getInfo()->get('idPhoneEnums'); - foreach ($this->phones as &$phone) { - if ($phone->getEnum() === 0) { - $phone->setEnum($idPhoneEnums['OTHER']); - } - } - $customFieldPhone = new CustomField(AmoCRM::getInfo()->get('phoneFieldId'), $this->phones); - $customFields[] = $customFieldPhone; - } - if (!empty($this->emails)) { - $idEmailEnums = AmoCRM::getInfo()->get('idEmailEnums'); - foreach ($this->emails as &$email) { - if ($email->getEnum() === 0) { - $email->setEnum($idEmailEnums['OTHER']); - } - } - $customFieldEmail = new CustomField(AmoCRM::getInfo()->get('emailFieldId'), $this->emails); - $customFields[] = $customFieldEmail; - } - if (!empty($customFields)) { - foreach ($customFields as $customFieldObj) { - $customField = array( - 'id' => $customFieldObj->getId(), - ); - $values = array(); - foreach ($customFieldObj->getValues() as $valueObj) { - $value = array( - 'enum' => $valueObj->getEnum(), - 'value' => $valueObj->getValue(), - 'subtype' => $valueObj->getSubtype(), - ); - $values[] = $value; - } - $customField['values'] = $values; - $data['custom_fields'][] = $customField; - } - } - return $data; - } - - /** - * @return array - */ - protected abstract function getExtraRaw(); - - /** - * @return Base|Company|Contact|Lead|Note|Task - * @throws AmoWrapException - */ - public function delete() - { - $typeDelete = $this->config['delete']; - $post = array('ACTION' => 'DELETE', 'ID[]' => $this->id); - $url = "ajax/$typeDelete/multiple/delete/"; - $res = AmoCRM::cUrl($url, http_build_query($post), null, true); - if ($res !== null && $res->status == 'success') { - foreach ($this as $key => $item) { - $this->$key = null; - } - return $this; - } - throw new AmoWrapException('Не удалось удалить сущность'); - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @param string $name - * @return Base|Company|Contact|Lead - */ - public function setName($name) - { - $this->name = $name; - return $this; - } - - /** - * @return int - */ - public function getResponsibleUserId() - { - return $this->responsibleUserId; - } - - /** - * @return string - * @throws AmoWrapException - */ - public function getResponsibleUserName() - { - $usersIdAndName = AmoCRM::getInfo()->get('usersIdAndName'); - return $usersIdAndName[$this->responsibleUserId]; - } - - /** - * @return int - */ - public function getCompanyId() - { - return $this->companyId; - } - - /** - * @param Company|null $company - * @return Base|Contact|Lead - */ - public function setCompanyId($company = null) - { - $this->companyId = $company !== null ? $company->getId() : $company; - return $this; - } - - /** - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * @return string[] - */ - public function getTags() - { - return $this->tags; - } - - /** - * @param string $tag - * @return Base|Company|Contact|Lead - */ - public function addTag($tag) - { - $this->tags[] = $tag; - return $this; - } + protected static $domain; /** - * @param string $tag - * @return Base|Company|Contact|Lead - * @throws AmoWrapException + * @var string */ - public function delTag($tag) - { - $key = array_search($tag, $this->tags); - if ($key === false) { - throw new AmoWrapException('Тэг не найден'); - } - unset($this->tags[$key]); - return $this; - } + protected static $userLogin; /** - * @param string $name - * @param int $type - * @return int|false - * @throws AmoWrapException + * @var string */ - public function addCustomField($name, $type = 1) - { - $elementType = $this->config['elementType']; - $data['request']['fields']['add'] = array( - array( - 'name' => $name, - 'type' => $type, - 'element_type' => $elementType, - 'origin' => 'AmoCRM Wrap', - 'disabled' => false, - ) - ); - $res = AmoCRM::cUrl('private/api/v2/json/fields/set', $data); - if ($res !== null) { - return $res->response->fields->add[0]->id; - } - throw new AmoWrapException('Не удалось добавить пользовательское поле'); - } + protected static $userAPIKey; /** - * @param int|string $nameOrId - * @return Base|Company|Contact|Lead - * @throws AmoWrapException + * @var bool */ - public function delCustomField($nameOrId) - { - $id = CustomField::getIdFromNameOrId($this->config['info'], $nameOrId); - if (empty($id)) { - throw new AmoWrapException('Не удалось найти id пользовательского поля'); - } - $data['request']['fields']['delete'] = array( - array( - 'id' => $id, - 'origin' => 'AmoCRM Wrap' - ) - ); - $res = AmoCRM::cUrl('private/api/v2/json/fields/set', $data); - if ($res !== null) { - if ($res->response->fields->delete[0]->id == $id) { - return $this; - } - } - throw new AmoWrapException('Не удалось удалить пользовательское поле'); - } + protected static $authorization = false; /** - * @param string|int $nameOrId - * @return string + * @param string $url + * @param array $data + * @param DateTime|null $modifiedSince + * @param bool $ajax + * + * @return stdClass|null + * * @throws AmoWrapException */ - public function getCustomFieldValue($nameOrId) + protected static function cUrl($url, $data = array(), DateTime $modifiedSince = null, $ajax = false) { - $values = array(); - if (AmoCRM::isAuthorization()) { - $id = CustomField::getIdFromNameOrId($this->config['info'], $nameOrId); - if (array_key_exists($id, $this->customFields)) { - foreach ($this->customFields[$id]->getValues() as $value) { - $values[] = $value->getValue(); - } - return implode('; ', $values); - } + $url = 'https://' . self::$domain . '.amocrm.ru/' . $url; + $isUnsorted = mb_stripos($url, 'incoming_leads') !== false; + if ($isUnsorted) { + $url .= '&login=' . self::$userLogin . '&api_key=' . self::$userAPIKey; } else { - $customFields = $this->getCustomFieldsValue(); - if (isset($this->customFields[$nameOrId])) { - foreach ($this->customFields[$nameOrId]->getValues() as $value) { - $values[] = $value->getValue(); - } - return implode('; ', $values); + if (mb_strpos($url, '?') === false) { + $url .= '?'; + } + $url .= '&USER_LOGIN=' . self::$userLogin . '&USER_HASH=' . self::$userAPIKey; + } + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_USERAGENT, 'DrillCoder AmoCRM_Wrap/v' . AmoCRM::VERSION); + curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + $headers = array(); + if (count($data) > 0) { + curl_setopt($curl, CURLOPT_POST, true); + $dataStr = ''; + if ($ajax) { + $headers[] = 'X-Requested-With: XMLHttpRequest'; + } elseif ($isUnsorted) { + $dataStr = http_build_query($data); } else { - if (array_key_exists($nameOrId, $customFields)) { - return $customFields[$nameOrId]; - } - } - } - return ''; - } - - /** - * @return string[]; - */ - public function getCustomFieldsValue() - { - $customFields = array(); - foreach ($this->customFields as $customField) { - $id = $customField->getId(); - $values = array(); - foreach ($this->customFields[$id]->getValues() as $value) { - $values[] = $value->getValue(); + $headers[] = 'Content-Type: application/json'; + $dataStr = json_encode($data); } - $customFields[$customField->getName()] = implode(', ', $values); + curl_setopt($curl, CURLOPT_POSTFIELDS, $dataStr); } - return $customFields; - } - - /** - * @param string|int $nameOrId - * @param string $values - * @return Base|Company|Contact|Lead - * @throws AmoWrapException - */ - public function setCustomField($nameOrId, $values) - { - $type = $this->config['info']; - $idCustomFields = AmoCRM::getInfo()->get("id{$type}CustomFields"); - if (array_key_exists($nameOrId, $idCustomFields)) { - $id = $nameOrId; - $name = $idCustomFields[$nameOrId]; - } elseif (in_array($nameOrId, $idCustomFields)) { - $id = array_search($nameOrId, $idCustomFields); - $name = $nameOrId; - } else { - throw new AmoWrapException('Не найти пользовательское поле'); + if ($modifiedSince !== null) { + $headers[] = 'IF-MODIFIED-SINCE: ' . $modifiedSince->format(DateTime::RFC1123); } - if (!empty($id)) { - if (empty($values)) { - if (array_key_exists($id, $this->customFields)) { - $this->customFields[$id]->delAllValues(); - } - } else { - $values = explode(';', $values); - $valueObj = array(); - foreach ($values as $value) { - $value = trim($value); - $idTypeCustomFieldsEnums = AmoCRM::getInfo()->get("id{$type}CustomFieldsEnums"); - if (isset($idTypeCustomFieldsEnums[$id])) { - $enum = array_search($value, $idTypeCustomFieldsEnums[$id]); - } else { - $enum = null; - } - $valueObj[] = new Value($value, $enum); - } - $customFieldObj = new CustomField($id, $valueObj, $name); - $this->customFields[$customFieldObj->getId()] = $customFieldObj; - return $this; - } - } - throw new AmoWrapException('Не удалось задать значение пользовательскому полю'); - } + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + $json = curl_exec($curl); + curl_close($curl); - /** - * @return int - */ - public function getElementId() - { - return $this->elementId; - } - - /** - * @param int $elementId - * @return Base|Note|Task - */ - public function setElementId($elementId) - { - $this->elementId = $elementId; - return $this; - } - - /** - * @return int - */ - public function getElementType() - { - return $this->elementType; - } + $result = json_decode($json); + if (isset($result->response->error) || (isset($result->title) && $result->title === 'Error')) { + $errorCode = isset($result->status) ? (int)$result->status : (int)$result->response->error_code; + $errorMessage = isset(Config::$errors[$errorCode]) ? Config::$errors[$errorCode] : $result->response->error; - /** - * @param int $elementType - * @return Base|Note|Task - */ - public function setElementType($elementType) - { - $this->elementType = $elementType; - return $this; - } - - /** - * @return string - */ - public function getText() - { - return $this->text; - } - - /** - * @param string $text - * @return Base|Note|Task - */ - public function setText($text) - { - $this->text = $text; - return $this; - } - - /** - * @return int|string - */ - public function getType() - { - return $this->type; - } - - /** - * @param int|string $type - * @return Base|Note|Task - */ - public function setType($type) - { - $this->type = $type; - return $this; - } - - /** - * @return \DateTime - */ - public function getDateCreate() - { - return $this->dateCreate; - } - - /** - * @return \DateTime - */ - public function getDateUpdate() - { - return $this->dateUpdate; - } - - /** - * @return int - */ - public function getUserIdUpdate() - { - return $this->userIdUpdate; - } - - /** - * @return string - * @throws AmoWrapException - */ - public function getUserNameUpdate() - { - $usersIdAndName = AmoCRM::getInfo()->get('usersIdAndName'); - return $usersIdAndName[$this->userIdUpdate]; - } - - /** - * @return int - */ - public function getCreatedUserId() - { - return $this->createdUserId; - } - - /** - * @return string - * @throws AmoWrapException - */ - public function getCreatedUserName() - { - $usersIdAndName = AmoCRM::getInfo()->get('usersIdAndName'); - return $usersIdAndName[$this->createdUserId]; - } - - /** - * @return int[] - */ - public function getLeadsId() - { - return $this->leadsId; - } - - /** - * @param Lead $lead - * @return Base|Company|Contact - */ - public function addLead(Lead $lead) - { - $this->leadsId[] = $lead->getId(); - return $this; - } - - /** - * @param Lead $lead - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function delLeadId(Lead $lead) - { - $delKeys = array_keys($this->leadsId, $lead->getId()); - if (count($delKeys) > 0) { - foreach ($delKeys as $delKey) { - unset($this->leadsId[$delKey]); - } - $this->unlink['leads_id'][] = $lead->getId(); - return $this; + throw new AmoWrapException($errorMessage, $errorCode); } - throw new AmoWrapException('Не найден id сделки'); - } - /** - * @return int[] - */ - public function getContactsId() - { - $contactsId = array(); - foreach ($this->contactsId as $contactId) { - $contactsId[] = $contactId; - } - return $contactsId; + return $result; } /** - * @param Contact $contact - * @return Base|Company|Lead - */ - public function addContactId(Contact $contact) - { - $this->contactsId[] = $contact->getId(); - return $this; - } - - /** - * @param Contact $contact - * @return Base|Company|Lead - * @throws AmoWrapException - */ - public function delContactId(Contact $contact) - { - $delKeys = array_keys($this->contactsId, $contact->getId()); - if (!empty($delKeys)) { - foreach ($delKeys as $delKey) { - unset($this->contactsId[$delKey]); - } - $this->unlink['contacts_id'][] = $contact->getId(); - return $this; - } - throw new AmoWrapException('Не найден id контакта'); - } - - /** - * @return string[] - */ - public function getPhones() - { - $phones = array(); - foreach ($this->phones as $value) { - $phones[] = $value->getValue(); - } - return $phones; - } - - /** - * @param string $phone - * @param string $enum - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function addPhone($phone, $enum = 'OTHER') - { - $enum = mb_strtoupper($enum); - if (!empty($this->phones)) { - foreach ($this->phones as $value) { - if (AmoCRM::clearPhone($value->getValue()) == AmoCRM::clearPhone($phone)) { - return $this; - } - } - } - if (AmoCRM::isAuthorization()) { - $idPhoneEnums = AmoCRM::getInfo()->get('idPhoneEnums'); - if (array_key_exists($enum, $idPhoneEnums)) { - $this->phones[] = new Value($phone, $idPhoneEnums[$enum]); - return $this; - } - } else { - $this->phones[] = new Value($phone); - return $this; - } - throw new AmoWrapException('Не удалось добавить телефон'); - } - - /** - * @param string $phone - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function delPhone($phone) - { - if (!empty($this->phones)) { - foreach ($this->phones as $key => $value) { - if (AmoCRM::clearPhone($value->getValue()) == AmoCRM::clearPhone($phone)) { - unset($this->phones[$key]); - return $this; - } - } - } - throw new AmoWrapException('Не удалось удалить телефон'); - } - - /** - * @return string[] - */ - public function getEmails() - { - $emails = array(); - foreach ($this->emails as $value) { - $emails[] = $value->getValue(); - } - return $emails; - } - - /** - * @param string $email - * @param string $enum - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function addEmail($email, $enum = 'OTHER') - { - $email = mb_strtolower($email); - $enum = mb_strtoupper($enum); - if (!empty($this->emails)) { - foreach ($this->emails as $value) { - if (mb_strtolower($value->getValue()) == $email) - return $this; - } - } - if (AmoCRM::isAuthorization()) { - $idEmailEnums = AmoCRM::getInfo()->get('idEmailEnums'); - if (array_key_exists($enum, $idEmailEnums)) { - $this->emails[] = new Value($email, $idEmailEnums[$enum]); - return $this; - } - } else { - $this->emails[] = new Value($email); - return $this; - } - throw new AmoWrapException('Не удалось добавить почту'); - } - - /** - * @param string $email - * @return Base|Company|Contact - * @throws AmoWrapException - */ - public function delEmail($email) - { - $email = mb_strtolower($email); - if (!empty($this->emails)) { - foreach ($this->emails as $key => $value) { - if (mb_strtolower($value->getValue()) == $email) { - unset($this->emails[$key]); - return $this; - } - } - } - throw new AmoWrapException('Не удалось удалить почту'); - } - - /** - * @param string $text - * @param int $type - * @return Base|Company|Contact|Lead - * @throws AmoWrapException - */ - public function addNote($text, $type = 4) - { - if (empty($this->amoId)) { - $this->save(); - } - $note = new Note(); - $note->setText($text) - ->setType($type) - ->setElementId($this->id) - ->setElementType($this->config['elementType']) - ->save(); - return $this; - } - - /** - * @return Company|Contact|Lead|Note|Task - * @throws AmoWrapException - */ - public function save() - { - return Base::saveBase($this->getExtraRaw()); - } - - /** - * @param array $data - * @return Base|Company|Contact|Lead|Note|Task - * @throws AmoWrapException - */ - public function saveBase($data = array()) - { - if (empty($this->id)) { - $method = 'add'; - } else { - $method = 'update'; - } - $requestData[$method] = array($this->getRawBase($data)); - $res = AmoCRM::cUrl("api/v2/{$this->config['url']}", $requestData); - if ($method == 'update') { - $idRes = $res->_embedded->items[0]->id; - if ($idRes == $this->id) - return $this; - } elseif ($method == 'add') { - if (isset($res->_embedded->items[0]->id)) { - $this->loadInAmoId($res->_embedded->items[0]->id); - return $this; - } - } - throw new AmoWrapException('Не удалось сохранить или обновить сущность'); - } - - /** - * @param string $text - * @param string $serviceName - * @return Base|Company|Contact|Lead - * @throws AmoWrapException - */ - public function addSystemNote($text, $serviceName) - { - if (empty($this->amoId)) { - $this->save(); - } - $note = new Note(); - $note->setText($text) - ->setType(25) - ->setService($serviceName) - ->setElementId($this->id) - ->setElementType($this->config['elementType']) - ->save(); - return $this; - - } - - /** - * @param string $text - * @param int|string|null $responsibleUserIdOrName - * @param \DateTime|null $completeTill - * @param int|string $typeId - * @return Base|Company|Contact|Lead - * @throws AmoWrapException - */ - public function addTask($text, $responsibleUserIdOrName = null, $completeTill = null, $typeId = 3) - { - if (empty($this->amoId)) { - $this->save(); - } - if ($responsibleUserIdOrName === null) { - $responsibleUserIdOrName = $this->responsibleUserId; - } - $task = new Task(); - if ($completeTill !== null) { - $task->setCompleteTill($completeTill); - } - if (!key_exists($typeId, AmoCRM::getInfo()->get('taskTypes'))) { - throw new AmoWrapException('Не удалось найти тип задачи'); - } - $task->setText($text) - ->setType($typeId) - ->setResponsibleUser($responsibleUserIdOrName) - ->setElementId($this->id) - ->setElementType($this->config['elementType']) - ->save(); - return $this; - } - - /** - * @param int|string $responsibleUserIdOrName - * @return Base|Company|Contact|Lead|Task - * @throws AmoWrapException - */ - public function setResponsibleUser($responsibleUserIdOrName) - { - $this->responsibleUserId = AmoCRM::getInfo()->getUserIdFromIdOrName($responsibleUserIdOrName); - if (empty($this->responsibleUserId)) { - throw new AmoWrapException('Ответственный не найден'); - } - return $this; - } - - /** - * @param string $pathToFile - * @return Base|Company|Contact|Lead - * @throws AmoWrapException + * @param string $var + * + * @return string */ - public function addFile($pathToFile) + protected static function onlyNumbers($var) { - if (empty($this->amoId)) { - $this->save(); - } - if (is_file($pathToFile) && file_exists($pathToFile)) { - $elementType = $this->config['elementType']; - if (class_exists('CURLFile')) { - $CURLFile = new \CURLFile(realpath($pathToFile)); - $post = array( - 'UserFile' => $CURLFile - ); - } else { - $post = array( - 'UserFile' => '@' . $pathToFile - ); - } - $url = "/private/notes/edit2.php?ACTION=ADD_NOTE&ELEMENT_ID={$this->id}&ELEMENT_TYPE={$elementType}&fileapi" . - str_replace('.', '', microtime(true)); - $res = AmoCRM::cUrl($url, $post, null, true); - if (isset($res->status) && $res->status == 'fail') { - throw new AmoWrapException('Не удалось добавить файл'); - } - $post = array( - 'ACTION' => 'ADD_NOTE', - 'DATE_CREATE' => time(), - 'ATTACH' => $res->note->params->link, - 'BODY' => $res->note->params->text, - 'ELEMENT_ID' => $this->id, - 'ELEMENT_TYPE' => $elementType, - ); - $res = AmoCRM::cUrl('private/notes/edit2.php', $post, null, true); - if (isset($res->status) && $res->status == 'ok') { - return $this; - } - } - throw new AmoWrapException('Не удалось добавить файл'); + return preg_replace('/\D/', '', $var); } } \ No newline at end of file diff --git a/src/BaseEntity.php b/src/BaseEntity.php new file mode 100644 index 0000000..711ed91 --- /dev/null +++ b/src/BaseEntity.php @@ -0,0 +1,1232 @@ +config = Config::$$className; + + if ($id !== null) { + $id = Base::onlyNumbers($id); + $this->load($id); + } + } + + /** + * @param stdClass|array $data + * + * @throws AmoWrapException + */ + public function loadInRaw($data) + { + try { + $data = json_decode(json_encode($data)); + if (!empty($data->id)) { + $this->id = Base::onlyNumbers($data->id); + $this->name = isset($data->name) ? $data->name : null; + $this->createdUserId = isset($data->created_by) ? Base::onlyNumbers($data->created_by) : null; + $dateCreate = new DateTime(); + $dateCreate->setTimestamp($data->created_at); + $this->dateCreate = $dateCreate; + $dateUpdate = new DateTime(); + $dateUpdate->setTimestamp($data->updated_at); + $this->dateUpdate = $dateUpdate; + $this->responsibleUserId = isset($data->responsible_user_id) ? + Base::onlyNumbers($data->responsible_user_id) : null; + $this->userIdUpdate = isset($data->updated_by) ? Base::onlyNumbers($data->updated_by) : null; + $this->companyId = isset($data->company->id) ? Base::onlyNumbers($data->company->id) : null; + $this->leadsId = isset($data->leads->id) ? $data->leads->id : array(); + $this->contactsId = isset($data->contacts->id) ? $data->contacts->id : array(); + $this->type = isset($data->note_type) ? (int)$data->note_type : null; + $this->elementId = isset($data->element_id) ? Base::onlyNumbers($data->element_id) : null; + $this->elementType = isset($data->element_type) ? (int)$data->element_type : null; + $this->text = isset($data->text) ? $data->text : null; + + if (isset($data->tags) && is_array($data->tags)) { + foreach ($data->tags as $tag) { + $this->tags[$tag->id] = $tag->name; + } + } + if (isset($data->custom_fields) && is_array($data->custom_fields)) { + foreach ($data->custom_fields as $custom_field) { + $customField = CustomField::loadInRaw($custom_field); + if ($customField->getId() === AmoCRM::getPhoneFieldId()) { + $this->phones = $customField->getValues(); + } elseif ($customField->getId() === AmoCRM::getEmailFieldId()) { + $this->emails = $customField->getValues(); + } else { + $this->customFields[$customField->getId()] = $customField; + } + } + } + } else { + throw new AmoWrapException('Не удалось загрузить сущность из сырых данных'); + } + } catch (Exception $e) { + throw new AmoWrapException("Ошибка в обёртке: {$e->getMessage()}", $e->getCode(), $e); + } + } + + /** + * @return array + */ + public function getRaw() + { + return $this->getRawBase($this->getExtraRaw()); + } + + /** + * @return Company|Contact|Lead|Note|Task + * + * @throws AmoWrapException + */ + public function save() + { + return $this->saveBase($this->getExtraRaw()); + } + + /** + * @return BaseEntity|Company|Contact|Lead|Note|Task + * + * @throws AmoWrapException + */ + public function delete() + { + $url = "ajax/{$this->config['delete']}/multiple/delete/"; + $post = array('ACTION' => 'DELETE', 'ID[]' => $this->id); + + $res = AmoCRM::cUrl($url, http_build_query($post), null, true); + if ($res !== null && $res->status === 'success') { + foreach ($this as $key => $item) { + $this->$key = null; + } + + return $this; + } + + throw new AmoWrapException('Не удалось удалить сущность'); + } + + /** + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + * + * @return BaseEntity|Company|Contact|Lead + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return string + */ + public function getResponsibleUserId() + { + return $this->responsibleUserId; + } + + /** + * @return string + */ + public function getResponsibleUserName() + { + $usersIdAndName = AmoCRM::getUsers(); + return $usersIdAndName[$this->responsibleUserId]; + } + + /** + * @param int|string $responsibleUserIdOrName + * + * @return BaseEntity|Company|Contact|Lead|Task + * + * @throws AmoWrapException + */ + public function setResponsibleUser($responsibleUserIdOrName) + { + $this->responsibleUserId = AmoCRM::searchUserId($responsibleUserIdOrName); + + return $this; + } + + /** + * @return int + */ + public function getCompanyId() + { + return $this->companyId; + } + + /** + * @return Company + * + * @throws AmoWrapException + */ + public function getCompany() + { + return new Company($this->companyId); + } + + /** + * @param Company $company + * + * @return BaseEntity|Contact|Lead + */ + public function setCompany($company) + { + $id = $company instanceof Company ? $company->getId() : Base::onlyNumbers($company); + $this->companyId = $id; + + return $this; + } + + /** + * @return string[] + */ + public function getTags() + { + return $this->tags; + } + + /** + * @param string $tag + * + * @return BaseEntity|Company|Contact|Lead + */ + public function addTag($tag) + { + $this->tags[] = $tag; + + return $this; + } + + /** + * @param string $tag + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function delTag($tag) + { + $key = array_search($tag, $this->tags); + if ($key !== false) { + unset($this->tags[$key]); + + return $this; + } + + throw new AmoWrapException('Тэг не найден'); + } + + /** + * @param string $name + * @param int $type + * @param array $enums + * + * @return int + * + * @throws AmoWrapException + */ + public function addCustomField($name, $type = CustomField::TYPE_TEXT, $enums = array()) + { + if (!is_array($enums)) { + $enums = array($enums); + } + $elementType = $this->config['elementType']; + $data['request']['fields']['add'] = array( + array( + 'name' => $name, + 'type' => $type, + 'enums' => $enums, + 'element_type' => $elementType, + 'origin' => 'DrillCoder AmoCRM Wrap', + 'disabled' => false, + ) + ); + $res = AmoCRM::cUrl('private/api/v2/json/fields/set', $data); + if ($res !== null && isset($res->response->fields->add[0]->id)) { + return $res->response->fields->add[0]->id; + } + + throw new AmoWrapException('Не удалось добавить пользовательское поле'); + } + + /** + * @param int|string $nameOrId + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function delCustomField($nameOrId) + { + $id = $this->searchCustomFieldsId($nameOrId); + + $data['request']['fields']['delete'] = array( + array( + 'id' => $id, + 'origin' => 'DrillCoder AmoCRM Wrap' + ) + ); + $res = AmoCRM::cUrl('private/api/v2/json/fields/set', $data); + if ($res !== null && isset($res->response->fields->delete[0]->id) && $res->response->fields->delete[0]->id === $id) { + return $this; + } + + throw new AmoWrapException('Не удалось удалить пользовательское поле'); + } + + /** + * @param string|int $nameOrId + * + * @return string + * + * @throws AmoWrapException + */ + public function getCustomFieldValueInStr($nameOrId) + { + return $this->getCustomField($nameOrId)->getValuesInStr(); + } + + /** + * @param string|int $nameOrId + * + * @return string[] + * + * @throws AmoWrapException + */ + public function getCustomFieldValueInArray($nameOrId) + { + return $this->getCustomField($nameOrId)->getValuesInArray(); + } + + /** + * @param string|int $nameOrId + * @param string|array $values + * @param int|null $subtype + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function setCustomFieldValue($nameOrId, $values, $subtype = null) + { + $customField = $this->getCustomField($nameOrId); + if (!is_array($values)) { + $values = array($values); + } + + if ($subtype !== null) { + $valueObj = $customField->getValues(); + } else { + $valueObj = array(); + } + + foreach ($values as $value) { + $value = trim($value); + $customFieldsEnums = $this->getEnums($customField->getId()); + $enum = null; + foreach ($customFieldsEnums as $enumId => $enumName) { + if (mb_stripos($enumName, $value) !== false) { + $enum = $enumId; + } + } + $valueObj[] = new Value($value, $enum, $subtype); + } + $customField->setValues($valueObj); + + return $this; + } + + /** + * @return string + */ + public function getElementId() + { + return $this->elementId; + } + + /** + * @param string $elementId + * + * @return BaseEntity|Note|Task + */ + public function setElementId($elementId) + { + $this->elementId = Base::onlyNumbers($elementId); + + return $this; + } + + /** + * @return int + */ + public function getElementType() + { + return $this->elementType; + } + + /** + * @param int $elementType + * + * @return BaseEntity|Note|Task + */ + public function setElementType($elementType) + { + $this->elementType = (int)$elementType; + + return $this; + } + + /** + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * @param string $text + * + * @return BaseEntity|Note|Task + */ + public function setText($text) + { + $this->text = $text; + + return $this; + } + + /** + * @return int|string + */ + public function getType() + { + return $this->type; + } + + /** + * @param int|string $type + * + * @return BaseEntity|Note|Task + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * @return DateTime + */ + public function getDateCreate() + { + return $this->dateCreate; + } + + /** + * @return DateTime + */ + public function getDateUpdate() + { + return $this->dateUpdate; + } + + /** + * @return string + */ + public function getUserIdUpdate() + { + return $this->userIdUpdate; + } + + /** + * @return string + */ + public function getUserNameUpdate() + { + $users = AmoCRM::getUsers(); + + return $users[$this->userIdUpdate]; + } + + /** + * @return string + */ + public function getCreatedUserId() + { + return $this->createdUserId; + } + + /** + * @return string + */ + public function getCreatedUserName() + { + $users = AmoCRM::getUsers(); + + return $users[$this->createdUserId]; + } + + /** + * @return int[] + */ + public function getLeadsId() + { + return $this->leadsId; + } + + /** + * @return Lead[] + * + * @throws AmoWrapException + */ + public function getLeads() + { + $leads = array(); + foreach ($this->leadsId as $leadId) { + $lead = new Lead($leadId); + $leads[] = $lead; + } + return $leads; + } + + /** + * @param Lead|string|int $lead + * + * @return BaseEntity|Company|Contact + */ + public function addLead($lead) + { + $id = $lead instanceof Lead ? $lead->getId() : Base::onlyNumbers($lead); + $this->leadsId[] = $id; + + return $this; + } + + /** + * @param Lead|string|int $lead + * + * @return BaseEntity|Company|Contact + * + * @throws AmoWrapException + */ + public function delLead($lead) + { + $id = $lead instanceof Lead ? $lead->getId() : Base::onlyNumbers($lead); + $delKeys = array_keys($this->leadsId, $id); + if (count($delKeys) > 0) { + foreach ($delKeys as $delKey) { + unset($this->leadsId[$delKey]); + } + $this->unlink['leads_id'][] = $id; + + return $this; + } + + throw new AmoWrapException('Не найден id сделки'); + } + + /** + * @return int[] + */ + public function getContactsId() + { + return $this->contactsId; + } + + /** + * @return Contact[] + * + * @throws AmoWrapException + */ + public function getContacts() + { + $contacts = array(); + foreach ($this->contactsId as $contactId) { + $contact = new Contact($contactId); + $contacts[] = $contact; + } + return $contacts; + } + + /** + * @param Contact|string|int $contact + * + * @return BaseEntity|Company|Lead + */ + public function addContact($contact) + { + $id = $contact instanceof Contact ? $contact->getId() : Base::onlyNumbers($contact); + $this->contactsId[] = $id; + + return $this; + } + + /** + * @param Contact|string|int $contact + * + * @return BaseEntity|Company|Lead + * + * @throws AmoWrapException + */ + public function delContact($contact) + { + $id = $contact instanceof Contact ? $contact->getId() : Base::onlyNumbers($contact); + $delKeys = array_keys($this->contactsId, $id); + if (!empty($delKeys)) { + foreach ($delKeys as $delKey) { + unset($this->contactsId[$delKey]); + } + $this->unlink['contacts_id'][] = $id; + return $this; + } + throw new AmoWrapException('Не найден id контакта'); + } + + /** + * @return string[] + */ + public function getPhones() + { + $phones = array(); + foreach ($this->phones as $value) { + $phones[] = $value->getValue(); + } + return $phones; + } + + /** + * @param string $phone + * @param string $enum + * + * @return BaseEntity|Company|Contact + * + * @throws AmoWrapException + */ + public function addPhone($phone, $enum = CustomField::PHONE_OTHER) + { + $enum = mb_strtoupper($enum); + if (count($this->phones) > 0) { + foreach ($this->phones as $value) { + if (Base::onlyNumbers($value->getValue()) === Base::onlyNumbers($phone)) { + return $this; + } + } + } + + $idPhoneEnums = AmoCRM::getPhoneEnums(); + if (isset($idPhoneEnums[$enum])) { + $this->phones[] = new Value($phone, $idPhoneEnums[$enum]); + + return $this; + } + + throw new AmoWrapException('Не удалось добавить телефон'); + } + + /** + * @param string $phone + * + * @return BaseEntity|Company|Contact + * + * @throws AmoWrapException + */ + public function delPhone($phone) + { + if (count($this->phones) > 0) { + foreach ($this->phones as $key => $value) { + if (AmoCRM::onlyNumbers($value->getValue()) === AmoCRM::onlyNumbers($phone)) { + unset($this->phones[$key]); + + return $this; + } + } + } + + throw new AmoWrapException('Не удалось удалить телефон'); + } + + /** + * @return string[] + */ + public function getEmails() + { + $emails = array(); + foreach ($this->emails as $value) { + $emails[] = $value->getValue(); + } + return $emails; + } + + /** + * @param string $email + * @param string $enum + * + * @return BaseEntity|Company|Contact + * + * @throws AmoWrapException + */ + public function addEmail($email, $enum = CustomField::EMAIL_OTHER) + { + $email = mb_strtolower($email); + $enum = mb_strtoupper($enum); + if (!empty($this->emails)) { + foreach ($this->emails as $value) { + if (mb_strtolower($value->getValue()) === $email) { + return $this; + } + } + } + + $emailEnums = AmoCRM::getEmailEnums(); + if (isset($emailEnums[$enum])) { + $this->emails[] = new Value($email, $emailEnums[$enum]); + + return $this; + } + + throw new AmoWrapException('Не удалось добавить почту'); + } + + /** + * @param string $email + * + * @return BaseEntity|Company|Contact + * + * @throws AmoWrapException + */ + public function delEmail($email) + { + $email = mb_strtolower($email); + if (!empty($this->emails)) { + foreach ($this->emails as $key => $value) { + if (mb_strtolower($value->getValue()) === $email) { + unset($this->emails[$key]); + + return $this; + } + } + } + + throw new AmoWrapException('Не удалось удалить почту'); + } + + /** + * @param string $text + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addNote($text) + { + if ($this->id === null) { + $this->save(); + } + + $note = new Note(); + $note->setText($text) + ->setType(4) + ->setElementId($this->id) + ->setElementType($this->config['elementType']) + ->save(); + + return $this; + } + + /** + * @param string $text + * @param string $serviceName + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addNoteSystem($text, $serviceName) + { + if ($this->id === null) { + $this->save(); + } + + $note = new Note(); + $note->setText($text) + ->setType(25) + ->setService($serviceName) + ->setElementId($this->id) + ->setElementType($this->config['elementType']) + ->save(); + + return $this; + } + + /** + * @param string $text + * @param string $phone + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addNoteSmsOut($text, $phone) + { + if ($this->id === null) { + $this->save(); + } + + $note = new Note(); + $note->setText($text) + ->setType(103) + ->setPhone($phone) + ->setElementId($this->id) + ->setElementType($this->config['elementType']) + ->save(); + + return $this; + } + + /** + * @param string $text + * @param string $phone + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addNoteSmsIn($text, $phone) + { + if ($this->id === null) { + $this->save(); + } + + $note = new Note(); + $note->setText($text) + ->setType(102) + ->setPhone($phone) + ->setCreatedUser($this->getResponsibleUserId()) + ->setElementId($this->id) + ->setElementType($this->config['elementType']) + ->save(); + + return $this; + } + + /** + * @param string $text + * @param int|string|null $responsibleUserIdOrName + * @param DateTime|null $completeTill + * @param int|string $type + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addTask($text, $responsibleUserIdOrName = null, DateTime $completeTill = null, $type = 3) + { + if (empty($this->amoId)) { + $this->save(); + } + $tapeId = AmoCRM::searchTaskType($type); + + if ($responsibleUserIdOrName === null) { + $responsibleUserIdOrName = $this->responsibleUserId; + } + + $task = new Task(); + if ($completeTill !== null) { + $task->setCompleteTill($completeTill); + } + + $task->setText($text) + ->setType($tapeId) + ->setResponsibleUser($responsibleUserIdOrName) + ->setElementId($this->id) + ->setElementType($this->config['elementType']) + ->save(); + + return $this; + } + + /** + * @param string $pathToFile + * + * @return BaseEntity|Company|Contact|Lead + * + * @throws AmoWrapException + */ + public function addFile($pathToFile) + { + if ($this->id === null) { + $this->save(); + } + + if (is_file($pathToFile) && file_exists($pathToFile)) { + $elementType = $this->config['elementType']; + if (class_exists('CURLFile')) { + $CURLFile = new CURLFile(realpath($pathToFile)); + $post = array( + 'UserFile' => $CURLFile + ); + } else { + $post = array( + 'UserFile' => '@' . $pathToFile + ); + } + $url = "/private/notes/edit2.php?ACTION=ADD_NOTE&ELEMENT_ID={$this->id}&ELEMENT_TYPE={$elementType}&fileapi" . + str_replace('.', '', microtime(true)); + $res = AmoCRM::cUrl($url, $post, null, true); + if ($res !== null && isset($res->status) && $res->status === 'fail') { + throw new AmoWrapException('Не удалось добавить файл'); + } + $post = array( + 'ACTION' => 'ADD_NOTE', + 'DATE_CREATE' => time(), + 'ATTACH' => $res->note->params->link, + 'BODY' => $res->note->params->text, + 'ELEMENT_ID' => $this->id, + 'ELEMENT_TYPE' => $elementType, + ); + $res = AmoCRM::cUrl('private/notes/edit2.php', $post, null, true); + if ($res !== null && isset($res->status) && $res->status !== 'ok') { + throw new AmoWrapException('Не удалось добавить файл'); + } + } + + return $this; + } + + /** + * @return array + */ + abstract protected function getExtraRaw(); + + /** + * @param int $id + * + * @throws AmoWrapException + */ + protected function load($id) + { + $typeUrl = $this->config['url']; + $link = "api/v2/$typeUrl?id=$id"; + + if ($this->config['info'] === 'note') { + $type = Config::$types[$this->elementType]; + $link .= "&type=$type"; + } + + $res = AmoCRM::cUrl($link); + if ($res !== null && count($res->_embedded->items) > 0) { + $this->loadInRaw(current($res->_embedded->items)); + } else { + throw new AmoWrapException('Не удалось загрузить сущность'); + } + } + + /** + * @param string|int $nameOrId + * + * @return CustomField + * + * @throws AmoWrapException + */ + private function getCustomField($nameOrId) + { + $id = $this->searchCustomFieldsId($nameOrId); + if (!isset($this->customFields[$id])) { + $this->customFields[$id] = new CustomField($id); + } + + return $this->customFields[$id]; + } + + + /** + * @param string|int $nameOrId + * + * @return int + * + * @throws AmoWrapException + */ + public function searchCustomFieldsId($nameOrId) + { + $customFields = AmoCRM::getCustomFields($this->config['info']); + + if (isset($customFields[$nameOrId])) { + return $nameOrId; + } + + foreach ($customFields as $customFieldId => $customFieldName) { + if (mb_stripos($customFieldName, $nameOrId) !== false) { + return $customFieldId; + } + } + + throw new AmoWrapException('Не удалось найти пользовательское поле'); + } + + /** + * @param array $data + * + * @return BaseEntity|Company|Contact|Lead|Note|Task + * + * @throws AmoWrapException + */ + private function saveBase($data = array()) + { + if ($this->id === null) { + $method = 'add'; + } else { + $method = 'update'; + } + $requestData[$method] = array($this->getRawBase($data)); + $res = AmoCRM::cUrl("api/v2/{$this->config['url']}", $requestData); + if ($res !== null && isset($res->_embedded->items[0]->id)) { + $classFullName = get_class($this); + /** @var BaseEntity $entity */ + $entity = new $classFullName; + if ($this->config['info'] === 'note') { + $entity->setElementType($this->elementType); + } + $entity->load($res->_embedded->items[0]->id); + + return $entity; + } + + throw new AmoWrapException('Не удалось сохранить сущность'); + } + + /** + * @param array $data + * + * @return array + */ + private function getRawBase($data = array()) + { + if ($this->name !== null) { + $data['name'] = $this->name; + } + if ($this->responsibleUserId !== null) { + $data['responsible_user_id'] = $this->responsibleUserId; + } + if ($this->companyId !== null) { + $data['company_id'] = $this->companyId; + } + if (count($this->leadsId) > 0) { + $data['leads_id'] = $this->leadsId; + } + if (count($this->contactsId) > 0) { + $data['contacts_id'] = $this->contactsId; + } + $data['tags'] = implode(',', $this->tags); + if (count($this->unlink) > 0) { + $data['unlink'] = $this->unlink; + } + if ($this->id === null) { + $data['created_by'] = isset($data['created_by']) ? $data['created_by'] : 0; + } else { + $data['id'] = $this->id; + $data['updated_at'] = date('U'); + $data['updated_by'] = 0; + } + $customFields = $this->customFields; + if (count($this->phones) > 0) { + $idPhoneEnums = AmoCRM::getPhoneEnums(); + foreach ($this->phones as $phone) { + if ($phone->getEnum() === 0) { + $phone->setEnum($idPhoneEnums['OTHER']); + } + } + $customFields[] = new CustomField(AmoCRM::getPhoneFieldId(), $this->phones); + } + if (count($this->emails) > 0) { + $idEmailEnums = AmoCRM::getEmailEnums(); + foreach ($this->emails as $email) { + if ($email->getEnum() === 0) { + $email->setEnum($idEmailEnums['OTHER']); + } + } + $customFields[] = new CustomField(AmoCRM::getEmailFieldId(), $this->emails); + } + if (count($customFields) > 0) { + foreach ($customFields as $customFieldObj) { + $values = array(); + foreach ($customFieldObj->getValues() as $valueObj) { + $value = array( + 'enum' => $valueObj->getEnum(), + 'value' => $valueObj->getValue(), + 'subtype' => $valueObj->getSubtype(), + ); + $values[] = $value; + } + $data['custom_fields'][] = array( + 'id' => $customFieldObj->getId(), + 'values' => $values + ); + } + } + return $data; + } + + /** + * @param string $id + * + * @return array + */ + private function getEnums($id) + { + $enums = AmoCRM::getCustomFieldsEnums($this->config['info']); + + return isset($enums[$id]) ? $enums[$id] : array(); + } +} \ No newline at end of file diff --git a/src/Company.php b/src/Company.php index 7308a74..96b961e 100644 --- a/src/Company.php +++ b/src/Company.php @@ -13,7 +13,7 @@ * Class Company * @package DrillCoder\AmoCRM_Wrap */ -class Company extends Base +class Company extends BaseEntity { /** * @return array diff --git a/src/Contact.php b/src/Contact.php index df5a915..9dfae0c 100644 --- a/src/Contact.php +++ b/src/Contact.php @@ -13,7 +13,7 @@ * Class Contact * @package DrillCoder\AmoCRM_Wrap */ -class Contact extends Base +class Contact extends BaseEntity { /** * @return array diff --git a/src/Helpers/Config.php b/src/Helpers/Config.php index 6c29475..4fae016 100644 --- a/src/Helpers/Config.php +++ b/src/Helpers/Config.php @@ -13,51 +13,138 @@ * Class Config * @package DrillCoder\AmoCRM_Wrap\Helpers */ -class Config +abstract class Config { /** * @var array */ - public $company = array( - 'elementType' => 3, - 'info' => 'Company', - 'url' => 'company', - 'delete' => 'companies', + public static $errors = array( + 244 => 'Недостаточно прав', + 330 => 'Количество привязанных сделок слишком большое', + 222 => 'Пустой запрос', + 405 => 'Метод передачи запроса неверный', + 203 => 'Системная ошибка при работе с дополнительными полями', + 204 => 'Дополнительное поле не найдено', + 282 => 'Не найден в аккаунте', + 283 => 'Неверный запрос, данные не переданы', + 284 => 'Неверный запрос, передан не массив', + 285 => 'Требуемое поле не передано', + 400 => 'Неверная структура массива передаваемых данных, либо не верные идентификаторы кастомных полей', + 403 => 'Аккаунт заблокирован, за неоднократное превышение количества запросов в секунду', + 429 => 'Превышено допустимое количество запросов в секунду', + 2002 => 'По вашему запросу ничего не найдено', + + 101 => 'Аккаунт не найден', + 102 => 'POST-параметры должны передаваться в формате JSON', + 103 => 'Параметры не переданы', + 104 => 'Запрашиваемый метод API не найден', + 402 => 'Подписка закончилась', + + 201 => 'Добавление контактов: пустой массив', + 202 => 'Добавление контактов: нет прав', + 205 => 'Добавление контактов: контакт не создан', + 206 => 'Добавление/Обновление контактов: пустой запрос', + 207 => 'Добавление/Обновление контактов: неверный запрашиваемый метод', + 208 => 'Обновление контактов: пустой массив', + 209 => 'Обновление контактов: требуются параметры "id" и "updated_at"', + 210 => 'Обновление контактов: системная ошибка при работе с дополнительными полями', + 211 => 'Обновление контактов: дополнительное поле не найдено', + 212 => 'Обновление контактов: контакт не обновлён', + 219 => 'Список контактов: ошибка поиска, повторите запрос позднее', + + 213 => 'Добавление сделок: пустой массив', + 214 => 'Добавление/Обновление сделок: пустой запрос', + 215 => 'Добавление/Обновление сделок: неверный запрашиваемый метод', + 216 => 'Обновление сделок: пустой массив', + 217 => 'Обновление сделок: требуются параметры "id", "updated_at", "status_id", "name"\'', + 240 => 'Добавление/Обновление сделок: неверный параметр "id" дополнительного поля', + + 218 => 'Добавление событий: пустой массив', + 221 => 'Список событий: требуется тип', + 226 => 'Добавление событий: элемент события данной сущности не найден', + 223 => 'Добавление/Обновление событий: неверный запрашиваемый метод (GET вместо POST)', + 224 => 'Обновление событий: пустой массив', + 225 => 'Обновление событий: события не найдены', + + 227 => 'Добавление задач: пустой массив', + 228 => 'Добавление/Обновление задач: пустой запрос', + 229 => 'Добавление/Обновление задач: неверный запрашиваемый метод', + 230 => 'Обновление задач: пустой массив', + 231 => 'Обновление задач: задачи не найдены', + 232 => 'Добавление событий: ID элемента или тип элемента пустые либо неккоректные', + 233 => 'Добавление событий: по данному ID элемента не найдены некоторые контакты', + 234 => 'Добавление событий: по данному ID элемента не найдены некоторые сделки', + 235 => 'Добавление задач: не указан тип элемента', + 236 => 'Добавление задач: по данному ID элемента не найдены некоторые контакты', + 237 => 'Добавление задач: по данному ID элемента не найдены некоторые сделки', + 238 => 'Добавление контактов: отсутствует значение для дополнительного поля', + + 281 => 'Каталог не удален: внутренняя ошибка', + + 280 => 'Добавление элементов каталога: элемент создан', + + 288 => 'Недостаточно прав. Доступ запрещен', + 425 => 'Функционал недоступен', + 426 => 'Функционал выключен', + ); + + /** + * @var array + */ + public static $types = array( + 1 => 'contact', + 2 => 'lead', + 3 => 'company', + 4 => 'tasks', ); + /** * @var array */ - public $contact = array( + public static $contact = array( 'elementType' => 1, - 'info' => 'Contact', + 'info' => 'contact', 'url' => 'contacts', 'delete' => 'contacts', ); + /** * @var array */ - public $lead = array( + public static $lead = array( 'elementType' => 2, - 'info' => 'Lead', + 'info' => 'lead', 'url' => 'leads', 'delete' => 'leads', ); + /** * @var array */ - public $note = array( - 'elementType' => null, - 'info' => 'Note', - 'url' => 'notes', - 'delete' => 'notes', + public static $company = array( + 'elementType' => 3, + 'info' => 'company', + 'url' => 'companies', + 'delete' => 'companies', ); + /** * @var array */ - public $task = array( + public static $task = array( 'elementType' => 4, 'info' => null, 'url' => 'tasks', 'delete' => 'tasks', ); + + /** + * @var array + */ + public static $note = array( + 'elementType' => null, + 'info' => 'note', + 'url' => 'notes', + 'delete' => 'notes', + ); } \ No newline at end of file diff --git a/src/Helpers/CustomField.php b/src/Helpers/CustomField.php index ed75fec..7fd7cbe 100644 --- a/src/Helpers/CustomField.php +++ b/src/Helpers/CustomField.php @@ -8,8 +8,7 @@ namespace DrillCoder\AmoCRM_Wrap\Helpers; -use DrillCoder\AmoCRM_Wrap\AmoCRM; -use DrillCoder\AmoCRM_Wrap\AmoWrapException; +use stdClass; /** * Class CustomField @@ -17,6 +16,109 @@ */ class CustomField { + /** + * Обыное текстовое поле + */ + const TYPE_TEXT = 1; + + /** + * Текстовое поле с возможностью передавать только цифры + */ + const TYPE_NUMERIC = 2; + + /** + * Поле обозначающее только наличие или отсутствие свойства (например: "да"/"нет") + */ + const TYPE_CHECKBOX = 3; + + /** + * Поле типа список с возможностью выбора одного элемента + */ + const TYPE_SELECT = 4; + + /** + * Поле типа список c возможностью выбора нескольких элементов списка + */ + const TYPE_MULTISELECT = 5; + + /** + * Поле типа дата возвращает и принимает значения в формате (Y-m-d H:i:s) + */ + const TYPE_DATE = 6; + + /** + * Обычное текстовое поле предназначенное для ввода URL адресов + */ + const TYPE_URL = 7; + + /** + * Поле textarea содержащее большое количество текста + */ + const TYPE_TEXTAREA = 9; + + /** + * Поле типа переключатель + */ + const TYPE_RADIOBUTTON = 10; + + /** + * Короткое поле адрес + */ + const TYPE_STREETADDRESS = 11; + + /** + * Поле адрес (в интерфейсе является набором из нескольких полей) + */ + const TYPE_SMART_ADDRESS = 13; + + /** + * Поле типа дата поиск по которому осуществляется без учета года, значения в формате (Y-m-d H:i:s) + */ + const TYPE_BIRTHDAY = 14; + + /** + * Рабочий телефон + */ + const PHONE_WORK = 'WORK'; + + /** + * Рабочий прямой телефон + */ + const PHONE_WORKDD = 'WORKDD'; + + /** + * Мобильный телефон + */ + const PHONE_MOB = 'MOB'; + + /** + * Факс + */ + const PHONE_FAX = 'FAX'; + + /** + * Домашний телефон + */ + const PHONE_HOME = 'HOME'; + + /** + * Другой телефон + */ + const PHONE_OTHER = 'OTHER'; + + /** + * Рабочая почта + */ + const EMAIL_WORK = 'WORK'; + /** + * Личная почта + */ + const EMAIL_PRIV = 'PRIV'; + /** + * Другая почта + */ + const EMAIL_OTHER = 'OTHER'; + /** * @var int */ @@ -36,10 +138,11 @@ class CustomField /** * CustomField constructor. - * @param int $id - * @param Value[] $values + * + * @param int $id + * @param Value[] $values * @param string|null $name - * @param bool $isSystem + * @param bool $isSystem */ public function __construct($id = 0, array $values = array(), $name = null, $isSystem = false) { @@ -50,34 +153,18 @@ public function __construct($id = 0, array $values = array(), $name = null, $isS } /** - * @param \stdClass $stdClass + * @param stdClass $data + * * @return CustomField */ - public static function loadInRaw($stdClass) + public static function loadInRaw($data) { $values = array(); - foreach ($stdClass->values as $valueStdClass) { - $values[] = Value::loadInStdClass($valueStdClass); + foreach ($data->values as $valueData) { + $values[] = Value::loadInRaw($valueData); } - return new CustomField($stdClass->id, $values, $stdClass->name, $stdClass->is_system); - } - /** - * @param string $type - * @param string|int $nameOrId - * @return int|null - * @throws AmoWrapException - */ - public static function getIdFromNameOrId($type, $nameOrId) - { - $idsCustomFields = AmoCRM::getInfo()->get("id{$type}CustomFields"); - if (array_key_exists($nameOrId, $idsCustomFields)) { - $id = $nameOrId; - } elseif (in_array($nameOrId, $idsCustomFields)) { - $id = array_search($nameOrId, $idsCustomFields); - } else - return null; - return $id; + return new CustomField($data->id, $values, $data->name, $data->is_system); } /** @@ -89,66 +176,60 @@ public function getId() } /** - * @return Value[] + * @return string */ - public function getValues() + public function getName() { - return $this->values; + return $this->name; } /** - * @return string[] + * @return bool */ - public function getArrayValues() + public function getIsSystem() { - $values = array(); - foreach ($this->values as $value) { - $values[] = $value->getValue(); - } - return $values; + return $this->isSystem; } /** - * @param Value $value - * @return CustomField + * @param Value[] $values */ - public function addValue($value) + public function setValues($values) { - $this->values[] = $value; - return $this; + $this->values = $values; } /** - * @param int $key - * @return CustomField + * @return Value[] */ - public function delValue($key) + public function getValues() { - unset($this->values[$key]); - return $this; + return $this->values; } /** - * + * @return string */ - public function delAllValues() + public function getValuesInStr() { - $this->values = array(); - } + $values = array(); + foreach ($this->getValues() as $value) { + $values[] = $value->getValue(); + } - /** - * @return bool - */ - public function getIsSystem() - { - return $this->isSystem; + return implode('; ', $values); } /** - * @return string + * @return string[] */ - public function getName() + public function getValuesInArray() { - return $this->name; + $values = array(); + foreach ($this->values as $value) { + $values[] = $value->getValue(); + } + + return $values; } } \ No newline at end of file diff --git a/src/Helpers/Info.php b/src/Helpers/Info.php deleted file mode 100644 index cfca2e9..0000000 --- a/src/Helpers/Info.php +++ /dev/null @@ -1,201 +0,0 @@ -users as $user) { - $this->usersIdAndName[$user->id] = $user->name; - } - foreach ($raw->custom_fields->contacts as $field) { - $this->idContactCustomFields[$field->id] = $field->name; - if ($field->name == 'Телефон' && $field->is_system) { - $this->phoneFieldId = $field->id; - $this->idPhoneEnums = array_flip(json_decode(json_encode($field->enums), true)); - } - if ($field->name == 'Email' && $field->is_system) { - $this->emailFieldId = $field->id; - $this->idEmailEnums = array_flip(json_decode(json_encode($field->enums), true)); - } - if ($field->field_type == 5) { - $this->idContactCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); - } - } - foreach ($raw->custom_fields->leads as $field) { - $this->idLeadCustomFields[$field->id] = $field->name; - if ($field->field_type == 4) { - $this->idLeadCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); - } - } - foreach ($raw->custom_fields->companies as $field) { - $this->idCompanyCustomFields[$field->id] = $field->name; - if ($field->field_type == 5) { - $this->idCompanyCustomFieldsEnums[$field->id] = json_decode(json_encode($field->enums), true); - } - } - foreach ($raw->pipelines as $pipeline) { - $this->pipelines[$pipeline->id]['name'] = $pipeline->name; - $this->pipelines[$pipeline->id]['statuses'] = array(); - foreach ($pipeline->statuses as $status) { - $this->pipelines[$pipeline->id]['statuses'][$status->id] = array( - 'name' => $status->name, - 'color' => $status->color - ); - } - } - foreach ($raw->task_types as $type) { - $this->taskTypes[$type->id] = $type->name; - } - } - - /** - * @param $prop - * @return mixed - * @throws AmoWrapException - */ - public function get($prop) - { - if (isset($this->$prop)) { - return $this->$prop; - } else { - throw new AmoWrapException('Параметр не найден'); - } - } - - /** - * @param int|string $pipelineIdOrName - * @return int|null - * @throws AmoWrapException - */ - public function getPipelineIdFromIdOrName($pipelineIdOrName) - { - if (array_key_exists($pipelineIdOrName, $this->pipelines)) { - return $pipelineIdOrName; - } else { - foreach ($this->pipelines as $id => $pipeline) { - if (mb_strtolower($pipeline['name']) == mb_strtolower($pipelineIdOrName)) { - return $id; - } - } - } - throw new AmoWrapException('Воронка не найдена'); - } - - /** - * @param int $idOrNamePipeline - * @param int|string $idOrNameStatus - * @return int|null - * @throws AmoWrapException - */ - public function getStatusIdFromStatusIdOrNameAndPipelineIdOrName($idOrNamePipeline, $idOrNameStatus) - { - $pipelineId = $this->getPipelineIdFromIdOrName($idOrNamePipeline); - if (array_key_exists($idOrNameStatus, $this->pipelines[$pipelineId]['statuses'])) { - return $idOrNameStatus; - } else { - foreach ($this->pipelines[$pipelineId]['statuses'] as $id => $pipeline) { - if (mb_strtolower($pipeline['name']) == mb_strtolower($idOrNameStatus)) { - return $id; - } - } - } - throw new AmoWrapException('Статус не найден'); - } - - /** - * @param int|string $userIdOrName - * @return int|null - * @throws AmoWrapException - */ - public function getUserIdFromIdOrName($userIdOrName) - { - if (array_key_exists($userIdOrName, $this->usersIdAndName)) { - return $userIdOrName; - } else { - foreach ($this->usersIdAndName as $id => $name) { - if (stripos($name, $userIdOrName) !== false) { - return $id; - } - } - } - throw new AmoWrapException('Пользователь не найден'); - } - - /** - * @return array - */ - public function getPipelines() - { - return $this->pipelines; - } -} \ No newline at end of file diff --git a/src/Helpers/Value.php b/src/Helpers/Value.php index 0fc786b..acf14d2 100644 --- a/src/Helpers/Value.php +++ b/src/Helpers/Value.php @@ -14,14 +14,46 @@ */ class Value { + /** + * Адрес. Первая строка + */ + const SUBTYPE_ADDRESS_LINE_1 = 1; + + /** + * Адрес. Вторая строка + */ + const SUBTYPE_ADDRESS_LINE_2 = 2; + + /** + * Город + */ + const SUBTYPE_CITY = 3; + + /** + * Регион + */ + const SUBTYPE_STATE = 4; + + /** + * Индекс + */ + const SUBTYPE_ZIP = 5; + + /** + * Страна. Задается кодом (Например: RU, UA, KZ, и т.д.) + */ + const SUBTYPE_COUNTRY = 6; + /** * @var string */ private $value; + /** * @var string|null */ private $enum; + /** * @var int|null */ @@ -29,91 +61,78 @@ class Value /** * Value constructor. - * @param string $value + * + * @param string $value * @param string|null $enum - * @param int|null $subtype + * @param int|null $subtype */ public function __construct($value, $enum = null, $subtype = null) { - $this->enum = (int)$enum; $this->value = $value; - switch ($subtype) { - case 1: - $subtype = 'address_line_1'; - break; - case 2: - $subtype = 'address_line_2'; - break; - case 3: - $subtype = 'city'; - break; - case 4: - $subtype = 'state'; - break; - case 5: - $subtype = 'zip'; - break; - case 6: - $subtype = 'country'; - break; - } + $this->enum = (int)$enum; $this->subtype = $subtype; } /** - * @param $stdClass + * @param $data + * * @return Value */ - public static function loadInStdClass($stdClass) - { - if (!isset($stdClass->enum)) - $stdClass->enum = null; - if (!isset($stdClass->subtype)) - $stdClass->subtype = null; - return new Value($stdClass->value, $stdClass->enum, $stdClass->subtype); - } - - /** - * @return string - */ - public function getValue() + public static function loadInRaw($data) { - return $this->value; + if (!isset($data->enum)) { + $data->enum = null; + } + if (!isset($data->subtype)) { + $data->subtype = null; + } + return new Value($data->value, $data->enum, $data->subtype); } /** - * @return null|string + * @param string $value + * + * @return Value */ - public function getEnum() + public function setValue($value) { - return $this->enum; + $this->value = $value; + return $this; } /** - * @return int|null + * @return string */ - public function getSubtype() + public function getValue() { - return $this->subtype; + return $this->value; } /** * @param string $enum + * * @return Value */ public function setEnum($enum) { $this->enum = $enum; + return $this; } /** - * @param string $value - * @return Value + * @return null|string */ - public function setValue($value) + public function getEnum() { - $this->value = $value; - return $this; + return $this->enum; + } + + /** + * @return int|null + */ + public function getSubtype() + { + return $this->subtype; } } \ No newline at end of file diff --git a/src/Lead.php b/src/Lead.php index ca8f2ee..56f619f 100644 --- a/src/Lead.php +++ b/src/Lead.php @@ -8,44 +8,51 @@ namespace DrillCoder\AmoCRM_Wrap; +use stdClass; /** * Class Lead * @package DrillCoder\AmoCRM_Wrap */ -class Lead extends Base +class Lead extends BaseEntity { /** * @var int */ - protected $statusId; + private $statusId; + /** * @var int */ - protected $sale; + private $sale; + /** * @var int */ - protected $pipelineId; + private $pipelineId; + /** * @var int */ - protected $mainContactId; + private $mainContactId; /** - * @param \stdClass $stdClass + * @param stdClass $data + * * @return Lead + * * @throws AmoWrapException */ - public function loadInRaw($stdClass) + public function loadInRaw($data) { - Base::loadInRaw($stdClass); - $this->sale = (int)$stdClass->sale; - $this->pipelineId = (int)$stdClass->pipeline->id; - $this->statusId = (int)$stdClass->status_id; - if (isset($stdClass->main_contact->id)) { - $this->mainContactId = (int)$stdClass->main_contact->id; + BaseEntity::loadInRaw($data); + $this->sale = (int)$data->sale; + $this->pipelineId = (int)$data->pipeline->id; + $this->statusId = (int)$data->status_id; + if (isset($data->main_contact->id)) { + $this->mainContactId = (int)$data->main_contact->id; } + return $this; } @@ -59,11 +66,13 @@ public function getSale() /** * @param int $sale + * * @return Lead */ public function setSale($sale) { $this->sale = $sale; + return $this; } @@ -77,30 +86,41 @@ public function getStatusId() /** * @return string - * @throws AmoWrapException */ public function getStatusName() { - $pipelines = AmoCRM::getInfo()->get('pipelines'); - return $pipelines[$this->pipelineId]['statuses'][$this->statusId]['name']; + $statuses = AmoCRM::getStatusesName($this->pipelineId); + + return $statuses[$this->statusId]; } /** - * @param int|string $idOrNamePipeline - * @param int|string $idOrNameStatus + * @param int|string $pipelineIdOrName + * * @return Lead + * * @throws AmoWrapException */ - public function setPipelineAndStatus($idOrNamePipeline, $idOrNameStatus) + public function setPipeline($pipelineIdOrName) { - $this->pipelineId = AmoCRM::getInfo()->getPipelineIdFromIdOrName($idOrNamePipeline); - if (empty($this->pipelineId)) { - throw new AmoWrapException('Не удалось задать воронку'); - } - $this->statusId = AmoCRM::getInfo()->getStatusIdFromStatusIdOrNameAndPipelineIdOrName($this->pipelineId, $idOrNameStatus); - if (empty($this->statusId)) { - throw new AmoWrapException('Не удалось задать статус'); - } + $this->pipelineId = AmoCRM::searchPipelineId($pipelineIdOrName); + + return $this; + } + + /** + * @param int|string $statusIdOrName + * @param int|string $pipelineIdOrName + * + * @return Lead + * + * @throws AmoWrapException + */ + public function setStatus($statusIdOrName, $pipelineIdOrName = null) + { + $pipelineId = $pipelineIdOrName !== null ? AmoCRM::searchPipelineId($pipelineIdOrName) : $this->pipelineId; + $this->statusId = AmoCRM::searchStatusId($pipelineId, $statusIdOrName); + return $this; } @@ -114,12 +134,12 @@ public function getPipelineId() /** * @return string - * @throws AmoWrapException */ public function getPipelineName() { - $pipelines = AmoCRM::getInfo()->get('pipelines'); - return $pipelines[$this->pipelineId]['name']; + $pipelines = AmoCRM::getPipelinesName(); + + return $pipelines[$this->pipelineId]; } /** @@ -131,12 +151,25 @@ public function getMainContactId() } /** - * @param Contact $contact + * @return Contact + * + * @throws AmoWrapException + */ + public function getMainContact() + { + return new Contact($this->mainContactId); + } + + /** + * @param Contact|string|int $contact + * * @return Lead */ public function setMainContact($contact) { - $this->mainContactId = $contact->getId(); + $id = $contact instanceof Contact ? $contact->getId() : Base::onlyNumbers($contact); + $this->mainContactId = $id; + return $this; } @@ -145,9 +178,7 @@ public function setMainContact($contact) */ public function isClosed() { - if ($this->statusId == 142 || $this->statusId == 143) - return true; - return false; + return $this->statusId === 142 || $this->statusId === 143; } /** diff --git a/src/Note.php b/src/Note.php index d0b5599..91cb2f2 100644 --- a/src/Note.php +++ b/src/Note.php @@ -8,45 +8,47 @@ namespace DrillCoder\AmoCRM_Wrap; +use stdClass; /** * Class Note * @package DrillCoder\AmoCRM_Wrap */ -class Note extends Base +class Note extends BaseEntity { /** * @var bool */ - protected $editable; + private $editable; + /** * @var string */ - protected $attachment; + private $attachment; + /** * @var string */ - protected $params; + private $service; /** * @var string */ - protected $service; + private $phone; /** - * @param \stdClass $stdClass + * @param stdClass $data + * * @return Note + * * @throws AmoWrapException */ - public function loadInRaw($stdClass) + public function loadInRaw($data) { - Base::loadInRaw($stdClass); - $this->type = (int)$stdClass->note_type; - $this->elementId = (int)$stdClass->element_id; - $this->elementType = (int)$stdClass->element_type; - $this->text = isset($stdClass->text) ? $stdClass->text : null; - $this->editable = $stdClass->is_editable; - $this->attachment = $stdClass->attachment; + BaseEntity::loadInRaw($data); + $this->editable = $data->is_editable; + $this->attachment = $data->attachment; + return $this; } @@ -68,21 +70,49 @@ public function getAttachment() /** * @param string $attachment + * * @return Note */ public function setAttachment($attachment) { $this->attachment = $attachment; + return $this; } /** * @param string $service + * * @return Note */ public function setService($service) { $this->service = $service; + + return $this; + } + + /** + * @param $phone + * + * @return $this + */ + public function setPhone($phone) + { + $this->phone = $phone; + + return $this; + } + + /** + * @param string $userId + * + * @return $this + */ + public function setCreatedUser($userId) + { + $this->createdUserId = $userId; + return $this; } @@ -96,9 +126,11 @@ protected function getExtraRaw() 'element_type' => $this->elementType, 'note_type' => $this->type, 'text' => $this->text, + 'created_by' => $this->createdUserId, 'params' => array( 'text' => $this->text, 'service' => $this->service, + 'phone' => $this->phone, ), ); } diff --git a/src/Task.php b/src/Task.php index 5be2960..e8b54c5 100644 --- a/src/Task.php +++ b/src/Task.php @@ -8,47 +8,55 @@ namespace DrillCoder\AmoCRM_Wrap; +use DateTime; +use Exception; +use stdClass; /** * Class Task * @package DrillCoder\AmoCRM_Wrap */ -class Task extends Base +class Task extends BaseEntity { /** * @var bool */ - protected $isComplete; + private $isComplete; + /** - * @var \DateTime + * @var DateTime */ - protected $completeTill; + private $completeTill; /** * Task constructor. - * @param null $amoId + * + * @param null $id + * * @throws AmoWrapException */ - public function __construct($amoId = null) + public function __construct($id = null) { - parent::__construct($amoId); - $this->completeTill = new \DateTime(); + parent::__construct($id); + + try { + $this->completeTill = new DateTime(); + } catch (Exception $e) { + throw new AmoWrapException("Ошибка в обёртке: {$e->getMessage()}", $e->getCode(), $e); + } } /** - * @param \stdClass $stdClass + * @param stdClass $data + * * @return Task * @throws AmoWrapException */ - public function loadInRaw($stdClass) + public function loadInRaw($data) { - Base::loadInRaw($stdClass); - $this->type = $stdClass->task_type; - $this->elementId = (int)$stdClass->element_id; - $this->elementType = (int)$stdClass->element_type; - $this->text = $stdClass->text; - $this->isComplete = $stdClass->is_completed; - $this->completeTill->setTimestamp($stdClass->complete_till_at); + BaseEntity::loadInRaw($data); + $this->isComplete = $data->is_completed; + $this->completeTill->setTimestamp($data->complete_till_at); return $this; } @@ -62,6 +70,7 @@ public function isIsComplete() /** * @param bool $isComplete + * * @return Task */ public function setIsComplete($isComplete) @@ -71,7 +80,7 @@ public function setIsComplete($isComplete) } /** - * @return \DateTime + * @return DateTime */ public function getCompleteTill() { @@ -79,12 +88,14 @@ public function getCompleteTill() } /** - * @param \DateTime $completeTill + * @param DateTime $completeTill + * * @return Task */ - public function setCompleteTill($completeTill) + public function setCompleteTill(DateTime $completeTill) { $this->completeTill = $completeTill; + return $this; } diff --git a/src/Unsorted.php b/src/Unsorted.php index 24c81f6..89d5bc7 100644 --- a/src/Unsorted.php +++ b/src/Unsorted.php @@ -13,83 +13,70 @@ * Class Unsorted * @package DrillCoder\AmoCRM_Wrap */ -class Unsorted +class Unsorted extends Base { - /** - * - */ - const CATEGORIES_SIP = 'sip'; - /** - * - */ - const CATEGORIES_MAIL = 'mail'; - /** - * - */ - const CATEGORIES_FORM = 'forms'; - /** - * - */ - const CATEGORIES_CHAT = 'chat'; - /** - * - */ - const ORDER_BY_ASC = 'asc'; - /** - * - */ - const ORDER_BY_DESC = 'desc'; /** * @var int */ - protected $id; + private $id; + /** * @var string */ - protected $formName; + private $formName; + /** * @var int */ - protected $pipelineId; + private $pipelineId; + /** * @var Contact[]|array */ - protected $contacts = array(); + private $contacts = array(); + /** * @var Lead|array */ - protected $lead = array(); + private $lead = array(); + /** * @var Company[]|array */ - protected $companies = array(); + private $companies = array(); + /** * @var Note[] */ - protected $notes; + private $notes; /** - * Unsorted constructor. - * @param string $formName - * @param Contact[] $contacts - * @param Lead $lead - * @param int|string $pipelineIdOrName - * @param Company[] $companies + * @param string $formName + * @param Contact[] $contacts + * @param Lead $lead + * @param int|string|null $pipeline + * @param Company[] $companies + * * @throws AmoWrapException */ - public function __construct($formName, $lead, $contacts = array(), $pipelineIdOrName = null, $companies = array()) + public function __construct($formName, $lead, $contacts = array(), $pipeline = null, $companies = array()) { + if (!AmoCRM::isAuthorization()) { + throw new AmoWrapException('Требуется авторизация'); + } + $this->contacts = $contacts; $this->lead = $lead; $this->companies = $companies; $this->formName = $formName; - if (!empty($pipelineIdOrName)) { - $this->pipelineId = AmoCRM::getInfo()->getPipelineIdFromIdOrName($pipelineIdOrName); + if ($pipeline !== null) { + $this->pipelineId = AmoCRM::searchPipelineId($pipeline); } } /** * @return Unsorted + * * @throws AmoWrapException */ public function save() @@ -114,7 +101,7 @@ public function save() } $request['add'] = array( array( - 'source_name' => 'AmoCRM Wrap by Drill', + 'source_name' => 'DrillCoder AmoCRM Wrap', 'created_at' => date('U'), 'pipeline_id' => $this->pipelineId, 'incoming_entities' => array( @@ -129,7 +116,7 @@ public function save() ), ); $response = AmoCRM::cUrl('api/v2/incoming_leads/form', $request); - if ($response->status == 'success') { + if ($response !== null && $response->status === 'success') { $this->id = $response->data[0]; return $this; } @@ -139,8 +126,10 @@ public function save() /** * @param string $text - * @param int $type + * @param int $type + * * @return Unsorted + * * @throws AmoWrapException */ public function addNote($text, $type = 4)