Часто в процессе разработки сталкиваемся с задачей скрывать те или иные поля в зависимости от значения поля. На рынке есть много модулей, которые без необходимости программирования делают эту функцию, но они работают на яваскрипте. Т.е. поля скрываются только после полной загрузки страницы. Это доставляет и определённые неудобства пользователям и создаёт дополнительную нагрузку на систему.
Поэтому я решил поделиться простым способом скрытия полей на уровне php. К счастью, это очень просто и быстро. Всё, что вам потребуется создать 1 новый файл и внести небольшие изменения в два существующих файла.
Для примера, давайте представим такую задачу - нам нужно показывать определённый набор полей в зависимости от того, какой статус сделки на данный момент.
Во-первых, давайте создадим конфигурационный файл, где будем хранить массив полей, которые мы будем разрешать к показу для модуля Сделки.
Создадим в корне файл vtiger_detailview_list.php со следующим содержимым
<?php
$detailview_list = array(
'Potentials' => [
'checkField' => 'cf_1269',
'checkValue' => 'Submission Received',
'allowedFields' => [
'potentialname', 'potential_no', 'cf_1269', 'cf_3709', 'cf_3713', 'cf_3867', 'cf_4368', 'cf_3711', 'cf_4421', 'forecast_amount', 'cf_1926'
]
]
);
Чтобы массив с конфигурацией был доступен в качестве глобальной переменной, нужно импортировать этот файл в конфигурационный файл config.inc.php
require_once 'vtiger_detailview_list.php';
Что из себя представляет конфигурационный файл? Это многомерный массив, разделённый по модулям. Ключ первого уровня - название модуля. В нём мы описываем, какое поле мы проверяем в ключе checkField (его системное наименование) и его значение в ключе checkValue. Далее в allowedFields описываем перечень полей, которые мы разрешаем к показу
Непосредственно само скрытие происходит в файле modules/Vtiger/models/DetailRecordStructure.php .
Здесь нам потребуется добавить функцию:
protected function isFieldAllowed(string $fieldName, ?Vtiger_Record_Model $record): bool
{
global $detailview_list;
if (!$record) {
return true;
}
if (!isset($detailview_list[$record->getModuleName()]['checkField'])) {
return true;
}
$fieldValue = $record->get($detailview_list[$record->getModuleName()]['checkField']);
if ($fieldValue === $detailview_list[$record->getModuleName()]['checkValue']) {
return in_array($fieldName, $detailview_list[$record->getModuleName()]['allowedFields'], true);
}
return true;
}
Далее в функции getStructure, в районе строчки 39 переписать условие. Вместо
if($fieldModel->isViewableInDetailView())
заменить
if($fieldModel->isViewableInDetailView() && $this->isFieldAllowed($fieldName, $recordModel))
И этого достаточно. Теперь если статус сделки "Submission Received", то в карточке мы будем видеть только те поля, которые прописали в массиве. Конечно, этот способ не защищает нас от отображения полей в режиме редактирования или отображения в общем списке, но общий подход, надеюсь, понятен.