Like и другие приключения unicode

Здравствуйте!
Столкнулся с такой ситуацией — нужно загрузить в опции данные. Все просто, берем ID документов (к которым нужно добавить значение опции) и поехали… Вроде все просто, но давайте немного подробнее.

Перед началом — modx 2.7.3 и miniShop2 примерно той же «даты выпуска».
Итак, нужно найти товар по цвету и артикулу. Артикул хранится в БД как обычное значение, а вот цвет хранится в БД как JSON строка.
Соответственно задаю обычное значение для article(B2019), ну и color(Красный) перевожу в JSON строку.

$article = 'B2019';
  $color = json_encode('Красный');
  $where = [
    'article' => $article,
    'color' => '['.$color.']'
  ];

  // Получаем объекты для редактирования и сохраняем в опции нужные значения
  $resources = $modx->getCollection('msProductData', $where);
  foreach($resources as $res) {
    $id[] = $res->get('id');
  };
Ну и в результате все вполне успешно работает и задача в принципе выполнена.

Но если немного добавить условий:
1. Сам цвет, по которому делаем запрос, всегда один;
2. Артикул тоже всегда один;
3. В БД может быть несколько цветов;
4. Цвет из запроса должен всегда совпадать только с первым цветом из БД.
К примеру в запросе «Красный», в БД «Красный», «Синий» — отлично. («Синий», «Красный» откликаться не должен)
Сразу пришло в голову такое:
$where = [
    'article' => $article,
    'color:LIKE' => '['.$color.'%'
  ];
Применяю LIKE и добавляю % к запросу и вроде все верно. Но «не успех».

Ну думаю ладно, напишу в лоб запрос:
$article = 'B2019';
$color = json_encode('Красный');
$color = '["\u041a\u0440\u0430\u0441\u043d\u044b\u0439"%'; // тут сразу указал % и для простого восприятия сразу указал цвет в unicode
$q = $modx->prepare('
  SELECT
    id
  FROM
    modx_ms2_products
  WHERE
    article = :article
    AND color = :color
');
$q->execute([
  ':article' => $article,
  ':color' => $color
  // ':color' => $color
]);
$result = $q->fetchAll(PDO::FETCH_ASSOC);
Но тут тоже не успел… Прям тоска, печалька =(

Смотрю что ушло в запрос:
$q->debugDumpParams();
SQL: [128] 
  SELECT
    id
  FROM
    modx_ms2_products
  WHERE
    article = :article
    AND color = :color

Sent SQL: [175] 
  SELECT
    id
  FROM
    modx_ms2_products
  WHERE
    article = NULL
    AND color = '[\"\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"%'
И… color то не тот, что отправляется…
Что хочу отправить — '["\u041a\u0440\u0430\u0441\u043d\u044b\u0439"%';
Что отправляется — '[\"\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"%'

Итак, загадка раскрыта, виновник найден. Но как решить дальше проблему?))

Пардон, если вопрос простой/тупой/бредовый. Прокопался с ним всю ночь и не додумался до решения =(
Прошу помощи более понимающих и компетентных)

PS. Подсказали, что тут нужно познакомить пространство имен с utf8, но там нужно файлы modx править. Хотелось бы более Элегантное решение)
Благодарю за внимание!
Rasul
08 июля 2022, 07:46
modx.pro
1 056
0

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

Максим
08 июля 2022, 12:32
+1
Если у вас и получится делать подобные выборки, то только через костыли… Я бы переопределил xtype поля color и писал бы выбранные цвета в отдельную табличку… Тогда проблем с фильтрацией возникать не должно!)
Кстати в miniShop2 есть уже отдельная табличка для опций (ну по крайней мере была, когда я последний раз с ним работал) и если ее использовать, то не придется расширять nimiShop2 подключением новой таблицы.
Пишу первый вариант решения проблемы, который я бы попробовал реализовать. Сам не реализовывал.
    Rasul
    09 июля 2022, 20:42
    0
    Здравствуйте!
    Ну может в версии 3+ цвет вынесен в таблицу, но в 2.7.3 цвет лежит в основной таблице modx_ms2_products.
    Да в принципе, еслиб цвет лежал бы в отдельной таблице, это ведь вопрос не решило бы. Проблема ведь в том, что при запросе «цвет» экранируется и получается в итоге не тот запрос, который нужен. Ну по крайней мере я в этом вижу проблему)
      Артур Шевченко
      09 июля 2022, 23:00
      0
      Если бы цвет лежал в отдельной таблице и товар был бы с ним связан связью «один ко многим», то это решило бы проблему, а сейчас он лежит в виде json и поэтому фильтровать по нему проблемно.
        Rasul
        10 июля 2022, 00:27
        0
        Да, да. Про это и говорю)
        Может предложите что-то?
          Артур Шевченко
          10 июля 2022, 00:39
          +1
          Так вам же уже предложили — вынести в отдельную таблицу. Можно плагином на сохранение товара разбирать поле с цветами на отдельные записи для кастомной таблицы и уже по ним фильтровать. Вот тут написано как сделать свои таблицы, которые потом можно со стандартными сниппетами использовать.
            Rasul
            10 июля 2022, 03:38
            0
            Ну для меня не совсем рационально под цвет заводить отдельную таблицу. Другое дело, если что-то еще там покидать.

            Просто надеялся на что-то попроще.
            Еще подсказали Это, но туда точно лезть не буду)
              Артур Шевченко
              10 июля 2022, 10:52
              0
              Интересные у вас критерии рациональности: танцы с бубном рационально, научный подход нет)))
                Rasul
                10 июля 2022, 18:40
                0
                Ну рационально было бы вообще расширить саму таблицу modx_ms2_products на один столбец и там хранить цвета. Только стоит это делать если столбец нативно попадает в объект msProduct. Где-то видел инструкции, как это сделать.

                Хотя в моем случае все-таки таблицу придется создавать. У меня много опций и их лучше вместе хранить отдельно)
                  Артур Шевченко
                  10 июля 2022, 22:24
                  0
                  У тебя товар может быть только одного цвета или нескольких цветов?
                    Rasul
                    10 июля 2022, 22:31
                    0
                    Эм, это как посмотреть)
                    В названии цвет один (основной цвет), но сам товар разноцветный и эти цвета думаю потом буду добавлять как дополнительные.
                      Артур Шевченко
                      10 июля 2022, 22:46
                      +1
                      Тебе нужно находить товар по артикулу и цвету. Цветов у товара несколько. Как добавление ещё одного поля в таблицу товара решает эту задачу, учитывая, что это поле(color) уже есть и содержит JSON? Помочь может только отдельная таблица где каждый цвет будет связан с определенным товаром.
              Максим
              11 июля 2022, 15:07
              0
              За вас уже сделали отдельную табличку. Артур выше предложил вариант ее использования через плагин на событие сохранения…
              И до сих пор понять не могу при чем тут ModX 3? Где я о нем писал?
              У гитхаба есть заветная кнопочка Blame… Посмотрите дату добавления этой таблицы в miniShop2…
              github.com/modx-pro/miniShop2/blob/master/core/components/minishop2/model/schema/minishop2.mysql.schema.xml#L122
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    12