На работающем wordpress-сайте вдруг сломались галереи NextGEN, который стал выдавать вместо нормальной вёрстки ошибку:
1 2 3 | This is the default gallery type template, located in: ... If you’re seeing this, it’s because the gallery type you selected has not provided a template of it’s own. |
Включенный в wp-config.php режим отладки (WP_DEBUG=true
) показал стопку уведомлений (ошибки php уровня E_NOTICE) на странице настроек плагина в админке.
1 | Trying to get property of non-object ... |
Сама форма выглядела сломанной, отсутствовали заголовки разделов и все настройки были сброшены. При попытке заполнить и сохранить поля получал белый экран с ошибкой save() on null
.
Надо сказать, что несколько дней до этого у моего хостера был аврал, связанный со взломом каких-то сайтов, как объяснила мне техподдержка. Сайты лагали и долго отдавали даже статические файлы. Не связав этот факт с моей проблемой (зря), я несколько часов потрошил исходники и копался в базе данных (первоначально ошибка и её описания в интернете выглядели как баг синхронизации версии плагина с БД), пока суть проблемы не прояснилась: настройки хостинга запрещали использование функций PHP base64_encode/base64_decode
.
Решение
Способ 1
Если галерея выдаёт одну из ошибок выше, она могла сломаться не только из-за настроек безопасности хостинга. В этом случае работают способы:
- (предварительный бэкап базы, отдельных таблиц NextGen) → деактивация/удаление плагина → установка заново.
- Если использовались шорткоды для вставки галерей в записи, то попробовать удалить из них кавычки.
Способ 2
Если ошибка всё-таки в запрете необходимых для работы функций, то самый правильный способ — начать переписку с хостером и выяснить причины запрета.
Указанные функции используются не только в сторонних плагинах, но и в ядре WordPress:
1 2 3 4 5 | ack base64_ --type php ./html --ignore-dir ./html/wp-content/ -l | wc -l # 15 файлов движка WordPress использует функции base64_* ack base64_ --type php ./html -l | wc -l # 68 файлов для моего сайта |
Способ 3
Экстремальный метод: заменить во всех файлах вызовы нативных функций PHP на пользовательскую реализацию алгоритма.
1 2 | find . -type f -name *php -exec sed -i 's/base64_/base64__/g' {} + |
Реализация нужных функций на PHP (файл base64-fix.inc.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | function base64__decode($input) { $keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; $chr1 = $chr2 = $chr3 = ""; $enc1 = $enc2 = $enc3 = $enc4 = ""; $i = 0; $output = ""; // remove all characters that are not A-Z, a-z, 0-9, +, /, or = $input = preg_replace("[^A-Za-z0-9\+\/\=]", "", $input); do { $enc1 = strpos($keyStr, substr($input, $i++, 1)); $enc2 = strpos($keyStr, substr($input, $i++, 1)); $enc3 = strpos($keyStr, substr($input, $i++, 1)); $enc4 = strpos($keyStr, substr($input, $i++, 1)); $chr1 = ($enc1 << 2) | ($enc2 >> 4); $chr2 = (($enc2 & 15) << 4) | ($enc3 >> 2); $chr3 = (($enc3 & 3) << 6) | $enc4; $output = $output . chr((int) $chr1); if ($enc3 != 64) { $output = $output . chr((int) $chr2); } if ($enc4 != 64) { $output = $output . chr((int) $chr3); } $chr1 = $chr2 = $chr3 = ""; $enc1 = $enc2 = $enc3 = $enc4 = ""; } while ($i < strlen($input)); return urldecode($output); } function base64__encode($data) { $b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; $o1 = $o2 = $o3 = $h1 = $h2 = $h3 = $h4 = $bits = $i = 0; $ac = 0; $enc = ''; $tmp_arr = array(); if (!$data) { return data; } do { // pack three octets into four hexets $o1 = charCodeAt($data, $i++); $o2 = charCodeAt($data, $i++); $o3 = charCodeAt($data, $i++); $bits = $o1 << 16 | $o2 << 8 | $o3; $h1 = $bits >> 18 & 0x3f; $h2 = $bits >> 12 & 0x3f; $h3 = $bits >> 6 & 0x3f; $h4 = $bits & 0x3f; // use hexets to index into b64, and append result to encoded string $tmp_arr[$ac++] = charAt($b64, $h1).charAt($b64, $h2).charAt($b64, $h3).charAt($b64, $h4); } while ($i < strlen($data)); $enc = implode($tmp_arr, ''); $r = (strlen($data) % 3); return ($r ? substr($enc, 0, ($r - 3)) : $enc) . substr('===', ($r || 3)); } function charCodeAt($data, $char) { return ord(substr($data, $char, 1)); } function charAt($data, $char) { return substr($data, $char, 1); } // источник в ссылках ниже |
Добавить загрузку этого файла в движок WordPress (файл wp-load.php):
1 | require 'base64-fix.inc.php'; |
Очевидно, что прибегать к подобному решению стоит только в крайнем случае: после каждого обновления движка и плагинов придётся редактировать файлы заново, к тому же возможны побочные эффекты. К примеру, на конфигурации моего сайта плагин autoptimise начал выдавать странные нечитаемые символы в оптимизированные версии страниц, из-за чего ломалась вёрстка, его пришлось отключить. За исключением этого момента, сайт работал стабильно в течении 12 часов, пока на следующий день, когда я уже собирался писать тикет хостеру, нужные функции не были включены обратно. Тогда я вернул все заранее сохранённые файлы назад, и сделал новые бэкапы стабильной версии.
Ссылки
- http://stackoverflow.com/questions/10233613/base64-functions-disabled-what-to-do-now
- https://wordpress.org/support/topic/default-gallery-template-error/