[update] Общая база товаров для разных контекстов

Очень долго не получалось заставить работать товары minishop2 на других контекстах, с выводом через сниппет нет проблем, а вот с ссылками и корзиной беда.
Использовал sendForward, с ним куча гемороя, но случайно наткнулся на вот это:
$modx->resource = $modx->getObject('modResource', $id);
$modx->request->prepareResponse();
exit();

В итоге вот что получилось:

Плагин SwitchProduct (вешаем на OnPageNotFound) для поиска товара по ссылке с других контекстов (site.ru/catalog/product/ имет дубликат по ссылке test.site.ru/catalog/product/)
<?php
if ($modx->event->name == 'OnPageNotFound') {
	$alias = $modx->context->getOption('request_param_alias', 'q');
	if (!isset($_REQUEST[$alias])) {return false;}
	$request = $_REQUEST[$alias];
	$tmp = explode('/', $request); // получаем ссылку
	$test = $modx->findResource(end($tmp));
	$document = $modx->getObject('msProduct', array('alias' => end($tmp))); // ищем товар по алиасу, последний кусок из /catalog/category/product-alias
	if($document){
		$modx->resource = $document;
		$modx->request->prepareResponse(); // рендерим товар миную контексты!
		exit();
	}
}
На моем примере сайт разделен на 2 контекста, web (site.ru) и test (test.site.ru)
к товарам создан tv brand, те которые будут выводиться на test имеют запись test в tv

Создаем в web:
catalog (msCategory) (id 3)
с контентом/содержимым
[[!msProducts]]
— product web 1 (tv.brand = пусто)
— product web 2 (tv.brand = пусто)
— product web + test 3 (tv.brand = test)
— product web + test 4 (tv.brand = test)

Создаем в test:
catalog (msCategory)
с контентом/содержимым
[[!msProducts? &parents=`3` &includeTVs=`brand` &where=`{"brand":"test"}`]]
Структура каталогов у контекстов должна быть идентична, иначе посыпятся 404 ошибки.
Должно быть включено ЧПУ, проверка на дублирование в контекстах = нет

В итоге: товары работают полностью во всех контекстах, добавление в корзину не вызывает проблем как и оформление заказа.
but1head
17 февраля 2015, 12:45
modx.pro
26
4 239
+3

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

Василий Столейков
18 февраля 2015, 11:55
0
Спасибо! Очень нужная вещь! Очень часто нужна одна общая база для многих контекстов (или например языков).
    but1head
    18 февраля 2015, 19:19
    +2
    тестировал, обнаружил проблемы, в итоге все переписал, хватило одного плагина. тикет обновил.
      Василий Столейков
      16 июня 2015, 08:13
      0
      А для мультиязычного сайта этот плагин не подойдёт? Но сайты не на разных доменах, а в подпапках:
      ру - /
      англ - /en/
      Как для такой структуры сделать общую базу товаров?
        but1head
        29 сентября 2015, 15:26
        +1
        Проглядел, ниже пример, он разбивает url на массив и ищет по последнему (т.е. алиасу). Тоже самое можно сделать и на /en/
        Ruslan Butakov
        29 сентября 2015, 15:22
        +1
        Дополнение от Никиты, если вы используете .html в своих URL

        <?php
        if ($modx->event->name == 'OnPageNotFound' && $modx->context->key != 'mgr' && $modx->context->key != 'web'){
            
            $alias = $modx->getOption('request_param_alias', null, 'alias', true);
            $request = &$_REQUEST[$alias];
            $tmp = explode('/', $request); // получаем ссылку
            $product_alias = str_replace(".html", "", end($tmp));
            $resource = $modx->getObject('modResource', array('alias' => $product_alias));
            
            print_r($resource->id); 
            
            
            
            if($resource){
                if($content) $resource->set('content', $content);
                $modx->resource = $resource;
        		$modx->request->prepareResponse(); 
        		exit();
            }
        
        }
          Сергей Самусев
          02 января 2016, 22:42
          0
          Добавил плагин, создал в контекст с каталогом, в другом контексте создал аналогичные категории. Вывожу товары одной из категорий вот так:
          [[!pdoPage?
                              	&element=`msProducts`
                              	&depth=`1`
          			&context=`catalog`
                              	&tpl=`tpl.msProducts.row1`
                              	&sortby=`RAND()`
                              	&ajaxMode=`scroll`
                              ]]
          Но в ресурсе данного контекста же нет товаров, только пустые категории, соответственно он товаров не видит.
            but1head
            02 января 2016, 23:04
            0
            Смысл в том, что товары выводятся из основного контекста.

              Сергей Самусев
              02 января 2016, 23:20
              0
              то есть каталог с товарами оставить в контексте web?
                but1head
                02 января 2016, 23:24
                0
                Да, заполняете web товарами.
                В новый контекст дублируете иерархию web и пр выводе указываете parent из web
                  Сергей Самусев
                  13 января 2016, 10:36
                  0
                  Вопрос — а как мне в шаблоне, вот тут
                  [[!pdoPage?
                                      	&element=`msProducts`
                                      	&depth=`1`
                                      	&tpl=`tpl.msProducts.row1`
                                      	&sortby=`RAND()`
                                      	&ajaxMode=`scroll`
                                      ]]
                  указать родителем ресурс из другого контекста?
                    but1head
                    13 января 2016, 11:42
                    0
                    &parent=`__id категории__`

                    или же можно завести tv поле «родитель» и в нем выбирать основную категорию, и выводить
                    &parent=`__tv_roditel__`
          Сергей Самусев
          02 января 2016, 23:25
          0
          ок. спасибо. буду пробовать.
          Михаил Божко
          31 марта 2016, 10:32
          +1
          А какой у вас геморрой был с sendForward? Немного подправил код, запросов к БД стало меньше. У вас есть строчка неиспользуемая:
          $test = $modx->findResource(end($tmp));
          Вот я на базе неё и сделал так:
          <?php
          if ($modx->event->name == 'OnPageNotFound') {
          	$alias = $modx->context->getOption('request_param_alias', 'q');
          	if (!isset($_REQUEST[$alias])) {return false;}
          	$request = $_REQUEST[$alias];
          	$tmp = explode('/', $request); // получаем ссылку
          	$document = $modx->findResource(end($tmp), 'web'); //ищем в том контексте, в котором общие товары, ищем товар по алиасу, последний кусок из /catalog/category/product-alias
          	if($document){
          		$modx->sendForward($document);
          		exit();
          	}
          }
          Только для форвардинга нужно в настройках включить опцию allow_forward_across_contexts
          По замерам получается так:

            Abu
            Abu
            17 февраля 2017, 17:31
            0
            Вроде получилось таким способом, но вот при клике на товар идёт смена контекста, как с этим быть?
              Александр
              30 октября 2018, 12:28
              0
              Удалось решить проблему?
            Валентин
            17 марта 2020, 12:40
            0
            При клике на товар идёт смена контекста, как это можно исправить?
              РОМАН
              21 марта 2021, 14:18
              0
              Для ссылок
              {$id | url | preg_replace : '~^https?://~' : '' | preg_replace : '/\w+\..{2,3}(?:\..{2,3})?(?:$|(?=\/))/i' : ''}
              Плагин для подмены ресурса
              <?php
              if ($modx->event->name == 'OnPageNotFound') {
              	$alias = $modx->context->getOption('request_param_alias', 'q');
              	if (!isset($_REQUEST[$alias])) {return false;}
              	$request = $_REQUEST[$alias];
              	$tmp = explode('/', $request); // получаем ссылку
              	$document = $modx->getObject('msProduct', array('alias' => end($tmp))); // ищем товар по алиасу, последний кусок из /catalog/category/product-alias
              	if($document){
              		$modx->resource = $document;
              		$modx->request->prepareResponse(); // рендерим товар миную контексты!
              		exit();
              	}
              }
              В настройках сниппетов PDO проставьте {$_modx->context.key}
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              19