Всем привет.
Буквально вчера, словил не приятную багу.

(P.S. вполне возможно что многие знают об этой баге. Но ради интереса решил воспроизвести данную багу на других сайтах — в 90% случаев ошибка воспроизводится).

Имеется сайт на MODX Revolution 2.7.3 в связке с miniShop2 2.5.0.
Бага заключалась в том, что пришёл «пустой» заказ. Т.е. все реквизиты клиента в письме и заказе есть, а вот товаров в этом заказе нет.

Долго и упорно не мог понять в чём же проблема. Благо есть вебвизор и он таки помог воспроизвести ошибку.

Дело оказалось в смайликах. Которые были вставлены в комментарий к заказу.

Как воспроизвести ошибку:
1. Кладём товар в корзину, идём в оформление заказа, заполняем поля которые надо заполнить и в комментарий к заказу вставляем любой Emoji смайлик.
Например такой: ???????? (как видим, даже данный сайт не поддерживает смайлики)
1.1 Тыкаем в любое место страницы чтобы убрать фокус с поля комментария и жмём на F5.
Убеждаемся что корзина стала пустой и бага таки присутствует =)

Причина данного явления:
1. minishop2 — никак не обрабатывает поле comment. Т.е. сохраняет его «как есть».
2. Все заполненные поля заказа, minishop2 сохраняет в сессию. В том числе и комментарий.
3. MODX дублирует сессию в базу данных. Т.е. каждая сессия — это отдельная запись в базе данных (таблица: modx_session).
4. В 99% случаев, ваша база данных имеет кодировку utf8_general_ci (особо отчаянные имеют кодировку CP1251).
5. Смайлики — это какой-то там 4-х битный набор символов. Данный набор символов поддерживает кодировка utf8mb4_unicode_ci (данную кодировку разработала команда разработчиков MySQL и была специально создана для поддержки смайликов).
6. Если вы сохраните смайлик в базе данных с кодировкой utf8_general_ci, то весь текст который будет идти после смайлика — затрется.
7. Как мы уже знаем, MODX дублирует все сессии в базу. В базу записывается и сессия минишопа. Если в этой записи имеется смайлик — то такая запись 100% «грохнется» и MODX не сможет её прочитать, т.к. текст банально затрется. Если MODX не может прочитать запись — то он обнуляет сессию и создаёт новую запись.
Таким образом мы имеем обнулённую корзину.

Решение проблемы:
Самое минимальное, это нужно сделать следующее:
0. Сделать бэкап базы данных.
1. Открыть базу данных (через phpmyadmin, Navicat и т.п.) и найти таблицу: modx_session (где modx — это ваш префикс).
1.1. В данной таблице необходимо поменять кодировку у поля «data» на utf8mb4_unicode_ci
2. На сервере найти и открыть файл ../core/config/config.inc.php
2.1. И установить кодировку:
9-я строка:
$database_connection_charset = 'utf8mb4';

12-я строка:
$database_dsn = 'mysql:host=localhost;dbname=mydbname;charset=utf8mb4';


Ну а по хорошему, нужно конечно же перевести всю базу в кодировку utf8mb4_unicode_ci
Но и минимальное решение — тоже заработает.