Не получается зайти в админку WordPress

При входе в админку происходит редирект на ту же страницу входа.

Эта статья для вас, если вы попробовали все стандарные решения из интернета типа:

Я приведу неочевидный кейс, который иногда случается.

Иногда в базе данных при обновлении пропадает поле AUTO_INCREMENT у некоторых таблиц.

Этот параметр отвечает за то, чтобы следить за уникальностью значений в каких-либо столбцах таблицы.

Например, если поле с *_id должно быть уникальным, то при вставке строки в таблицу, AUTO_INCREMENT будет присваивать ему следующее свободное числовое значение.

Таким образом, если AUTO_INCREMENT отключен, то присвоится, например, 1. Если в столбце, который должен иметь уникальные значения, появятся две строки со значением 1, то будет ошибка и строка не вставится.

Что происходит при этой ошибке:

  1. При логине, создается новая сессия со своим id
  2. В таблице wp_usermeta создается новая строка с идентификатором сессии
  3. Если в поле umeta_id нет параметра AUTO_INCREMENT, то будет ошибка
  4. id сессии не будет создан и не запишется в куки браузера
  5. WordPress проверит, что он пустой и переотправит вас снова на страницу логина

Решение проблемы со входом в админку

Желательно перед любыми манипуляциями с базой данных, делать бэкап.

1. Заходим в phpMyAdmin в панели управления вашим хостингом

2. В базе данных среди таблиц вы найдете wp_usermeta

wordpress wp_usermeta

3. Заходите в эту таблицу и нажимаете "Структура"

4. Нажимаете редактировать umeta_id

5. Должна стоять галочка в параметре A_I

wordpress auto_increment

6. Если вы вернетесь в структуру таблицы, то там это будет выглядеть так

wordpress auto_increment

7. Убедитесь, что у вас нет строк с umeta_id = 0. Если такая строка есть, удалите её.

8. Попробуйте залогиниться. Проблема должна исчезнуть

wp-cli RuntimeException: failed to get url No working transport found

Иногда можно получить такую ошибку:

RuntimeException: failed to get url ... No working transport found

Я столкнулся с этой проблемой когда переносил сайты со старого сервера на новый.

Причин может быть много. Некоторые решения:

Перенос сайтов WordPress со старого OpenServer на новый

Если вы работаете, как и я под Open Server, то периодически, когда приходят обновления, приходится переносить сайты WordPress и базы данных с одного сервера на другой.

Для переноса удобно использовать утилиту wp-cli

Последовательность переноса такая:

  1. Делаете все дампы БД с помощью wp-cli
  2. Копируете файлы на новый сервер
  3. Меняете пути к интерпретатору php и исполняемому файлу MySQL в переменной path в windows
  4. Заливаете дампы в новую базу

Тут я рассказываю как решить wp-cli Error: ошибка соединения с базой данных

wp-cli под Windows

Перед запуском wp-cli вам потребуется скачать и установить cygwin

Весь wp-cli это один файл, который нужно скачать и запустить:

Скачать файл wp-cli.phar с https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

Чтобы удобно обращаться к нему через консоль, нужно сделать обертку через .bat файл. Создайте текстовый документ со следующим содержимым и сохраните как wp.bat :

@ECHO OFF
php "c:/wp-cli/wp-cli.phar" %*

Чтобы использовать в git-bash консоли, сделайте еще один файл с именем wp без расширения, просто wp, со следующим содержанием:

#!/usr/bin/env sh

dir=$(d=${0%[/\\]*}; cd "$d"; pwd)

# See if we are running in Cygwin by checking for cygpath program
if command -v 'cygpath' >/dev/null 2>&1; then
   # Cygwin paths start with /cygdrive/ which will break windows PHP,
   # so we need to translate the dir path to windows format. However
   # we could be using cygwin PHP which does not require this, so we
   # test if the path to PHP starts with /cygdrive/ rather than /usr/bin
   if [[ $(which php) == /cygdrive/* ]]; then
       dir=$(cygpath -m $dir);
   fi
fi

dir=$(echo $dir | sed 's/ /\ /g')
"${dir}/wp-cli.phar" "$@"

После этого нужно внести директорию до этих файлов (C:\wp-cli\) в PATH windows

Мой компьютер -> Свойства -> Дополнительные параметры системы -> Переменные среды -> Добавляете еще одно значение в Path

Теперь команда wp должна стать доступна как в командной строке Windows, так и в Git-bash.

Что полезного в wp-cli?

Можно начать с таких команд:

Просто wp выведет на экран справку

wp --info
OS:     Windows NT 10.0 build 19044 (Windows 10) AMD64
Shell:  C:\WINDOWS\system32\cmd.exe
PHP binary:     C:\OSPanel\modules\php\PHP_7.3-x64\php.exe
PHP version:    7.3.9
php.ini used:   C:\OSPanel\modules\php\PHP_7.3-x64\php.ini
MySQL binary:
MySQL version:
SQL modes:
WP-CLI root dir:        phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:      phar://wp-cli.phar/vendor
WP_CLI phar path:       C:\OpenServer\domains\mad-dog.loc\public
WP-CLI packages dir:
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 2.6.0

wp option get *option name*

вернет значение опции

wp option get home

wp option update *option name* *значение*

обновит значение опции

wp option update home https://mad-dog.ru

wp core download --local="ru_RU"

Установит русскоязычную версию WordPress.

wp config create --dbname="имя БД" --dbuser="имя пользователя БД" --dbpass="пароль к БД"

Создаст wp-config.php

wp core install --url=mad-dog.ru --title="Web-developer Blog" --admin_user=admin --admin_password=123

Устновит WordPress на хостинг

wp plugin install *plugin name*

Можно набирать по имени плагина

wp plugin list

Выведет список плагинов

wp plugin list

wp plugin activate *plugin-name*

Сработает если имя плагина взять в том виде, в котором выводит wp plugin list

wp-cli Error: ошибка соединения с базой данных

После того как я установил wp-cli, при попытке создать wp-config.php через консоль, я столкнулся с такой проблемой:

Error: ошибка соединения с базой данных

Сразу скажу, что эта проблема возникает на MySQL 8.0 и чтобы ее решить, мне в итоге пришлось откатиться на MySQL 5.7

Я быстро пришел к выводу, что проблема в том, что база данных требует наличия ssl сертификата для соединения. Из консоли я мог подключиться только командой с отключеным сертификатом

mysql -h localhost -u *username* -p *password* --ssl-mode=DISABLED

Так как дело происходило под OpenServer, то я первым делом полез в конфиг, чтобы отключить SSL сертификаты для MySQL.

Перезагружаю сервер, вижу что сертификаты отключены. wp-cli все еще не работает, хотя я могу подключться из консоли без отключения ssl

mysql -h localhost -u *username* -p *password*

При проверке:

mysql> SHOW VARIABLES LIKE '%ssl%';

Я вижу, что have_openssl и have_ssl стоят в DISABLED

Перехожу в wp-config.php и включаю

define('WP_DEBUG', true);

Теперь в консоли я вижу больше информации

Error: `The server requested authentication method unknown to the client`
mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
mysqli_real_connect(): (HY000/2054): The server requested authentication method unknown to the client
Ошибка установки соединения с базой данных
Это значит, что либо имя пользователя и пароль в файле `wp-config.php` неверны, либо нам не удалось связаться с сервером базы данных по адресу `127.0.0.1`. Возможно, сервер недоступен.

Проверив все настройки, я пробую сделать root пользователя без пароля и wp-cli прекрасно подключается. Значит дело именно в шифровании пароля.

Немного погуглив, я понял, что такое происходит в MySQL 8 и решил, что проще вернуться на MySQL 5.7.

Что нового в ACF 6

Новый интерфейс

advanced custon fields 6 ui

WordPress Назначить шаблон для Кастомных постов в плагине

Вы можете использовать этот код в своем плагине. Для этого замените тип поста с 'product' на ваш. В конце я привожу код для регистрации нового кастомного типа постов.

add_filter( 'template_include', 'my_template' );
function my_template( $template ) {
  global $post;
  if( $post->post_type == 'products' ){
    return wp_normalize_path( WP_PLUGIN_DIR ) . '/add-pumps/custom post/single-products.php';
  }
  return $template;
}

Здесь мы назначаем для этого типа постов шаблон в файле папка_плагинов/add-pumps/custom post/single-products.php

Для примера зарегистрируем тип постов 'product', в которых я буду хранить модели насосов в каталоге.

add_action( 'init', 'products_register_post_type' );
function products_register_post_type() {
  $labels = array(
    'name' => 'Насосы',
    'singular_name' => 'Насос', // админ панель Добавить->Функцию
    'add_new' => 'Добавить насос',
    'add_new_item' => 'Добавить новый насос', // заголовок тега title
    'edit_item' => 'Редактировать насос',
    'new_item' => 'Новый насос',
    'all_items' => 'Все насосы',
    'view_item' => 'Просмотр насоса на сайте',
    'search_items' => 'Искать насосы',
    'not_found' =>  'Насосов не найдено.',
    'not_found_in_trash' => 'В корзине нет насосов.',
    'menu_name' => 'Насосы' // ссылка в меню в админке
  );
  $args = array(
    'labels' => $labels,
    'public' => true,
    'show_ui' => true, // показывать интерфейс в админке
    'has_archive' => false,
    'menu_icon' => get_stylesheet_directory_uri() .'/img/box-seam.svg', // иконка в меню
    'menu_position' => 20, // порядок в меню
    'supports' => array( 'title', 'editor', 'comments', 'author', 'thumbnail', 'excerpt', 'custom-fields', 'revisions')
  );
  register_post_type('products', $args);
}

add_filter( 'post_updated_messages', 'products_post_type_messages' );
function products_post_type_messages( $messages ) {
  global $post, $post_ID;

  $messages['products'] = array( // functions - название созданного нами типа записей
    0 => '', // Данный индекс не используется.
    1 => sprintf( 'Продукт обновлен. <a href="%s">Просмотр</a>', esc_url( get_permalink($post_ID) ) ),
    2 => 'Параметр обновлён.',
    3 => 'Параметр удалён.',
    4 => 'Продукт обновлен',
    5 => isset($_GET['revision']) ? sprintf( 'Продукт восстановлен из редакции: %s', wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    6 => sprintf( 'Продукт опубликован на сайте. <a href="%s">Просмотр</a>', esc_url( get_permalink($post_ID) ) ),
    7 => 'Продукт сохранен.',
    8 => sprintf( 'Отправлено на проверку. <a target="_blank" href="%s">Просмотр</a>', esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    9 => sprintf( 'Запланировано на публикацию: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Просмотр</a>', date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
    10 => sprintf( 'Черновик обновлён. <a target="_blank" href="%s">Просмотр</a>', esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
  );

  return $messages;
}

function post_tag_for_products(){
  register_taxonomy_for_object_type( 'post_tag', 'products');
}
add_action( 'init', 'post_tag_for_products' );

Функция esc_attr_x() — описание

Переводит строку, используя gettext контекст. Возвращает экранированную стироку.

esc_attr_x( $text, $context, $domain = 'default' );

Используется в случае, если необходимо менять перевод в зависимости от контекста. Например, значение переводить на русский в одном месте "Поиск", а в другом "Искать".

Пример из файла (woocommerce) product-searchform.php:

esc_attr_x( 'Search', 'submit button', 'woocommerce' );

Ищет перевод в файле /wp-content/languages/plugins/woocommerce-ru_RU.mo

$text(string) (required)
Текст для перевода
$context(string) (required)
Контекст (Триггер, определяющий какой из переводов использовать в данном случае, если их несколько).
$domain(string)
Опционально. Текстовый домен. Уникальный идентификатор для возврата переведенный строки. По-умолчанию 'default'.

Как получить ID страницы, установленной как главная в WordPress

В настройках WordPress можно указать какая страница будет главной. Для этого нужно перейти в меню "Внешний вид" -> "Настроить" -> "Статическая главная страница" и указать какая страница будет главной.

В некоторых случаях необходимо получить ID этой страницы. Отмечу, что это значение хранится в базе в таблице wp_options. Столбец option_name = page_on_front, а option_value = ID. Для того, чтобы получить это значение, можно воспользоваться функцией get_option( 'page_on_front' );