Работа с множественными свойствами типа 'файл' в Битрикс: добавление и удаление изображений

В этой статье я расскажу, как работать с множественными свойствами типа "файл" в Битрикс. Мы рассмотрим методы для добавления и удаления изображений, которые помогут вам эффективно управлять галереями на вашем сайте. Эти методы особенно полезны при интеграции с фронтендом, когда нужно синхронизировать данные между клиентской и серверной частями приложения.

Вступление

В моём проекте я работаю с инфоблоками в Битрикс и активно использую ORM (Object-Relational Mapping) для удобства работы с данными. Для этого я создал класс-наследник \Bitrix\Iblock\Elements\ElementNewsTable, который отвечает за обработку запросов, поступающих с фронтенда.

Основной объект, с которым я работаю, — это сущность, унаследованная от \Bitrix\Iblock\Elements\EO_ElementNews. Этот класс динамически генерируется Битрикс и предоставляет удобные методы для работы с элементами инфоблока.

Для обработки данных, поступающих с фронтенда, я реализовал несколько методов, которые упрощают работу с множественными свойствами типа "файл". В частности, методы removeGalleryImages и setNewGalleryImages позволяют удалять и добавлять изображения в галерею элемента инфоблока.

Кроме того, я использую вспомогательный метод setGallery, который автоматически разбирает поля, пришедшие с запросом, и вызывает соответствующие методы для обновления галереи. Вот как это работает:

public function setGallery(): void 
{
    // 1. Проверяем свойство removed_gallery[]
    // Если массив не пуст, вызываем метод удаления файлов из галереи
    $removed_gallery = request()->removed_gallery;
    if (!empty($removed_gallery)) {
        $this->removeGalleryImages($removed_gallery);
    }

    // 2. Проверяем массив gallery[]
    // Если не пустой, вызываем метод добавления файлов в свойство
    $files = request()->gallery;
    if (!empty($files)) {
        $this->setNewGalleryImages($files);
    }
}

Этот метод позволяет гибко управлять галереей изображений, обрабатывая как удаление, так и добавление файлов в зависимости от данных, пришедших с фронтенда.

Как это работает в проекте

Инициализация сущности:

При получении запроса с фронтенда я создаю объект сущности, используя динамически сгенерированный класс EO_ElementNews.

Этот объект предоставляет доступ к свойствам элемента инфоблока, включая множественные свойства типа "файл".

Обработка запросов:

Метод setGallery анализирует данные, пришедшие с фронтенда, и вызывает соответствующие методы для обновления галереи.

Если в запросе есть данные для удаления (removed_gallery), вызывается метод removeGalleryImages.

Если в запросе есть новые файлы (gallery), вызывается метод setNewGalleryImages.

Обновление элемента:

После обработки данных элемент инфоблока обновляется с помощью методов CIBlockElement::SetPropertyValues и CFile::Delete.

Преимущества подхода

Гибкость: Метод setGallery автоматически определяет, какие действия нужно выполнить (удаление или добавление файлов), что упрощает обработку запросов.

Удобство: Использование ORM Битрикс позволяет работать с данными инфоблока в объектно-ориентированном стиле, что делает код более читаемым и поддерживаемым.

Безопасность: Методы removeGalleryImages и setNewGalleryImages включают проверки, которые предотвращают ошибки при обработке данных.

Пример использования

Предположим, фронтенд отправляет запрос с данными для обновления галереи:

{
    "removed_gallery": [
        "/upload/iblock/abc/file1.jpg",
        "/upload/iblock/def/file2.jpg"
    ],
    "gallery": [
        {"name": "new_image.jpg", "size": 1024, "tmp_name": "/tmp/php123", "type": "image/jpeg"}
    ]
}

Метод setGallery обработает этот запрос следующим образом:

Удалит файлы file1.jpg и file2.jpg из галереи.

Добавит новый файл new_image.jpg в галерею.

Удаление файлов

Метод removeGalleryImages принимает массив путей к файлам и удаляет их из множественного свойства инфоблока. Вот как это работает:

/**
 * Удаление файлов из множественного свойства инфоблока.
 *
 * @param array $paths Массив путей к файлам, которые нужно удалить.
 */
protected function removeGalleryImages($paths)
{
    // Получаем коллекцию текущих файлов, привязанных к элементу
    $currentFilesIds = [];
    foreach ($this->getMorePhoto()->getAll() as $prop) {
        $currentFilesIds[$prop->getId()] = $prop->getValue();
    }

    if (empty($currentFilesIds)) {
        return;
    }

    // Получаем данные о файлах из таблицы b_file
    $currentFiles = \Bitrix\Main\FileTable::getList(['filter' => [
        '@ID' => $currentFilesIds
    ]])->fetchAll();

    // Массив для обновления свойства
    $arFiles = [];
    $idFilesToDeleted = [];

    // Проходим по каждому пути и ищем соответствующий файл
    foreach ($paths as $path) {
        $filePath = array_slice(array_filter(explode('/', $path)), -3);
        $fileName = $filePath[2]; // Имя файла
        $subdir = $filePath[0] . '/' . $filePath[1]; // Поддиректория

        // Сопоставляем файлы по имени и поддиректории
        foreach ($currentFiles as $file) {
            if ($file['FILE_NAME'] == $fileName && $file['SUBDIR'] == $subdir) {
                $arFiles[array_search($file['ID'], $currentFilesIds)]['del'] = 'Y';
                $idFilesToDeleted[] = $file['ID'];
            }
        }
    }

    // Удаляем файлы из файловой системы
    foreach ($idFilesToDeleted as $id) {
        \CFile::Delete($id);
    }

    // Обновляем свойство элемента
    \CIBlockElement::SetPropertyValues($this->getId(), self::IBLOCK_ID, $arFiles, 'MORE_PHOTO');
}

Добавление файлов

Метод setNewGalleryImages добавляет новые файлы в множественное свойство инфоблока. Вот как это работает:

  /**
 * Добавление новых файлов в множественное свойство инфоблока.
 *
 * @param array $files Массив файлов для добавления.
 */
public function setNewGalleryImages($files)
{
    $arFiles = [];

    // Если файлы не переданы, выходим из метода
    if (empty($files) || $files[0] === null) {
        return;
    }

    // Подготавливаем массив файлов для добавления
    foreach ($files as $file) {
        $arFiles[] = [
            'name' => $file->getClientOriginalName(),
            'size' => $file->getSize(),
            'tmp_name' => $file->getPathname(),
            'type' => $file->getMimeType()
        ];
    }

    // Обновляем свойство элемента
    \CIBlockElement::SetPropertyValues($this->getId(), self::IBLOCK_ID, $arFiles, 'MORE_PHOTO');
}

Заключение

В этой статье мы рассмотрели, как работать с множественными свойствами типа "файл" в Битрикс. Мы реализовали методы для добавления и удаления изображений, которые помогут вам эффективно управлять галереями на вашем сайте. Эти методы особенно полезны при интеграции с фронтендом, когда нужно синхронизировать данные между клиентской и серверной частями приложения.

Если у вас есть вопросы или предложения, оставляйте их в комментариях. Также рекомендую ознакомиться с официальной документацией Битрикс для более глубокого понимания работы с инфоблоками.