Миграция на minishop2

Всем доброго времени суток. Пытаюсь перенести поля с ТВ в опции minishop2
Делаю запрос в базу данных
INSERT INTO brzhprf1x_ms2_products
(id,price) 
select contentid,value from brzhprf1x_site_tmplvar_contentvalues where
tmplvarid=6
Переношу данные с тв с id 6 в поле price минишоп
В ответ получаю ошибку
#1062 — Дублирующаяся запись '12311' по ключу 'PRIMARY'

Если же запрос делаю REPLACE

REPLACE INTO brzhprf1x_ms2_products
(id,price) 
select contentid,value from brzhprf1x_site_tmplvar_contentvalues where
tmplvarid=6
То все переносится. Но возникает следующая проблема при переносе поля старой цены

REPLACE INTO brzhprf1x_ms2_products
(id,old_price) 
select contentid,value from brzhprf1x_site_tmplvar_contentvalues where
tmplvarid=7
Делая такой запрос почему то перезаписываются поля PRICE при этом значения в поле старая цена записываются. Что я делаю не так подскажите пожалуйста.
Maks
04 октября 2022, 18:31
modx.pro
667
0

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

vectorserver
04 октября 2022, 19:53
+1
А что мешает работать через API!?
Вот пример синхры tv поля price:
<?php
/* @var msProduct $resource */
$resource = $modx->getObject('msProduct', $prod_ID);

//tv
$tv_price = $resource->getTVValue('price');

//Opt
$resource->set('price',$tv_price);

$resource->save();


//debug
var_dump($resource->toArray());
    Maks
    04 октября 2022, 20:51
    0
    Не подскажете в чем проблема?
    Maks
    04 октября 2022, 20:32
    0
    Спасибо. Попробовал через консоль получил следующее

    Fatal error: Uncaught Error: Call to a member function getTVValue() on null in core/components/console/processors/exec.class.php(24): eval()'d code:6 Stack trace: #0 core/components/console/processors/exec.class.php(24): eval() #1
    core/model/modx/modprocessor.class.php(185): ConsoleExecProcessor->process() #2 core/model/modx/modx.class.php(1770): modProcessor->run() #3 /core/model/modx/modconnectorresponse.class.php(144): modX->runProcessor('exec', Array, Array) #4 /core/model/modx/modconnectorrequest.class.php(86): modConnectorResponse->outputContent(Array) #5 /core/model/modx/modconnectorrequest.class.php(73): modConnectorRequest->prepareResponse(Array) #6 www/manager/components/console/connectors/console.php(11): modConnectorR in /core/components/console/processors/exec.class.php(24): eval()'d code on line 6
      Константин Ильин
      04 октября 2022, 21:29
      0
      $prod_ID указали верный?
        Maks
        04 октября 2022, 21:31
        0
        Так мне надо все товары а не конкретный товар.
          Константин Ильин
          04 октября 2022, 21:53
          0
          ну надо сначала получить все товары, и в цикле обработать

          $query = $modx->newQuery('modResource');
          $query->select(['msProduct.*']);
          $query->where(['class_key' => 'msProduct']);
          $query->limit(0);
          $resources = $modx->getIterator('modResource',$query);
          foreach ($resources as $resource) {
                $tv_price = $resource->getTVValue('price');
                  $resource->set('price',$tv_price);
                  //$resource->save();
          }
            Maks
            04 октября 2022, 21:58
            0
            Получил в ответ
            SQL time: 0,0001 s
            SQL queries: 1
            PHP time: 0,0009 s
            Total time: 0,0010 s
            Memory: 0 MB
              Maks
              04 октября 2022, 22:00
              0
              И ничего не изменилось при этом.
                Константин Ильин
                04 октября 2022, 22:12
                0
                Вам дали готовый код, Вы код смотрите вообще?
                я специально закомментировал строчку кода.
                  Maks
                  04 октября 2022, 22:16
                  0
                  Так ваш код и взял его и использовал.
                    Maks
                    04 октября 2022, 22:18
                    0
                    Или что то недопонял, объясните пожалуйста.
                      Maks
                      04 октября 2022, 22:22
                      0
                      //$resource->save(); эту строку я раскомментировал. результат тот же.
                        Константин Ильин
                        04 октября 2022, 22:37
                        +1
                        В этой строке указано имя ТВ — price, можете туда id поставить

                        $tv_price = $resource->getTVValue('price');
                        на ночь глядя ошибся
                        $query = $modx->newQuery('msProduct');
                        msProduct надо указывать везде
                          Maks
                          04 октября 2022, 22:53
                          0
                          Спасибо. Работает. Не подскажете еще как перенести из тв в опцию товара. К примеру создал опцию available в нее перенести из тв Наличие товара.
                            vectorserver
                            05 октября 2022, 07:40
                            +1
                            Я использовал для наличия товара menuindex, или оставляй в TV как есть.
                            Все опции товара можно посмотреть через var_dump($product->toArray()) (скрин)


                            <?php
                            $parent = 8;
                            $debug = 1;
                            
                            /* @var modX $modx*/
                            $array_ids = $modx->getChildIds($parent,6,array('context' => 'web'));
                            
                            foreach ($array_ids as $doc_ID){
                                /* @var msProduct $product */
                                $product = $modx->getObject('msProduct',$doc_ID);
                                if($product){
                                    //FILTERS
                                    //$dataOpt = $product->getOne('Data');
                                    //$optionKeys = $dataOpt->getOptionKeys();
                                    //var_dump($optionKeys);
                            
                            
                            
                                    //tv price
                                    $tv_price = $product->getTVValue('price');
                            
                                    //tv available
                                    $tv_available = $product->getTVValue('available');
                            
                                    //msProduct price
                                    $product->set('price',$tv_price);
                            
                                    //msProduct available to menuindex
                                    $product->set('menuindex',$tv_available);
                            
                                    //Save
                                    $product->save();
                            
                                    //debug
                                    if($debug) var_dump($product->toArray()); break;
                            
                                }
                            
                            }
                            Maks
                            05 октября 2022, 10:25
                            0
                            Да но только не одной опцией все ограничивается. Есть и другие опции. Может кто подскажет как опции сюда прикрутить?
                            vectorserver
                            05 октября 2022, 11:45
                            0
                            Тогда иди в miniShop2 :: Настройки (скрин), создавай доп. опции, потом вызывай из через метод $product->loadData()->get('options') (пример кода ниже)



                            Пример:
                            <?php
                            $debug = 1;
                            $array_ids = $modx->getChildIds(8,6,array('context' => 'web'));
                            
                            foreach ($array_ids as $doc_ID){
                                /* @var msProduct $product */
                                $product = $modx->getObject('msProduct',$doc_ID);
                                if($product){
                            
                                    //tv price
                                    $tv_price = $product->getTVValue('price');
                                    //tv available
                                    $tv_available = $product->getTVValue('available');
                            
                            
                            
                                    //msProduct price
                                    $product->set('price',$tv_price);
                            
                                    //Дополнительные опции товара
                                    $options = $product->loadData()->get('options');
                                    //Добавим значение в доп. опцию товара
                                    $options['available'][0] = $tv_available;
                                    //Обновим опции
                                    $product->set('options', $options);
                                    //Save
                                    $product->save();
                            
                                    //debug
                                    if($debug){
                            
                                        var_dump($product->toArray());
                                        break;
                                    }
                            
                            
                            
                                }
                            
                            }
                            Maks
                            05 октября 2022, 23:23
                            0
                            Вот так кстати работает только почему то один товар а дальше не идет.
                            vectorserver
                            06 октября 2022, 04:25
                            0
                            ? переменную $debug=0;
                            Maks
                            06 октября 2022, 07:27
                            0
                            А так же со свойствами товара нельзя сделать? Со свойствами типа tags color
        Maks
        05 октября 2022, 10:59
        0
        Здесь проблема именно с записью в поля такие как Tags Color и остальные того же типа ввода. Если поле просто текст то проблем с записью нет никаких.

        Никто не подскажет как сделать запись именно в такие поля?
          Константин Ильин
          05 октября 2022, 11:43
          0
          Совсем вы не хотите гуглить.
          Есть процессоры, один минус они медленные. Если товаров очень много(примерно >1000) то это будет долго или выйдет за лимит выполнения скрипта.
          .....
          foreach ($resources as $resource) {
              // Эти строки не трогайте
              $arr = $resource->toArray();
              $productArray['context_key'] = 'web';
              $productArray['class_key'] = 'msProduct';
              $productArray['alias'] = $arr['alias'];
              $productArray['id'] = $arr['id'];
              
              // Эти строки настраивайте как вам надо
              $productArray['options-cvet'] = ['белый' , 'кофе', 'серый'];
              $productArray['options-available'] = 1;
              $productArray['price'] = 99999;
              $productArray['tags'] =  ['большие' , 'маленькие'];
              
              // Это процессор обновления товара
              $response = $modx->runProcessor('resource/update', $productArray);
          }
            Maks
            05 октября 2022, 11:57
            -2
            <?php
            $query = $modx->newQuery('msProduct');
            $query->select(['msProduct.*']);
            $query->where(['class_key' => 'msProduct']);
            $query->limit(0);
            $resources = $modx->getIterator('modResource',$query);
            foreach ($resources as $resource) {
                  $tv_available = $resource->getTVValue('30');
                    $resource->set('available',$tv_available);
                    $resource->save();
            }
            А сюда нельзя добавить запись именно в поля такие как Список с автодополнением?

            Пользуюсь поиском видимо не так ищу. Подскажите пожалуйста, уже голова отваливается никак не могу разобраться.
              Константин Ильин
              05 октября 2022, 11:59
              0
              Так я вам и дал код который туда вставить, в цикл, внимательно смотрите.
                Maks
                05 октября 2022, 12:21
                -1
                $productArray['options-available'] = 1; как сюда добавить тв с которого данные вытянуть необходио?
                  Константин Ильин
                  05 октября 2022, 12:28
                  0
                  Ну это уже совсем. Программированию вас никто учить не будет. Включите голову, как присваиваются переменные. Вам уже все дали, как получить из ТВ, засунуть ее в переменную, как обновлять товар и его опции, осталось чуть подумать собрать все вместе, удалить ненужное.
                    Maks
                    05 октября 2022, 12:30
                    0
                    Я одного не могу понять почему из обычного тв в поле price все прописывается а в поле Список с автодополнением ничего записываться не хочет.

                    Может за деньги поможете?
                      Константин Ильин
                      05 октября 2022, 19:44
                      +1
                      Примеры я давал, нужно для «Список с автодополнением» передавать массив, а не просто значение
                      <?
                      $productArray['tags'] =  ['большие' , 'маленькие'];
                      $productArray['options-cvet'] = ['белый' , 'кофе', 'серый'];
                      $productArray['options-napryzhenie'] = ['220' , '320'];
                      «У вас же заданы конкретные значения для опций, мне же надо эти самые опции вытаянуть из дополнительных полей.»

                      Ничего трудного же нет в этом, вот чуть просто подумать надо
                      $productArray['options-available'] = $resource->getTVValue(30);
                      Просто ведь? да?

                      Если у вас TV с множеством значений, то его сначала надо разобрать и преобразовать в массив, чтобы условно получилось ['белый', 'кофе', 'серый'] и потом уже присвоить нужной вам опции. Т.е. надо посмотреть что выдает $resource->getTVValue('id или название ТВ') и преобразовать в нужные данные.
                        Maks
                        05 октября 2022, 20:38
                        0
                        Спасибо. Но ничего у меня не получается.
                        <?php
                        $query = $modx->newQuery('msProduct');
                        $query->select(['msProduct.*']);
                        $query->where(['class_key' => 'msProduct']);
                        $query->limit(0);
                        $resources = $modx->getIterator('modResource',$query);
                        foreach ($resources as $resource) {
                                $productArray['options-available'] = $resource->getTVValue(30);
                                $resource->set('available',$tv_available);
                                $resource->save();
                        }

                        Сделал так только ничего не получилось. Параметры не перенеслись.
                          Константин Ильин
                          05 октября 2022, 20:44
                          0
                          мда…

                          <?php
                          $query = $modx->newQuery('msProduct');
                          $query->select(['msProduct.*']);
                          $query->where(['class_key' => 'msProduct']);
                          $query->limit(0);
                          $resources = $modx->getIterator('msProduct',$query);
                          foreach ($resources as $resource) {
                          
                                  // Эти строки не трогайте
                                  $arr = $resource->toArray();
                                  $productArray['context_key'] = 'web';
                                  $productArray['class_key'] = 'msProduct';
                                  $productArray['alias'] = $arr['alias'];
                                  $productArray['id'] = $arr['id'];
                              
                                  // Эти строки настраивайте как вам надо
                                   $productArray['options-available'] = $resource->getTVValue(30);
                              
                                  // Это процессор обновления товара
                                  $response = $modx->runProcessor('resource/update', $productArray);
                          }
                            Maks
                            05 октября 2022, 20:56
                            0
                            Тут еще проблема в том что товаров более 5к и вылазит за выделенное время. Увеличил до 60 секунда, максимум но все равно не хватает на обработку данных.
                            Maks
                            05 октября 2022, 21:04
                            0
                            Получаю на выходе Fatal error: Maximum execution time of 60 seconds exceeded in /core/xpdo/xpdo.class.php on line 2190
                            Константин Ильин
                            05 октября 2022, 21:08
                            0
                            ну тогда надо писать поэтапное обновление, аяксом или сессионно, по 30-50 товаров за проход.
                            Maks
                            05 октября 2022, 21:09
                            0
                            Через htaccess таким образом
                            php_value max_execution_time 300
                            Не получиться увеличить время на обработку?
                            Константин Ильин
                            05 октября 2022, 21:55
                            0
                            может быть, пробуйте, поставьте больше

                            $query->limit(0); тут поставьте 50 проверьте сначала работает ли код
                            Maks
                            05 октября 2022, 22:04
                            0
                            Нет. Не работает. Указал лимит как вы написали
                            Получил
                            SQL time: 0.1978 s
                            SQL queries: 1654
                            PHP time: 4.3618 s
                            Total time: 4.5596 s
                            Memory: 12 MB

                            Но ничего не обновилось
                            Константин Ильин
                            05 октября 2022, 22:09
                            0
                            не знаю тогда, проверяйте, что дает getvalue
                            Maks
                            05 октября 2022, 22:25
                            0
                            Если установить поле Наличие как текстовое поле то все переносится. так что выдает оно то что необходимо.
                            Константин Ильин
                            05 октября 2022, 22:38
                            0
                            Я уже писал, что надо смотреть, что выдает и преобразовывать в массивы ЕСЛИ НАДО! Вы ничего не хотите понимать, искать, видимо. Просто пишет не работает, не работает. Я уже ничем таким людям не помогу
                            Maks
                            05 октября 2022, 22:47
                            0
                            А как посмотреть что выдает тв не подскажете?
                            Константин Ильин
                            05 октября 2022, 23:00
                            0
                            print_r() или var_dump()
                            Maks
                            05 октября 2022, 23:24
                            -1
                            Нихрена блядь не получается. не знаю даже как получить данные тв поля.
                            Константин Ильин
                            05 октября 2022, 23:41
                            0
                            печаль беда
                Maks
                05 октября 2022, 12:26
                -1
                У вас же заданы конкретные значения для опций, мне же надо эти самые опции вытаянуть из дополнительных полей.
                  vectorserver
                  05 октября 2022, 13:25
                  0
                  Тебе дали 100500, подсказок, разжевали как могли!
                  Изучай документацию, и методы работы с компонентом minishop, если не понимаешь что к чему, пиши в раздел modx.pro/work
                    Maks
                    05 октября 2022, 13:40
                    -1
                    Достойный ответ. Спасибо. Вместо такого количество букв можно было бы новичку показать как и на примере одного из полей.
                    Спасибо за помощь всем.
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          46