Как добавить вывод картинок и документов в API VtigerCRM

Как добавить вывод картинок и документов в API VtigerCRM

Как я уже писал ранее, Vtiger предоставляет удобный API по получению данных из CRM. Можно одним запросом достать и отфильтровать данные по любому модулю, получить связанные записи и прочее.

Однако, в стандартном API VtigerCRM есть один недостаток - нельзя получить, например, аватар контакта и связанные документы.

В этой статье я расскажу вам, как можно доработать стандартный API VtigerCRM, добавив в него возможность вывода привязанной к модулю картинки или связанных документов.

Давайте посмотрим, как у нас выводится картинка из контакта или товаров. В классе Vtiger_Record_Model у нас есть метод getImageDetails, который выдаёт нам всю информацию по аватару. По этой информации можно выстроить URL и получить нужный нам файл.

Аналогичным образом мы можем получить и список привязанных документов. В классе Vtiger_Record_Model есть метод getFileDetails. С его помощью мы можем получить массив привязанных к записи модуля документов.

Т.е. аватар или привязанные файлы создаются унифицированным образом. Но что делать, если вы хотите включить выдачу файлов и изображений только для определённых модулей, а не для всех. Нагружать API ненужными данными и запросами к базе - плохая идея.

Я нашёл следующий вариант. Добавляем два поля к нужному нам модулю:

  • image_avatar - если мы хотим выводить аватар записи.
  • images_list - если мы хотим выводить список связанных документов.

Эти поля будут системными. Обычно для этих целей я делаю отдельный блок, называю его "System Information" помещаю туда все поля, которые не должен видеть пользовать и скрываю его из системы.

Сделать это очень просто. Для этого переходим в файл modules/Vtiger/models/Block.php

В начале класса (строчка 14) Vtiger_Block_Model добавляем константу

 

public const SYSTEM_INFORMATION_LABEL = 'System Information';

 

Затем в функции getAllForModule (после строчки 118) в цикле foreach($blockObjects as $blockObject) 

находим строчку 

$blockModelList[] = self::getInstanceFromBlockObject($blockObject);

и меняем её на следующую:

    $blockModel = self::getInstanceFromBlockObject($blockObject);

    if ($blockModel->label === self::SYSTEM_INFORMATION_LABEL) {

        continue;

                }

$blockModelList[] = $blockModel;

 

Таким образом, если блок называется System Information, вы можете его полностью скрыть от пользователей. При необходимости можно добавить дополнительное условие и показываеть блок только администратору.

Переходим к следующему шагу. Создадим отдельный класс, который будем передавать нам список файлов и изображений. Создадим специальный сервис. Создаём файл modules/Vtiger/services/ImageReceiver.php со следующим содержимым:

 

<?php

class Vtiger_ImageReceiver_Service
{
public const AVATAR_FIELD = 'image_avatar';

public const DOCUMENTS_FIELD = 'images_list';

protected string $column;

protected ?string $value;

protected int $record_id;

public function __construct(int $record_id, string $column, ?string $value)
{
$this->record_id = $record_id;
$this->column = $column;
$this->value = $value;
}

public function getAvatar(): array
{
if ($this->record_id < 1) {
return [];
}
/** @var Contacts_Record_Model $recordModel */
$recordModel = Vtiger_Record_Model::getInstanceById($this->record_id);
if (!$recordModel) {
return [];
}
return $recordModel->getImageDetails();
}

public function getImages(): array
{
if ($this->record_id < 1) {
return [];
}
/** @var Vtiger_Record_Model $recordModel */
$recordModel = Vtiger_Record_Model::getInstanceById($this->record_id);
if (!$recordModel) {
return [];
}
return $recordModel->getFileDetails();
}
}

 

Теперь нам остаётся подключить этот класс к Vtiger. Переходим в файл include/Webservices/DataTransform.php и в самом начале этого файла подключаем наш класс, добавляя строчку:

require_once 'modules/Vtiger/services/ImageReceiver.php';

 

И затем в функции sanitizeDataWithColumn в самом её конце перед строчкой 

 

return $newRow;

 

добавляем следующий блок 

if (array_key_exists(Vtiger_ImageReceiver_Service::AVATAR_FIELD, $row)) {
$receiverService = new Vtiger_ImageReceiver_Service((int) $row[$meta->getIdColumn()], Vtiger_ImageReceiver_Service::AVATAR_FIELD, $row[Vtiger_ImageReceiver_Service::AVATAR_FIELD]);
$newRow['avatar'] = $receiverService->getAvatar();
}
if (array_key_exists(Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD, $row)) {
$receiverService = new Vtiger_ImageReceiver_Service((int) $row[$meta->getIdColumn()], Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD, $row[Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD]);
$newRow['images'] = $receiverService->getImages();
}

 

Таким образом, если вы захотите теперь получить список контактов, в выводе API у вас добавится следующий массив:

 

"avatar": [

        {

          "id": "74",

          "orgname": "2021-06-28_10-30.png",

          "path": "storage\/2021\/August\/week1\/74",

          "name": "2021-06-28_10-30.png",

          "url": "http:\/\/crm.kindergou.test\/public.php?fid=74&key=2021-06-28_10-30.png"

        }

      ],

"images": [

        {

          "0": "74",

          "attachmentsid": "74",

          "1": "2021-06-28_10-30.png",

          "name": "2021-06-28_10-30.png",

          "2": "",

          "description": "",

          "3": "image\/png",

          "type": "image\/png",

          "4": "storage\/2021\/August\/week1\/",

          "path": "storage\/2021\/August\/week1\/",

          "5": "89061811daaad0ac66dd2dfa0d331903.png",

          "storedname": "89061811daaad0ac66dd2dfa0d331903.png",

          "6": null,

          "subject": null,

          "7": "70",

          "crmid": "70",

          "8": "74"

        }

      ]

 

Здесь стоит иметь в виду, что это сработает только в выводе списка записей модуля. Если вы хотите получить картинки при запросе записи по id, то добавьте таким же образом код в функцию filterAndSanitize:

 

if (array_key_exists(Vtiger_ImageReceiver_Service::AVATAR_FIELD, $row)) {
$receiverService = new Vtiger_ImageReceiver_Service((int) vtws_getCRMEntityId($row['id']), Vtiger_ImageReceiver_Service::AVATAR_FIELD, $row[Vtiger_ImageReceiver_Service::AVATAR_FIELD]);
$row['avatar'] = $receiverService->getAvatar();
}
if (array_key_exists(Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD, $row)) {
$receiverService = new Vtiger_ImageReceiver_Service((int) vtws_getCRMEntityId($row['id']), Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD, $row[Vtiger_ImageReceiver_Service::DOCUMENTS_FIELD]);
$row['images'] = $receiverService->getImages();
}

 

В качестве бонуса выкладываю скрипт по добавлению поля images_list в модуль Contacts. Поместите его в папку scripts и запустите:

<?php

/*
* Скрипт добавляет поле в модуль через API тигры.
* Удобно тем, что можно задать понятное название поле вместо стандартного cf_3443
* Также используется для создания одинаковых полей между девом и продом. Один и тот же скрипт запускается на деве и проде.
* Скрипты для удобство класть в vtiger/scripts/
* Перед запуском проверить, чтобы у файла были полномочия на запуск от сервере апаче
* Перед запуском проверить путь к файлам, которые добавлены через require_once
* Для правильного пути добавлена функция chdir('../')
*/


$Vtiger_Utils_Log = true;
chdir('../');
require_once('vtlib/Vtiger/Menu.php');
require_once('vtlib/Vtiger/Module.php');
require_once('vtlib/Vtiger/Block.php');
require_once('vtlib/Vtiger/Field.php');
$module = Vtiger_Module::getInstance('Contacts'); // Имя модуля из таблицы vtiger_tab
if ($module) {
$block = Vtiger_Block::getInstance('LBL_CUSTOM_INFORMATION', $module); // Название блока из таблицы vtiger_blocks
if ($block) {
$field = Vtiger_Field::getInstance('images_list', $module); // Название поля без пробелов через нижнее подчеркивание
if (!$field) {
$field = new Vtiger_Field();
$field->name = 'images_list'; // Название поля без пробелов через нижнее подчеркивание
$field->table = $module->basetable;
$field->label = 'LBL_IMAGES_LIST'; // Лейбл на английском. Переводить на русский через файлы-переводов.
$field->column = 'images_list'; // Название поля без пробелов через нижнее подчеркивание
$field->columntype = 'VARCHAR(255)'; // Посмотреть тип у похожих полей в таблице vtiger_навание-модуля

// Посмотреть тип у похожих полей в таблице vtiger_field
// 1 - текстовое поле
// 15 - поле-список)
$field->uitype = 1;

$field->displaytype = 1; // Посмотреть тип у похожих полей в таблице vtiger_field

// Посмотреть тип у похожих полей в таблице vtiger_field
// V~O~LE~100 - текстовое поле
// V~O - поле список
$field->typeofdata = 'V~O~LE~100';

$field->presence = 2; // Посмотреть тип у похожих полей в таблице vtiger_field
$field->quickcreate = 1; // Посмотреть тип у похожих полей в таблице vtiger_field
$field->generatedtype = 2; // Посмотреть тип у похожих полей в таблице vtiger_field
$block->addField($field);

//Для создания поля-списка раскомментировать эти две строки и прописать значения на английском. Переводить на русский через файлы-переводов.
//$pickListValues = array('Active', 'Inactive', 'Standby');
//$field->setPicklistValues($pickListValues);

echo "Поле успешно добавлено.";
}
} else {
echo "Не найден блок. Сверьте название блока в таблице vtiger_blocks.";
}
} else {
echo "Не найден модуль. Сверьте название модуля в таблице vtiger_tab.";
}

?>

Если у вас остались вопросы или дополнительные потребности в доработке API VtigerCRM - обращайтесь.

Популярное

Самые популярные посты

Как быть максимально продуктивным на удалённой работе?
Business

Как быть максимально продуктивным на удалённой работе?

Я запустил собственный бизнес и намеренно сделал всё возможное, чтобы работать из любой точки мира. Иногда я сижу с своём кабинете с большим 27-дюймовым монитором в своей квартире в г. Чебоксары. Иногда я нахожусь в офисе или в каком-нибудь кафе в другом городе.

Привет! Меня зовут Сергей Емельянов и я трудоголик
Business PHP

Привет! Меня зовут Сергей Емельянов и я трудоголик

Я программист. В душе я предприниматель. Я начал зарабатывать деньги с 11 лет, в суровые 90-е годы, сдавая стеклотару в местный магазин и обменивая её на сладости. Я зарабатывал столько, что хватало на разные вкусняшки.

Акция! Профессиональный разработчик CRM за 2000 руб. в час

Выделю время под ваш проект. Знания технологий Vtiger CRM, SuiteCRM, Laravel, Vue.js, Golang, React.js. Предлагаю варианты сотрудничества, которые помогут вам воспользоваться преимуществами внешнего опыта, оптимизировать затраты и снизить риски. Полная прозрачность всех этапов работы и учёт временных затрат. Оплачивайте только рабочие часы разработки после приемки задачи. Экономьте на платежах по его содержанию разработчика в штате. Возможно заключение договора по ИП. С чего начать, чтобы нанять профессионального разработчика на full-time? Просто заполните форму!

Telegram
@sergeyem
Telephone
+4915211100235