digitalwand.admin_helper
digitalwand.admin_helper copied to clipboard
Проблема с типом Дата со временем
class CourseAdminInterface extends AdminInterface {
public function fields() {
return array(
'MAIN' => array(
'FIELDS' => array(
"UF_DATE_LESSON" => array(
'WIDGET' => new HLIBlockFieldWidget()
)
))
);
}
public function helpers() {
return array(
'\Pam\HLcourse\Course\AdminInterface\CourseListHelper',
'\Pam\HLcourse\Course\AdminInterface\CourseEditHelper'
);
}
}
UF_DATE_LESSON является типом Дата со временем в HighLoad ИБ, множественным и не объязательным. При сохранение нового элемента в сгнерированной админке появляется сообщение Значение поля «UF_DATE_LESSON» не является корректной датой/временем. При этом само поле может быть пустым или заполеным датой из календаря. Я только смог понять что не србатывает CheckFields
По хайлоад-блокам лучше к @ASGAlex, он делал интеграцию с ними.
Поправил виджет сам. CheckFields для CUserTypeDateTime не может принимать массив, когда множественное значение. Плюс не надо запускать для этого класса modifyValueBeforeSave
if (is_callable(array($className, 'CheckFields'))) {
if (!is_array($value)) {
$arrValue = array($value);
}
else {
$arrValue = $value;
}
foreach ($arrValue as $checkValue) {
$errors = $className::CheckFields($fieldInfo, $checkValue);
if (!empty($errors)) {
$this->addError($errors);
return;
}
}
}
// use save modifiers
$field = $entity_data_class::getEntity()->getField($this->getCode());
if ($fieldInfo['USER_TYPE']['CLASS_NAME'] != 'CUserTypeDateTime') $value = $field->modifyValueBeforeSave($value, $data);
У меня устранение $value = $field->modifyValueBeforeSave($value, $data);
не решает проблему: при сохранении множественной даты с полем без значения всё равно выскакивает ошибка. $value и в том и в другом случае будет array(0 => "")
, ошибка появится.
для этого выше идёт foreach
для перебора массива. И ещё, я выставил в настройках HL ИБ семь обязательных полей, так и в function fields()
прописал у них 'REQUIRED' => true
, но при сохранение ошибка пишится только для трёх полей, и если их заполнить, то ошибок больше не возникает, а если повтроно редактировать элемент, то можно даже стереть информацию в этих полях и сохранить, и ошибок не возникнет. Нет ошибок для Привязка к разделам инф. блоков и привязка к пользователю и список. Правда так же происходит при создании эдемента в маом HL ИБ
в итоге немного исправленный метод processEditAction в HLIBlockFieldWidget выглядит у меня так.
public function processEditAction() {
/** @var \CAllUserTypeManager $USER_FIELD_MANAGER */
global $USER_FIELD_MANAGER;
$iblockId = 'HLBLOCK_' . $this->getHLId();
//Чтобы не терялись старые данные
if (!isset($this->data[$this->getCode()]) AND isset($_REQUEST[$this->getCode() . '_old_id'])) {
$this->data[$this->getCode()] = $_REQUEST[$this->getCode() . '_old_id'];
}
//Функция работает для всех полей, так что запускаем её только один раз, результат кешируем.
static $data = array();
if (empty($data)) {
$data = $this->data;
$USER_FIELD_MANAGER->EditFormAddFields($iblockId, $data);
}
$value = $data[$this->getCode()];
$entity_data_class = AdminBaseHelper::getHLEntity($this->getSettings('MODEL'));
$oldData = $this->getOldFieldData($entity_data_class);
$fieldsInfo = $USER_FIELD_MANAGER->getUserFieldsWithReadyData($iblockId, $oldData, LANGUAGE_ID, false, 'ID');
$fieldInfo = $fieldsInfo[$this->getCode()];
$className = $fieldInfo['USER_TYPE']['CLASS_NAME'];
if (is_callable(array($className, 'CheckFields'))) {
if (!is_array($value)) {
$arrValue = array($value);
}
else {
$arrValue = $value;
}
foreach ($arrValue as $checkValue) {
$errors = $className::CheckFields($fieldInfo, $checkValue);
if (!empty($errors)) {
$this->addError($errors);
return;
}
}
}
// use save modifiers
$field = $entity_data_class::getEntity()->getField($this->getCode());
//hack для множественных значений Дата и Дата со временем
if ($fieldInfo['USER_TYPE']['CLASS_NAME'] != 'CUserTypeDateTime' && $fieldInfo['USER_TYPE']['CLASS_NAME'] != 'CUserTypeDate') $value = $field->modifyValueBeforeSave($value, $data);
//Типоспецифичные хаки
if ($unserialized = unserialize($value)) {
//Список значений прилетает сериализованным
$this->data[$this->getCode()] = $unserialized;
}
else if ($className == 'CUserTypeFile' AND ! is_array($value)) {
//Если не сделать intval, то при сохранении с ранее добавленным файлом будет выскакивать ошибка
$this->data[$this->getCode()] = intval($value);
}
else {
//Все остальные поля - сохраняем как есть.
$this->data[$this->getCode()] = $value;
}
}