Вывод перечня заказанных товаров в таблицу с заказами minishop2 (панель менеджера)

Доброго всем времени суток!
Требуется вывести перечень товаров, которые содержаться в заказе.
На сколько я понимаю, за все это мероприятие отвечает вот этот вот товарищ: core/components/minishop2/processors/mgr/orders/getlist.class.php

и на сколько я понял, за запрос к базе отвечают следующие части:

$c->leftJoin('modUser', 'User');
        $c->leftJoin('modUserProfile', 'UserProfile');
        $c->leftJoin('msOrderStatus', 'Status');
        $c->leftJoin('msDelivery', 'Delivery');
        $c->leftJoin('msPayment', 'Payment');
        $c->leftJoin('msOrderAddress', 'Address');
и

$c->select(
            $this->modx->getSelectColumns('msOrder', 'msOrder', '', ['status', 'delivery', 'payment'], true) . ',
            msOrder.status as status_id, msOrder.delivery as delivery_id, msOrder.payment as payment_id,
            UserProfile.fullname as customer, User.username as customer_username,
            Status.name as status, Status.color, Delivery.name as delivery, Payment.name as payment'
        );
на мои попытки в первую часть кода добавить
$c->leftJoin('msOrderProduct', 'Product');
и во вторую часть

Product.name,
минишоп выдает пустую таблицу…

И вот что-то я все ни как не соображу как сделать… На сколько я понимаю, объект или класс msOrderAddress не описан в данном процессоре… или поправьте меня?

Буду признателен за подсказки, в какую сторону копать!
Дмитрий
13 апреля 2025, 20:28
modx.pro
1 002
0

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

Alexey
14 апреля 2025, 08:05
+1
msOrdermsOrderProduct — опечатка?

Если минишоп выдает пустую таблицу, то — возможно — в логах админки есть что-нибудь?
    Дмитрий
    16 апреля 2025, 12:35
    0
    Действительно опечатка, спасибо, исправил
      Дмитрий
      16 апреля 2025, 13:16
      0
      А в логах следующее:
      (ERROR @ /home/c/cz42644/test-iflower/public_html/core/xpdo/xpdo.class.php: 644) Could not load class: ms2_order_products from mysql.ms2_order_products.
      (ERROR @ /home/c/cz42644/test-iflower/public_html/core/xpdo/xpdo.class.php: 644) Could not load class: msorderProducts from mysql.msorderproducts.
      [2025-04-13 15:04:21] (ERROR @ /home/c/cz42644/test-iflower/public_html/core/xpdo/xpdo.class.php: 1827) No foreign key definition for parentClass: msOrder using relation alias: Product

      Каждая ошибка повторяется по нескольку раз, но это я так понимаю, идет несколько обращений к бд и каждое порождает одну и тужу ошибку.
        Alexey
        16 апреля 2025, 22:04
        0
        Самое главное: нет конкретики…

        Что за список товаров? Если в админке — он и так выводится в списке заказов, когда модалку открываешь. Если в публичной части сайта, к примеру, в ЛК, то зачем тащить процессор? Не проще ли составить нужный запрос в сниппете и в зависимости от id заказа цеплять товары? Ну, плюс ещё проверять принадлежность заказа к юзеру.
          Дмитрий
          Вчера в 21:35
          0
          Действительно! Самого главного я и не обозначил! Спасибо! Поправлю заголовок.
          Речь идет именно о панели менеджера и возможности управления заказами.
          В модалке без условно выводится и с этим нет сложностей, вопрос в том, что в данном контексте требуется перечень товаров выводить в общую таблицу.
          Ну т.е. на равне с комментарием к заказу, датой заказа и прочими данными, требуется вывести перечень заказов.
      Артур Шевченко
      14 апреля 2025, 10:14
      +1
      Требуется вывести перечень товаров, которые содержаться в заказе.
      В админке он и так выводится, а чтобы с фронта запустить процессор нужно дать права пользователю.

      Второй момент ты хочешь присоединить к одной строке много строк, для этого нужно завернуть много строк в json. Примерно так
      $q = $this->modx->newQuery('modResource');
      $q->leftJoin('msCategoryMember', 'Member', 'Product.id=Member.product_id');
      $q->leftJoin(
                  'modResource',
                  'Category',
                  'Member.category_id=Category.id AND Category.class_key="msCategory" AND Category.id != Product.parent AND Category.published = 1'
              );
              $q->select(':categoriesSelect AS categories');
              $this->replacements[':categoriesSelect'] = <<<EOD
              CONCAT(
                      '[', GROUP_CONCAT(
                          DISTINCT CONCAT(
                              '{"alias":"', Category.alias, '", "rid":"', Category.id, '", "menuindex":"', Category.menuindex, '", "template":"', Category.template, '"}'
                          )
                          SEPARATOR ','
                      ), ']'
                  )
      EOD;
      Если MySQL повыше можно использовать спец функции для создания json
        Дмитрий
        16 апреля 2025, 13:06
        0
        Большое спасибо за ответ, но к сожалению я мало чего понял из него… Я даже не до конца понимаю, что такое фронт… Это фронт-енд? Т.е. панель администрирования? Или отработка скриптов?
        Как я это себе вижу=) А ты меня поправь.
        Те данные, что присутствуют в таблице с заказами, берутся из таблицы _ms2_orders, у меня уже получилось расширить эту таблицу данными из таблицы _ms2_order_addresses, это выглядело сложно, но я справился (скажу даже, что я не менял исходники, а сделал красиво, именно расширив своими файлами), т.к. нужный запрос уже присутствовал в процессоре (фильтрация заказов частично делается и по этой таблице). Я так понимаю, что за это отвечает эта часть кода $c->leftJoin('msOrderAddress', 'Address'); Т.е. дальше, я просто немного изменил SQL-запрос добавив выборку нужных полей.
        Сейчас, мне нужно в запрос подключить еще одну таблицу, а именно _ms2_order_products, причем еще нужно сделать сортировку по id заказа, т.к. товаров в одном заказе может быть много.
        Не получится ли сделать подобным образом?
        или нужно идти по пути, который ты предложил?

        Что такое msOrderAddress в данном случае $c->leftJoin('msOrderAddress', 'Address');? А самое главное откуда оно берется, это же не таблица в БД, а объект, класс или что-то еще? Где можно найти рождение msOrderAddress этого? Выше написанная строчка кода делает алиас в запросе, и при дальнейшем обращении я уже могу обращаться к таблице _ms2_order_addresses как Address.
          Артур Шевченко
          16 апреля 2025, 22:39
          +2
          Я не видел весь твой код, но думаю что $c это объект класса xPDOQuery, который является конструктором SQL-запросов. А $c->leftJoin(), $c->select() это всё вызовы методов конструктора запросов. После все манипуляций получается обычный SQL, который и отправляется в БД.
          Если упрощать, то когда ты делаешь leftJoin одна таблица ставится рядом с другой так, чтобы совпали поля, которые ты указываешь в условии ON (или передаешь третьим параметром в метод leftJoin). Таким образом получается новая таблица, но с бОльшим количеством столбцов, при этом количество строк будет таким же как и в первой таблице. Например, если у тебя в первой таблице одна запись, а во второй две, в итоговой таблице будет одна запись. Именно поэтому ты не можешь просто взять и присоединить все товары, тебе нужно сгруппировать их по id заказа, упаковать их в одну строку и только потом присоединять. вот так можно получить товары для заказа с id = 594
          <?php
          $q = $this->modx->newQuery('msOrder');
          $q->leftJoin('msOrderProduct', 'Product', 'msOrder.id=Product.order_id');
          $select = <<<EOD
                  CONCAT(
                          '[', GROUP_CONCAT(
                              DISTINCT CONCAT(
                                  '{"name":"', Product.name, '", "count":"', Product.count, '", "price":"', Product.price, '"}'
                              )
                              SEPARATOR ','
                          ), ']'
                      )
          EOD;
          $q->select('msOrder.id as order_id, :products AS products');
          $q->where(['msOrder.id' => 594]);
          $q->groupby('msOrder.id');
          $q->prepare();
          $sql = $q->toSQL();
          $sql = str_replace(':products', $select,$sql);
          $stmt = $modx->prepare($sql);
          if($stmt->execute()){
              $result = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
              print_r($result);
          }
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        8