Короткая памятка по реальному кейсу: как правильно сохранить файлы в Highloadblock, чтобы они отображались в админке, а не просто лежали в b_file.
1. Подготовка поля в HL
В HL-блоке создайте пользовательское поле:
- Код:
UF_PHOTO(пример) - Тип:
Файл - Множественное:
Да(если нужно несколько файлов)
Если поле не множественное, передача массива файлов вызовет ошибку вида:
Поле "Фото" не может быть множественным.
2. Главная идея
Для UF-поля типа file в HL важно передавать правильный формат.
Рабочий формат для множественного поля:
- сначала сохранить файл через
CFile::SaveFile(...)и получить$fileId - затем для
UF_PHOTOпередать массивCFile::MakeFileArray($fileId)
3. Пример: множественная загрузка файлов в Highloadblock
use Bitrix\Highloadblock\HighloadBlockTable;
$hlBlock = HighloadBlockTable::getById($hlBlockId)->fetch();
$entity = HighloadBlockTable::compileEntity($hlBlock);
$dataClass = $entity->getDataClass();
$filesForUf = array();
foreach ($uploadedFiles as $file) {
// $file в формате из $_FILES: name, type, tmp_name, error, size
$fileId = (int)CFile::SaveFile($file, 'questionnaire');
if ($fileId <= 0) {
throw new \RuntimeException('Не удалось сохранить файл');
}
$fileArray = CFile::MakeFileArray($fileId);
if (!is_array($fileArray)) {
throw new \RuntimeException('Не удалось подготовить файл для UF-поля');
}
$filesForUf[] = $fileArray;
}
$result = $dataClass::add(array(
'UF_USER_NAME' => (string)$userName,
'UF_PHOTO' => $filesForUf,
));
if (!$result->isSuccess()) {
throw new \RuntimeException(implode('; ', $result->getErrorMessages()));
}
4. Пример: одиночный файл в Highloadblock
$fileId = (int)CFile::SaveFile($file, 'questionnaire');
if ($fileId <= 0) {
throw new \RuntimeException('Не удалось сохранить файл');
}
$fileForUf = CFile::MakeFileArray($fileId);
$result = $dataClass::add(array(
'UF_DOCUMENT' => $fileForUf,
));
5. Валидация: разрешать только изображения
Можно настроить в админке, можно минимально безопасно проверять на сервере:
private function isImageFile(array $file)
{
if (empty($file['tmp_name'])) {
return false;
}
$imageCheckError = CFile::CheckImageFile($file);
if (is_string($imageCheckError) && $imageCheckError !== '') {
return false;
}
return @getimagesize($file['tmp_name']) !== false;
}
И в шаблоне формы:
<input type="file" name="attachments[]" multiple accept="image/*">
6. Что проверить, если файлы не видно в админке
- Поле точно типа
Файл? - Множественность поля совпадает с тем, что отправляете?
- В
add()/update()передается именно форматCFile::MakeFileArray(...)? - Файл реально попадает в
b_file(естьfileId> 0)?
Если коротко: для HL-поля типа file чаще всего надежный путь — SaveFile -> MakeFileArray -> UF_FIELD.