Удалить все картинки элементов инфоблока: анонс, детальную и дополнительные картинки (MORE_PHOTO)

Просмотров: 154

Задача: В инфоблоке 10 000 элементов, нужно удалить картинки анонса, детальные и дополнительные картинки из свойства MORE_PHOTO. Так как элементов много, скорее всего упремся в лимиты таймаутов сервера, по этому нужно сделать это пошагово.

Удалить все картинки элементов инфоблока: анонс, детальную и дополнительные картинки

Удаление картинок и очистка множественного свойства через API

Для начала сделаем скрипт, который с помощью API 1С-Битрикс выполнит всю работу за один шаг. Для работы нам нужно будет подключить пролог и эпилог и воспользоаться модулем 'iblock'

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

// Подключение необходимых модулей
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;

Loader::includeModule('iblock');

$el = new CIBlockElement;

// ВАШ ИНФОБЛОК
$IBLOCK_ID = 6; 

// Получение элементов инфоблока
$rsElements = ElementTable::getList([
    'filter' => [
        'IBLOCK_ID' => $IBLOCK_ID
    ],
    'select' => [
        'ID'
    ]
])->fetchAll();

// Это нужно для метода SetPropertyValuesEx
$Del_More_Photos = [
    0 => [
        'VALUE' => '',
        'DESCRIPTION' => ''
    ]
];

foreach ($rsElements as $element) {
    // Очищаем PREVIEW_PICTURE и DETAIL_PICTURE
    $el->Update(
        $element['ID'],
        [
            'PREVIEW_PICTURE' => [
                'del' => 'Y'
            ],
            'DETAIL_PICTURE' => [
                'del' => 'Y'
            ]
        ]
    );
    
    // Очищаем свойство MORE_PHOTO
    CIBlockElement::SetPropertyValuesEx(
        $element['ID'],
        $IBLOCK_ID,
        [
            'MORE_PHOTO' => $Del_More_Photos
        ]
    );
}

// Подключение эпилога
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

Здесь мы, с помощью ElementTable::getList, получаем все элементы нужного инфоблока и обходим каждый элемент в цикле. Для работы нам достаточно получить только ID элемента.

C помощью CIBlockElement::Update удаляем картинки анонса и детальной. Далее, с помощью CIBlockElement::SetPropertyValuesEx ощищаем ножественное свойство MORE_PHOTO.

Обратите внимание: просто так, передав в него пустоту, очистить множественное свойство нельзя. Обязательно должен быть массив с одним ключем в котором пустые ключи со значением и описанием (создаем его до цикла в $Del_More_Photos).

Пошаговая обработка элементов инфоблока.

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

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;

Loader::includeModule('iblock');

$el = new CIBlockElement;

$IBLOCK_ID = 6; // ВАШ ИНФОБЛОК
$BATCH_SIZE = 100; // Количество элементов для обработки за один шаг
$startFrom = isset($_GET['startFrom']) ? (int)$_GET['startFrom'] : 0; // Позиция, с которой начать обработку

// Получение элементов инфоблока
$rsElements = ElementTable::getList([
    'filter' => [
        'IBLOCK_ID' => $IBLOCK_ID
    ],
    'select' => [
        'ID'
    ],
    'limit' => $BATCH_SIZE,
    'offset' => $startFrom
])->fetchAll();

$Del_More_Photos = [
    0 => [
        'VALUE' => '',
        'DESCRIPTION' => ''
    ]
];

foreach ($rsElements as $element) {
    // Очищаем PREVIEW_PICTURE и DETAIL_PICTURE
    $el->Update(
        $element['ID'],
        [
            'PREVIEW_PICTURE' => [
                'del' => 'Y'
            ],
            'DETAIL_PICTURE' => [
                'del' => 'Y'
            ]
        ]
    );

    // Очищаем свойство MORE_PHOTO
    CIBlockElement::SetPropertyValuesEx(
        $element['ID'],
        $IBLOCK_ID,
        [
            'MORE_PHOTO' => $Del_More_Photos
        ]
    );
}

$processedCount = count($rsElements);
$nextStartFrom = $startFrom + $processedCount;

if ($processedCount < $BATCH_SIZE) {
    echo 'Операция завершена.';
} else {
    echo 'Обработано ' . $processedCount . ' элементов. Страница будет автоматически обновлена для продолжения...';
    ?>
    <script>
        setTimeout(function () {
            window.location.href = "?startFrom=' . $nextStartFrom . '";
        }, 1000); // Задержка 1 секунда перед следующим запуском
    </script>'
    <?php
}

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

Для выполнения скрипта поэтапно, обрабатывая по 100 элементов за шаг, можно использовать механизм сохранения состояния между запусками. Один из способов — это использование параметров в URL для передачи текущей позиции и подсчета обработанных элементов. Ниже приведен пример реализации такого подхода.

Сергей 27.05.2024
А этим кодом можно удалить товары? Просто у меня их очень много и если удаляю через админку, даже по 500 товар не получается
Nginx уходит в ошибку таймаута
Михаил Базаров 27.05.2024
Да, в переборе элементов можно что угодно с ними делать
Для удаления:
Код
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

// Подключение необходимых модулей
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;

Loader::includeModule('iblock');

// ВАШ ИНФОБЛОК
$IBLOCK_ID = 6; 

// Получение элементов инфоблока
$rsElements = ElementTable::getList([
    'filter' => [
        'IBLOCK_ID' => $IBLOCK_ID
    ],
    'select' => [
        'ID'
    ]
])->fetchAll();

foreach ($rsElements as $element) {
   CIBlockElement::Delete($element['ID']);
}

// Подключение эпилога
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

В пошаговом варианте тоже самое: удаляем элемент зная его ID, методом  CIBlockElement::Delete