[mSync] Публикуем товары, если они есть в выгрузке

Приветствую, коллеги. Задача в следующем: есть выгрузка с названием товара, его ценой и артикулом, нужно снимать с публикации товары, которых в этой выгрузке нет, а те, что есть, публиковать.

Очевидное решение написать плагин. Вот он
<?php
switch($modx->event->name){
    case 'mSyncOnProductImport':
        if($mode == 'category'){
            $products = $modx->getIterator('modResource', ['class_key' => 'msProduct', 'published' => 1, 'parent' => $resource->get('id')]);
            foreach($products as $product){
                $product->set('published', 0);
                $product->save();
                $c++;
            }
            
        }
        break;
        
    case 'mSyncOnPrepareProduct':
        $values = &$modx->event->returnedValues;
        $properties['data']['published'] = 1;
        $values['properties'] = $properties;
        break;

}
Суть в следующем, перед началом импорта отдельной категории, мы снимаем с публикации все товары в ней. Перед импортом товара мы добавляем в его данные свойство published со значением 1.

Если кого-то интересует, почему я вообще это написал, то всё просто — решение, в плане выбора событий, неочевидное. Интуитивно кажется, что для снятия с публикации можно использовать событие mSyncOnBeforeImport. Но это не так, поскольку это событие вызывается более одного раза, что приводит к снятию с публикации всех ресурсов после завершения импорта.
Второй момент, передача свойства published через $values['data'] также не даст результата, если ресурс обновляется, а не создается.
Третий момент, установка системной настройки msync_publish_default в значение ДА тоже не сработало.

Как всегда, надеюсь, что сэкономил кому-то время.
Артур Шевченко
17 мая 2023, 20:37
modx.pro
2
873
+2
Поблагодарить автора Отправить деньги

Комментарии: 6

Павел Бигель
18 мая 2023, 01:51
0
foreach($products as $p){
            $p->set('published', 0);
            $p->save();
        }
Мне кажется получить ошибку MySQL gone away получить можно очень быстро с обновлением элементов коллекции отделельно.
Лучше бы их обновить в БД напрямую

P.S очень печально что в модкс нельзя обновить коллекцию пачкой. Но я понимаю почему — иначе не отработают плагины на эти события
    Николай Савин
    18 мая 2023, 10:47
    +1
    очень печально что в модкс нельзя обновить коллекцию пачко
    Вполне себе есть метод
    $modx->updateCollection()
Николай Савин
18 мая 2023, 10:49
1
+2
Артур ты тоже обрати внимание. Есть шикарный метод
$modx->updateCollection();
Он позволяет быстро без перебора обновить записи в базе по заданным критериям.
Да — нужно знать про него, что он сразу в базу лезет, и не задействует никакие модели, плагины.
Конкретно в этом случае — это норм.
    Артур Шевченко
    18 мая 2023, 11:46
    0
    Спасибо, изменил код.
      Артур Шевченко
      20 мая 2023, 16:06
      0
      Не знаю почему, но в плагине метод $modx->updateCollection() не работает, если запустить тот же код в Console — работает, а в плагине нет.
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      6