Миграция на minishop2
        Всем доброго времени суток. Пытаюсь перенести поля с ТВ в опции minishop2 
Делаю запрос в базу данных
В ответ получаю ошибку
#1062 — Дублирующаяся запись '12311' по ключу 'PRIMARY'
Если же запрос делаю REPLACE
    
    
                                                                                
            Делаю запрос в базу данных
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 при этом значения в поле старая цена записываются. Что я делаю не так подскажите пожалуйста.    Комментарии: 46
                А что мешает работать через API!?
Вот пример синхры tv поля price:
                    Вот пример синхры 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());            
                Не подскажете в чем проблема?            
                    
                Спасибо. Попробовал через консоль получил следующее
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
                    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
                $prod_ID указали верный?            
                    
                Так мне надо все товары а не конкретный товар.            
                    
                ну надо сначала получить все товары, и в цикле обработать
                    $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();
}            
                Получил в ответ
SQL time: 0,0001 s
SQL queries: 1
PHP time: 0,0009 s
Total time: 0,0010 s
Memory: 0 MB
                    SQL time: 0,0001 s
SQL queries: 1
PHP time: 0,0009 s
Total time: 0,0010 s
Memory: 0 MB
                И ничего не изменилось при этом.            
                    
                Вам дали готовый код, Вы код смотрите вообще? 
я специально закомментировал строчку кода.
                    я специально закомментировал строчку кода.
                Так ваш код и взял его и использовал.            
                    
                Или что то недопонял, объясните пожалуйста.            
                    
                //$resource->save(); эту строку я раскомментировал. результат тот же.            
                    
                В этой строке указано имя ТВ — price, можете туда id поставить
                    $tv_price = $resource->getTVValue('price');на ночь глядя ошибся$query = $modx->newQuery('msProduct');msProduct надо указывать везде            
                Спасибо. Работает. Не подскажете еще как перенести из тв в опцию товара. К примеру создал опцию available в нее перенести из тв Наличие товара.            
                    
                Я использовал для наличия товара menuindex, или оставляй в TV как есть.
Все опции товара можно посмотреть через var_dump($product->toArray()) (скрин)

                    Все опции товара можно посмотреть через 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;
    }
}            
                Да но только не одной опцией все ограничивается. Есть и другие опции. Может кто подскажет как опции сюда прикрутить?            
                    
                Тогда иди в 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;
        }
    }
}            
                Вот так кстати работает только почему то один товар а дальше не идет.            
                    
                ? переменную $debug=0;            
                    
                А так же со свойствами товара нельзя сделать? Со свойствами типа tags color            
                    
                Здесь проблема именно с записью в поля такие как Tags Color и остальные того же типа ввода. Если поле просто текст то проблем с записью нет никаких. 
Никто не подскажет как сделать запись именно в такие поля?
                    Никто не подскажет как сделать запись именно в такие поля?
                Совсем вы не хотите гуглить.
Есть процессоры, один минус они медленные. Если товаров очень много(примерно >1000) то это будет долго или выйдет за лимит выполнения скрипта.
                    Есть процессоры, один минус они медленные. Если товаров очень много(примерно >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);
}            <?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();
}А сюда нельзя добавить запись именно в поля такие как Список с автодополнением?Пользуюсь поиском видимо не так ищу. Подскажите пожалуйста, уже голова отваливается никак не могу разобраться.
                Так я вам и дал код который туда вставить, в цикл, внимательно смотрите.            
                    
                $productArray['options-available'] = 1; как сюда добавить тв с которого данные вытянуть необходио?            
                    
                Ну это уже совсем. Программированию вас никто учить не будет. Включите голову, как присваиваются переменные. Вам уже все дали, как получить из ТВ, засунуть ее в переменную, как обновлять товар и его опции, осталось чуть подумать собрать все вместе, удалить ненужное.            
                    
                Я одного не могу понять почему из обычного тв в поле price все прописывается а в поле Список с автодополнением ничего записываться не хочет.
Может за деньги поможете?
                    Может за деньги поможете?
                Примеры я давал, нужно для «Список с автодополнением» передавать массив, а не просто значение
Ничего трудного же нет в этом, вот чуть просто подумать надо
Если у вас TV с множеством значений, то его сначала надо разобрать и преобразовать в массив, чтобы условно получилось ['белый', 'кофе', 'серый'] и потом уже присвоить нужной вам опции. Т.е. надо посмотреть что выдает $resource->getTVValue('id или название ТВ') и преобразовать в нужные данные.
                    <?
$productArray['tags'] =  ['большие' , 'маленькие'];
$productArray['options-cvet'] = ['белый' , 'кофе', 'серый'];
$productArray['options-napryzhenie'] = ['220' , '320'];«У вас же заданы конкретные значения для опций, мне же надо эти самые опции вытаянуть из дополнительных полей.»Ничего трудного же нет в этом, вот чуть просто подумать надо
$productArray['options-available'] = $resource->getTVValue(30);Просто ведь? да?Если у вас TV с множеством значений, то его сначала надо разобрать и преобразовать в массив, чтобы условно получилось ['белый', 'кофе', 'серый'] и потом уже присвоить нужной вам опции. Т.е. надо посмотреть что выдает $resource->getTVValue('id или название ТВ') и преобразовать в нужные данные.
                Спасибо. Но ничего у меня не получается.
Сделал так только ничего не получилось. Параметры не перенеслись.
                    <?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();
}Сделал так только ничего не получилось. Параметры не перенеслись.
                мда…
                    <?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);
}            
                Тут еще проблема в том что товаров более 5к и вылазит за выделенное время. Увеличил до 60 секунда, максимум но все равно не хватает на обработку данных.            
                    
                Получаю на выходе Fatal error: Maximum execution time of 60 seconds exceeded in /core/xpdo/xpdo.class.php on line 2190            
                    
                ну тогда надо писать поэтапное обновление, аяксом или сессионно, по 30-50 товаров за проход.            
                    
                Через htaccess таким образом
php_value max_execution_time 300
Не получиться увеличить время на обработку?
                    php_value max_execution_time 300
Не получиться увеличить время на обработку?
                может быть, пробуйте, поставьте больше
                    $query->limit(0); тут поставьте 50 проверьте сначала работает ли код            
                Нет. Не работает. Указал лимит как вы написали 
Получил
SQL time: 0.1978 s
SQL queries: 1654
PHP time: 4.3618 s
Total time: 4.5596 s
Memory: 12 MB
Но ничего не обновилось
                    Получил
SQL time: 0.1978 s
SQL queries: 1654
PHP time: 4.3618 s
Total time: 4.5596 s
Memory: 12 MB
Но ничего не обновилось
                не знаю тогда, проверяйте, что дает getvalue            
                    
                Если установить поле Наличие как текстовое поле то все переносится. так что выдает оно то что необходимо.            
                    
                Я уже писал, что надо смотреть, что выдает и преобразовывать в массивы ЕСЛИ НАДО! Вы ничего не хотите понимать, искать, видимо. Просто пишет не работает, не работает. Я уже ничем таким людям не помогу            
                    
                А как посмотреть что выдает тв не подскажете?            
                    
                print_r() или var_dump()            
                    
                Нихрена блядь не получается. не знаю даже как получить данные тв поля.            
                    
                печаль беда            
                    
                У вас же заданы конкретные значения для опций, мне же надо эти самые опции вытаянуть из дополнительных полей.            
                    
                Тебе дали 100500, подсказок, разжевали как могли!
Изучай документацию, и методы работы с компонентом minishop, если не понимаешь что к чему, пиши в раздел modx.pro/work
                    Изучай документацию, и методы работы с компонентом minishop, если не понимаешь что к чему, пиши в раздел modx.pro/work
                Достойный ответ. Спасибо. Вместо такого количество букв можно было бы новичку показать как и на примере одного из полей. 
Спасибо за помощь всем.
                    Спасибо за помощь всем.
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.