[msOptionsColor] - групповое редактирование цвета опций.


[msOptionsColor]пакет для цвета / паттерна опций продукта Minishop2.
Под катом пример плагина для группового редактирования и автоматического создания цвета товаров, а также скрипт для обработки всех существующих товаров.


— делаем бэкап БД
Прежде всего выполнить бэкап БД. Случаи бывают разные, лучше перебдеть.

— создаем товар «образец»
Нужно создать товар образец который будет содержать все опции цвета и выполнить в нем назначение цвета.



— создаем плагин
Создаем плагин. При изменении цвета в образце будем менять цвет у всех остальных товаров. При сохранении товара будем назначать цвет из образца.
Назначаем плагину события OnDocFormSave, msocColorSave

<?php

/** @var modX $modx */
/** @var array $scriptProperties */

// ресурс образец
$sid = 21390;
// обработываемые опции
$keys = array(
    'color',
);

switch ($modx->event->name) {

    case 'OnDocFormSave':

        $resource = $modx->getOption('resource', $scriptProperties);
        $mode = $modx->getOption('mode', $scriptProperties);
        if (!$resource OR $mode == modSystemEvent::MODE_NEW) {
            return;
        }

        $fqn = $modx->getOption('msoptionscolor_class', null, 'msoptionscolor.msoptionscolor', true);
        $path = $modx->getOption('msoptionscolor_core_path', null,
            $modx->getOption('core_path', null, MODX_CORE_PATH) . 'components/msoptionscolor/');
        if (!$msoptionscolor = $modx->getService($fqn, '', $path . 'model/', array('core_path' => $path))) {
            return;
        }
        $msoptionscolor->initialize($modx->context->key);

        if (!$msoptionscolor->isWorkingClassKey($resource) OR !$msoptionscolor->isWorkingTemplates($resource)) {
            return;
        }

        $rid = $resource->get('id');
        if ($rid == $sid) {
            return;
        }

        foreach ($keys as $key) {
            if (!$values = $resource->get($key)) {
                continue;
            }
            if (!is_array($values)) {
                $values = array($values);
            }

            foreach ($values as $value) {
                $rquery = $modx->newQuery('msocColor', array('rid' => $rid, 'key' => $key, 'value' => $value));
                $squery = $modx->newQuery('msocColor', array('rid' => $sid, 'key' => $key, 'value' => $value));
                /** @var msocColor $color */
                if (!$modx->getObject('msocColor', $rquery) AND $color = $modx->getObject('msocColor', $squery)) {
                    /** @var msocColor $o */
                    $o = $modx->newObject('msocColor');
                    $o->fromArray($color->toArray(), '', true);
                    $o->set('rid', $rid);
                    $o->save();
                }
            }
        }
        break;

    case 'msocColorSave':
        $color = $modx->getOption('color', $scriptProperties);
        if (!$color OR $sid != $color->get('rid') OR !in_array($color->get('key'), $keys)) {
            return;
        }

        $c = $modx->newQuery('msocColor');
        $c->command('UPDATE');
        $c->set(array(
            'name'     => $color->get('name'),
            'color'    => $color->get('color'),
            'color2'   => $color->get('color2'),
            'pattern'  => $color->get('pattern'),
            'pattern2' => $color->get('pattern2'),
        ));

        $c->where(array(
            'rid:!=' => $color->get('rid'),
            'key'    => $color->get('key'),
            'value'  => $color->get('value'),
        ));
        $c->prepare();
        $c->stmt->execute();

        break;

}

— Обработаем уже имеющиеся товары
Нужно пройтись по всем товарам и пересохранить их чтобы сработало событие OnDocFormSave на которое написан наш плагин, мы конечно так делать не будем.
Есть компонент Console который позволяем запускать скрипт в админке MODX, устанавливаем его и запускаем код указанный ниже

<?php

$step = 1;
if (!isset($_SESSION['Console']['completed'])) {
    $_SESSION['console_offset'] = 0;
}
$offset = isset($_SESSION['console_offset']) && $_SESSION['console_offset'] ? $_SESSION['console_offset'] : 0;
$q = $modx->newQuery('modResource');
$q->where(array(
    'class_key' => 'msProduct',
));
$total = $modx->getCount('modResource', $q);
$q->limit($step, $offset);
$resources = $modx->getCollection('modResource', $q);
/** @var modResource[] $resources */
foreach ($resources as $resource) {
    $modx->invokeEvent('OnDocFormSave', array(
        'mode'       => modSystemEvent::MODE_UPD,
        'id'         => $resource->get('id'),
        'resource'   => &$resource,
        'reloadOnly' => false,
    ));
    print "<p>Processing resource <b>" . $resource->get('pagetitle') . "</b></p>";
    sleep(0.2);
}
$_SESSION['console_offset'] = $offset + $step;
if ($_SESSION['console_offset'] >= $total) {
    $sucsess = 100;
    $_SESSION['Console']['completed'] = true;
    unset($_SESSION['console_offset']);
} else {
    $sucsess = round($_SESSION['console_offset'] / $total, 2) * 100;
    $_SESSION['Console']['completed'] = false;
}
for ($i = 0; $i <= 100; $i++) {
    if ($i <= $sucsess) {
        print '=';
    } else {
        print '_';
    }
}
$current = isset($_SESSION['console_offset']) ?
    $_SESSION['console_offset'] :
    ($sucsess == 100 ? $total : 0);
print "\n";
print $sucsess . '% (' . $current . ')' . "\n\n";

За код спасибо Илье, первоисточник ilyaut.ru/reposts/console-2-0-4-beta-cyclic-queries-in-the-console-modx/
Нам нужно лишь добавить часть для вызова события на ресурсе
$modx->invokeEvent('OnDocFormSave', array(
'mode'       => modSystemEvent::MODE_UPD,
'id'         => $resource->get('id'),
'resource'   => &$resource,
'reloadOnly' => false,
));

ps. Всем спасибо за внимание!
гист gist.github.com/vgrish/041904a4f98ea6be5278298f5a69ea68
20 января 2018, 12:01    Володя   G+  
4    363 +5


Комментарии ()

    Вы должны авторизоваться, чтобы оставлять комментарии.