В этой заметке расскажу как красиво вывести множественное свойство типа файл в инфоблоке 1С-Битрикс. С показом оригинального названия файла, его транслитированной версии, размера файла в килобайтах и, само собой, ссылкой на скачивание.
Исходные данные для вывода файлов
Итак, в инфоблоке каталога сайта имеем стандартное, множественное свойство "типа файл" с кодом "FILES".

Если мы его выведем, штатным способом, через вывод свойств- как оно задумано в Битрикс изначально. Выглядеть это будет не казисто и не интересно

Абсолютно не интересно и самое главное не информативно. В моем случае, в данное свойство загружаются документы. Причем они в разных форматах и разного размера. Пользователь должен видеть и название документа и его размер с форматом. Например вот так:

Выводим свойство файл через API Битрикс- получая все данные о файлах
Все достаточно просто, так как множественные свойства это обычные массивы. Мы можем получить все данные о каждом файле, просто зная код свойства, в моем случае "FILES". Выглядеть foreach будет следующим образом.
<?foreach($arResult["DISPLAY_PROPERTIES"]['FILES']['FILE_VALUE'] as $pid=>$arProperty):?>
<?
//echo '<pre>';print_r($arProperty);echo '</pre>';
echo $arProperty['FILE_SIZE']; //размер файла в байтах
echo $arProperty['FILE_NAME']; //Транслитированное название файла
echo $arProperty['ORIGINAL_NAME']; //Оригинальное название файла
echo $arProperty['SRC']; //Ссылка на скачивание
>
<?endforeach?>
Расскоментировав строку
// echo '<pre>';print_r($arProperty);echo '</pre>';
Вы сможете увидеть все данные о каждом файле, доступные для вывода. По мимо основных, там есть и дата загрузки и тип файла.
В принципе и все. Конкретно в моем случае, в примере выше, результат вывода выглядет следующим образом:
<? foreach ($arResult["DISPLAY_PROPERTIES"]['FILES']['FILE_VALUE'] as $pid => $arProperty): ?>
<a
href="<? echo $arProperty['SRC']; ?>"
title="Скачать <? echo $arProperty['FILE_NAME']; ?>">
<strong>
<? echo $arProperty['ORIGINAL_NAME']; ?>
<span> —
<?
$strKb = $arProperty['FILE_SIZE']/1024;
echo round($strKb) . ' Кб';
?>
</span>
</strong>
<i>
<? echo $arProperty['FILE_NAME']; ?>
</i>
</a>
<? endforeach ?>
Несколько полезных моментов
Байты в килобаты (размер файла), я привратил, обычной php функцией округления в большую сторону round. Предварительно приведя байты в килобаты. просто разделив $arProperty['FILE_SIZE'] на 1024 (смотри в коде выше).
Иконки для разных типов файлов, назначил через CSS - тут простая стилизация. Зная расширение файла, а точнее расширенеие на которое заканчивается ссылка, просто прописал background для каждой разновидности ссылки. Вот так:
a[href$=".doc"],
a[href$=".docx"],
a[href$=".rtf"] {
background: url("img/doc.png");
}
a[href$=".pdf"] {
background: url("img/pdf.png");
}
a[href$=".xls"],
a[href$=".xlsx"] {
background: url("img/exl.png");
}
Дополнено: вывод файла для catalog.element
Так как в компоненте и шаблоне catalog.element доступна информация, только для ID файла - те же самые данные (из текста выше), мы можем получить методом CFile::GetFileArray(). Просто передав в него ID файла.
Пример:
foreach ($arResult["PROPERTIES"]['FILES']['VALUE'] as $pid => $arProperty):
$arFile = CFile::GetFileArray($arProperty);
print_r($arFile);// Распечатка всего массива
endforeach
Код |
---|
<?if(count($arItem["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["SRC"]) == 1):?> <a href="<?echo $arItem["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["SRC"]?>" class="file" target="_blank" style="margin-top: 0" > <strong> <?echo $arItem["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["ORIGINAL_NAME"] ?> <span> — <?= round((intval($arItem["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["FILE_SIZE"]) / 1024), 1); ?> Кб </span> </strong> <br> <i> <?echo $arItem["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["FILE_NAME"] ?> </i> </a> <?else:?> <? foreach ($arItem["DISPLAY_PROPERTIES"]['FILES']['FILE_VALUE'] as $pid => $arProperty): ?> <a href="<? echo $arProperty['SRC']; ?>" class="file" title="Скачать <? echo $arProperty['FILE_NAME']; ?>"> <strong> <? echo $arProperty['ORIGINAL_NAME']; ?> <span> — <? $strKb = $arProperty['FILE_SIZE']/1024; echo round($strKb) . ' Кб'; ?> </span> </strong> <br> <i> <? echo $arProperty['FILE_NAME']; ?> </i> </a> <br> <?endforeach;?> <?endif?> |
Сергей, спасибо за не менее важное дополнение!
Для вывода списка файлов на детальной странице комплексного компонента catalog у меня получился такой код:
Код |
---|
<?if(count($arResult["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["SRC"]) == 1):?> <a href="<?echo $arResult["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["SRC"]?>" class="file" target="_blank" style="margin-top: 0" > <strong> <?echo $arResult["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["ORIGINAL_NAME"];?> <span> — <?= round((intval($arResult["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["FILE_SIZE"]) / 1024), 1); ?> Кб</span> </strong> <br> <i><?echo $arResult["DISPLAY_PROPERTIES"]["FILES"]["FILE_VALUE"]["FILE_NAME"] ?></i> </a> <?else:?> <?foreach ($arResult["DISPLAY_PROPERTIES"]['FILES']['FILE_VALUE'] as $pid => $arProperty):?> <a href="<? echo $arProperty['SRC'];?>" title="Скачать <? echo $arProperty['FILE_NAME'];?>"> <strong> <? echo $arProperty['ORIGINAL_NAME'];?> <span> —<?$strKb = $arProperty['FILE_SIZE']/1024; echo round($strKb) . ' Кб';?></span> </strong> <i><? echo $arProperty['FILE_NAME'];?></i> </a> <br> <?endforeach?> <?endif;?> |

Что бы это сделать можно воспользоваться методом
CFile::GetFileArray
В параметр передаем ID нужного файла или переменную с нужным ID и классом DateTime
приводим к строке:
Код |
---|
<? $arItem = 123; // ID нужного файла $rsFile = CFile::GetFileArray($arItem); echo $rsFile['TIMESTAMP_X']->toString(); ?> |
Распечатываем массив
Код |
---|
<? print_r($rsFile); ?> |
код не работает - если элемент один загружен.
как быть, есть загружаю во множественное поле только один элемент?
Цитата |
---|
Damir написал: Добрый день код не работает - если элемент один загружен. как быть, есть загружаю во множественное поле только один элемент? |
Damir имел в виду скорее всего что с переходом в добровольно-принудительном порядке битрикса на php8, данный код перестал выводить одиночно загруженные файлы. Ругается на
count(): Argument #1 ($value) must be of type Countable|array, string given (0)
Ситуация как кажется на первый взгляд проще некуда. Есть свойство типа файл, множественное, "PHOTOS_OBJECT", компонент комплексный news, вывожу в деталке.
Может содержать в себе как одно так и несколько значений и все варианты значений должны работать в слайдере футурамы, все работало, до того как "пришли они" со своей 8-кой.
Вот моя конструкция:
Код |
---|
<div class="fotorama" data-transition="crossfade" data-allowfullscreen="native" data-nav="thumbs" data-width="100%" data-minheight="300" data-ratio="1500/1000"> <//? var_dump ($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"]);?> <?if (count($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"]) > 1) { ?> <?if (is_array($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"])) : ?> <?foreach($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"] as $pid=>$arProperty):?> <img width="356" alt="<?echo $arProperty["ORIGINAL_NAME"];?>" src="<?echo $arProperty["SRC"];?>" height="200" title="<?echo $arProperty["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?endforeach;?> <?endif;?> <?}{?> <img width="356" alt="<?echo $arResult["ORIGINAL_NAME"];?>" src="<?echo $arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["VALUE"]["SRC"];?>" height="200" title="<?echo $arResult["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?}?> </div> |
Сколько только вариантов уже не перепробовал, выводит фотку в слайдере или где одно значение, или где несколько, поочередности, вместе вообще никак не хотят дружить...
Код |
---|
<?if (count($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"]) > 1) { ?> <?if (is_array($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"])) : ?> <?foreach($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"] as $pid=>$arProperty):?> <img width="356" alt="<?echo $arProperty["ORIGINAL_NAME"];?>" src="<?echo $arProperty["SRC"];?>" height="200" title="<?echo $arProperty["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?endforeach;?> <?else:?> <img width="356" alt="<?echo $arResult["ORIGINAL_NAME"];?>" src="<?echo $arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"];?>" height="200" title="<?echo $arResult["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?endif;?> <?}?> |

В целом если использовали проверку count для массивов (не только в случае этой заметки)
Что бы не получать ошибку типа array must be of type Countable|array, string given (0)
проверяем вот так:
Код |
---|
if(count((array)$вашМассив) > 1){ .... } |
Вместо:
Код |
---|
if(count($вашМассив) > 1){ .... } |

Вот так все заработало как положено:
Код |
---|
<div class="fotorama" data-transition="crossfade" data-allowfullscreen="native" data-nav="thumbs" data-width="100%" data-minheight="300" data-ratio="1500/1000"> <?if(count((array)$arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"]["SRC"]) == 1):?> <img width="356" alt="<?echo $arResult["ORIGINAL_NAME"];?>" src="<?echo $arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"]["SRC"];?>" height="200" title="<?echo $arResult["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?else:?> <?foreach($arResult["DISPLAY_PROPERTIES"]["PHOTOS_OBJECT"]["FILE_VALUE"] as $pid=>$arProperty):?> <img width="356" alt="<?echo $arProperty["ORIGINAL_NAME"];?>" src="<?echo $arProperty["SRC"];?>" height="200" title="<?echo $arProperty["ORIGINAL_NAME"];?>" class="foto-in-objects"> <?endforeach;?> <?endif?> </div> |