title

Все наверное уже заметили, что Лента активности еще вчера не отображала всю активность пользователей на сайте - некоторые комментарии и сообщения с форума просто не появлялись в ней.

Ошибку я впервые заметил после первого сообщения от Fatik, именно тогда все "началось", как будто она пришла и зачитала какое-то магическое, древнее заклинание.

Тогда я подумал, что допустил ошибку в коде и решил проверить - мне неудалось найти ничего, что потверждало бы мои догадки. Но лента все чаще "ошибалась" поэтому мне приходилось перепроверять свой код в поисках ошибки каждый день.

Код Ленты активности состоит из нескольких частей - код, который вызывается системой при определенных событиях (hooks) - например когда добавляется комментарий, сообщение на форуме и т.д. Вторая часть кода, которая содержит все необходимые условия для обновления Ленты активности, третья часть, которая отвечает за ее непосредственное обновление, и последняя часть, которая отображает обновления на сайте.

Я был уверен, что ошибки в последней части кода нет потому, что все что было в базе данных отображалось на сайте правильно. Значит ошибка должна была быть в трех предыдущих частях.

Моя логика была проста - если есть в коде ошибка, значит в лог-файлах должно появиться сообщение о ней. Но в лог-файлах сайта не было ничего. И вот вчера я решил, что не пойду спать до тех пор, пока не исправлю это ошибку. Вариантов было два - либо нахожу ошибку и исправляю ее, либо полностью переписываю код.

Зная насколько неприятен и непрост данный код, мне не хотелось браться за второй вариант, поэтому решил искать дальше. И на этот раз я проанализировал код детально - поставил везде breakpoint-ы. И снова никакого сообщения об ошибке не было найдено, все breakpoint-ы проходили успешно. Уже было 3:00 утра, и я начал потихоньку сходить с ума.

После долгих мучений появилась одна зацепка - функция $wpdb->insert(), отвечающая за сохранение инфорамации в базе данных возращала null, что означает, что данные не сохранились в БД.  Возвращаемое значение данной функции я не проверял в коде по двум причинам - она вызывалась последней, поэтому не было повода ею интересоваться, и вторая причина - при возникновении ошибки данная функция пишет код и сообщение ошибки в лог-файлы, а там ничего такого не было.

И в этот момент "студента" озарило. Я вспомнил сообщения Smith и Fatik, которым я тогда не придал особого значения:

Fatik: Админ а шо с сообщениями ?
Fatik: Нохчо да нет отправляю вроде, но не доходит и в отправленных пусто..

Smith: Дважды ответил на сообщение, но так и не увидел ответ в Отправленных.

PS оказывается всё дело было в смайле(

Да! Ну конечно! Проблема именно в смайлах. Ведь раньше их в таком количестве не использовали на сайте, поэтому данную ошибку никто не замечал.

Та же самая ошибка оказалась и в приватных сообщениях.

Итак, к 4 часам утра мне было известно чем вызвана данная ошибка, но теперь вопрос был в другом - ПОЧЕМУ? Почему сообщения со смайлами не сохраняются в базе данных? Найти ответ на этот вопрос мне помог Google и несколько обсуждений на сайте Stack overflow:

Для того, чтобы закодировать азбуку и многие другие символы достаточно 3 байтов поэтому чаще всего используется кодировка utf8. Сообщения в таблице в базе данных для Ленты активности тоже сохранялись именно в этой кодировке, но оказалось, что некоторые смайлики выходят за рамки 3 байтов и они не могут быть сохранены в utf8. Для закодирования этих смайлов необходимы как минимум 4 байта, а это можно сделать в кодировке utf8mb4.

Вот что об этом пишут на официальном сайте MySQL (база данных которая используется у нас на сайте):

The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. As of MySQL 5.5.3, the utf8mb4 character set uses a maximum of four bytes per character supports supplemental characters:
  • For a BMP character, utf8 and utf8mb4 have identical storage characteristics: same code values, same encoding, same length.
  • For a supplementary character, utf8 cannot store the character at all, whereas utf8mb4 requires four bytes to store it. Because utf8 cannot store the character at all, you have no supplementary characters in utf8 columns and need not worry about converting characters or losing data when upgrading utf8 data from older versions of MySQL.
utf8mb4 is a superset of utf8, so for an operation such as the following concatenation, the result has character set utf8mb4 and the collation of utf8mb4_col...

--- И что мы имеем в результате - логика, которую несколько лет развивали в техническом ВУЗе обнаружила ошибку после многих часов непростых поисков, в то время, как женская интуиция обнаружила данную ошибку в первые же секунды:

Reinkarnazia: В цитатах смайлы оживают в полный рост)))
Reinkarnazia: Эти смайлы мутанты меня пугают)
Merlin: Смайлы как в фильме ужасов😂 пошли в тему «приемная доктора»..

Мораль сей басни такова, друзья, никогда не недооценивайте женскую интуицию.