MODX Revolution и MySQL v5.7.x: проблема с сохранением значений TV-параметров
Работая с новым сайтом на движке MODX Revolution я столкнулся с проблемой невозможности сохранения значений пользовательских TV-параметров. Как оказалось, всему виной была новая версия MySQL.
Суть проблемы
Во время сохранения ресурса значения TV-параметров не сохраняются в таблице базы данных (modx_site_tmplvar_
), при этом внешне всё выглядит нормально: после сохранения в соответствующих полях отображаются обновлённые значения. Однако после перезагрузки страницы редактирования поля вновь оказываются пустыми (или заполненными значениями по умолчанию).
В файле error.log системы (раздел Управление→Отчёты→Журнал ошибок административной панели) отображается следующее сообщение об ошибке:
[2016-10-19 08:18:19] (ERROR @ /var/www/init/www/core/xpdo/om/xpdoobject.class.php : 240) Error HY000 executing statement:
Array
(
[0] => HY000
[1] => 3065
[2] => Expression #1 of ORDER BY clause is not in SELECT list, references column 'init.tvtpl.rank' which is not in SELECT list; this is incompatible with DISTINCT
)
Версия MODX Revolution: 2.5.0-pl
Версия MySQL: 5.7.15
Причина
Потратив приличное количество времени на поиск решения в интернете, я узнал, что всё дело в новой версии MySQL и её обновлённых настройках по умолчанию: задействована настройка ONLY_FULL_GROUP_BY
, в результате чего перестаёт работать часть запросов MODX. Как оказалось, проблема уже известна разработчикам (описание в багтрекере MODX на GitHub: https://github.com/modxcms/revolution/issues/12826) и будет исправлена в новых версиях движка (скорее всего в версии 2.5.2-pl).
Решение
Чтобы не ждать официального релиза с исправлениями и обновлять движок, вы можете самостоятельно внести правки в файлы ядра MODX, к счастью исправлять придётся немного:
- Файл /core/model/modx/modresource.class.php:
$c = $resource->xpdo->newQuery('modTemplateVar'); $c->query['distinct'] = 'DISTINCT'; $c->select($resource->xpdo->getSelectColumns('modTemplateVar', 'modTemplateVar')); $c->select($resource->xpdo->getSelectColumns('modTemplateVarTemplate', 'tvtpl', '', array('rank'))); if ($resource->isNew()) { $c->select(array( 'modTemplateVar.default_text AS value',
Добавлена строка №342.
- Файл /core/model/modx/modtemplate.class.php:
$c = $this->xpdo->newQuery('modTemplateVar'); $c->query['distinct'] = 'DISTINCT'; $c->select($this->xpdo->getSelectColumns('modTemplateVar')); $c->select($this->xpdo->getSelectColumns('modTemplateVarTemplate', 'tvtpl', '', array('rank'))); $c->select(array('value' => $this->xpdo->getSelectColumns('modTemplateVar', 'modTemplateVar', '', array('default_text')))); $c->innerJoin('modTemplateVarTemplate','tvtpl',array( 'tvtpl.tmplvarid = modTemplateVar.id',
Добавлена строка №144.
После внесения изменений механизм сохранения значений TV-параметров должен работать нормально.
Скажу ещё, что можно просто отказаться от использования MySQL последней версии, однако не думаю, что такой способ решения проблемы придётся вам по душе.