Копирование элементов инфоблока вместе с файлами

К сожалению битрикс не умеет копировать элементы инфоблоков вместе с файлами, картинками анонса и детальной картинкой. Копируемый элемент создается с пустыми полями. А общение с тех. поддержкой битрикса выявило, что в документации сам процесс копирования элементов никак не описан, не описано, что копируется, а что нет и что вообще с этим делать.

Подходящих решений в маркетплейсе битрикса найти не удалось, а из блогов наиболее подходящую запись нашел только тут: https://odva.pro/blog/bitrix_copy_files/

Но в этом решении ID инфоблока и коды свойств прописаны хардокодом. Для более универсального решения я немного переписал скрипт и выкладываю тут:

<?php

use Bitrix\Main\EventManager;


$eventManager = EventManager::getInstance();
$eventManager->addEventHandler('iblock', 'OnBeforeIBlockElementAdd', 'ClassElementImageCopy::OnBeforeIBlockElementAddHandler');


class ClassElementImageCopy {
    public static function OnBeforeIBlockElementAddHandler(&$arFields): void {
        if (!empty($_REQUEST['copyID']) && ($copyId = (int)$_REQUEST['copyID'])) {
            CModule::IncludeModule('iblock');

            $product = CIBlockElement::GetByID($copyId)->fetch();
            if (!empty($product['DETAIL_PICTURE'])) {
                $detailPicture = CFile::MakeFileArray(CFile::GetPath($product['DETAIL_PICTURE']));
                $arFields['DETAIL_PICTURE'] = $detailPicture;
            }

            if (!empty($product['PREVIEW_PICTURE'])) {
                $previewPicture = CFile::MakeFileArray(CFile::GetPath($product['PREVIEW_PICTURE']));
                $arFields['PREVIEW_PICTURE'] = $previewPicture;
            }


            $iblockId = $arFields['IBLOCK_ID'];

            $resProps = CIBlock::GetProperties($iblockId);
            $filesProp = [];
            while ($prop = $resProps->Fetch()) {
                if ($prop['PROPERTY_TYPE'] === 'F') {
                    $filesProp[] = $prop;
                }
            }

            foreach ($filesProp as $prop) {
                $resProperty = CIBlockElement::GetProperty($iblockId, $copyId, ['ID' => 'ASC'], ['CODE' => $prop['CODE']]);

                while ($fileValue = $resProperty->GetNext()) {
                    $file = CFile::MakeFileArray(CFile::GetPath($fileValue['VALUE']));

                    $arFields['PROPERTY_VALUES'][$prop['CODE']][] = [
                        'VALUE'       => $file,
                        'DESCRIPTION' => $fileValue['DESCRIPTION'] ?: '',
                    ];
                }

                if (!empty($arFields['PROPERTY_VALUES'][$prop['CODE']])) {
                    CIblockElement::SetPropertyValues($arFields['ID'], $iblockId, $arFields['PROPERTY_VALUES'][$prop['CODE']], $prop['CODE']);
                }
            }
        }
    }
}

Копируемы файлы появятся в элементе после нажатия на кнопки «Применить» или «Сохранить».