@Akorolev

Как встроить \Bitrix\Main\UI\FileInput в iblock.element.add.form?

Как встроить \Bitrix\Main\UI\FileInput в iblock.element.add.form вместо <input type="file" />?
  • Вопрос задан
  • 5654 просмотра
Решения вопроса 1
@PetrPo
Привет.
Раньше не доводилось такого делать, пришлось ядро расковырять...
По всей видимости без кастома компонента не получится. Когда через стандартное поле type=file грузишь, то данные о файле попадают в массив $_FILES где есть tmp_name - полный путь к временному файлу, а при использовании \Bitrix\Main\UI\FileInput в $_REQUEST где тоже есть tmp_name но с обрезанным значением
5e316661c6ca9430784855.jpeg

должно быть
5e316675706e8091370218.jpeg

В компоненте вызывается CIBlockElement::Add дальше -
CIBlockElement::Add --> CFile::CheckImageFile --> CFile::GetImageSize($arFile["tmp_name"], true, $flashEnabled)

вот в последней функции и происходит косяк, если tmp_name не полный (полный путь можно получить с помощью CIBlock::makeFileArray)

Пример кастома компонента (тестировал только для PREVIEW_PICTURE):
1. В файле component.php найди проверку
if($arResult["PROPERTY_LIST_FULL"][$propertyID]["PROPERTY_TYPE"] == "F")

замени
$arFile = $_FILES["PROPERTY_FILE_".$propertyID."_0"];
на
$arFile = ($_FILES["PROPERTY_FILE_".$propertyID."_0"] ? $_FILES["PROPERTY_FILE_".$propertyID."_0"] : CIBlock::makeFileArray($_REQUEST["PROPERTY_FILE_".$propertyID."_0"]));

2. В шаблоне template.php замени весь case "F":
for ($i = 0; $i<$inputNum; $i++)
{
	$name = 'PROPERTY_FILE_'.$propertyID.'_'.($arResult["ELEMENT_PROPERTIES"][$propertyID][$i]["VALUE_ID"] ? $arResult["ELEMENT_PROPERTIES"][$propertyID][$i]["VALUE_ID"] : $i);
	$value = intval($propertyID) > 0 ? $arResult["ELEMENT_PROPERTIES"][$propertyID][$i]["VALUE"] : $arResult["ELEMENT"][$propertyID];

	echo \Bitrix\Main\UI\FileInput::createInstance(array(
		"name" => $name,
		"description" => true,
		"upload" => true,
		"allowUpload" => "I",
		"medialib" => true,
		"fileDialog" => true,
		"cloud" => true,
		"delete" => true,
		"maxCount" => 1
	))->show(
		$value,
		$value ? true : false
	);
}

P.S. учти тот факт, что тестировалось только для PREVIEW_PICTURE для свойств, для мноржественных точно дописывать надо
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
An3k
@An3k
\Bitrix\Main\UI\FileInput довольно просто работать в любом месте сайта, достаточно получить данные файлов и с ними можно уже работать как угодно, отправляю форму на обработку или допустим вы в админке где то хотите вставить этот модуль и нет возможности отправить всю форму, тогда можно отследить события изменения и уже дальше эти данные слать куда вам надо.

При простой подзагрузке файлов они сохраняются во временную директорию Битрикс обычно это
\home\bitrix\.bx_temp\******sitemanager, а вам нужно уже далее это всё послать в форме или аяксом из полей.

Простыми словами:
1. вариант вы вставляете компонент в форму и шлёте форму как обычно на обработку со всеми полями.
2. вариант вы берёте данные из полей шлёте яксом на сохранение и уже дальше работаете с id файлами как обычно.

// загружены файлы
BX.addCustomEvent('onAjaxSuccess', (e) => {

// слать данные без формы можно прямо так
$.ajax({
    type: 'POST',
    url : '/handler.php',
    data: { pics : e.files },
    success: function(data)
    { console.log(data) }
})


})

 // изменения
BX.addCustomEvent('onFileinputIsChanged', (e) => {})

// удаление
BX.addCustomEvent('onFileIsDeleted', (e) => {})


в обработчике есть один нюанс по поводу путей к файлам
// 1. собираете массив файлов

    $i = 0;
    foreach( $_POST['pics'] as $itm){
        $arFile[$i]['hash'] = $itm['file']['hash'];
        $arFile[$i]['name'] = $itm['file']['files']['default']['name'];
        $arFile[$i]['type'] = $itm['file']['files']['default']['type'];
        $arFile[$i]['tmp_name'] = $itm['file']['files']['default']['path'];
        $arFile[$i]['size'] = $itm['file']['files']['default']['size'];
        $arFile[$i]['error'] = '';
        $i++;
    }

  // 2. нужно обязательно прогнать через CIBlock::makeFileArray( ); тогда будут верные пути и сможете сохранять файлы CFile::SaveFile(); иначе будет ошибка
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы