Проверка текущей страницы wp-login
Как проверить, является ли текущая страница wp-login.php
или wp-signup.php
?
Существуют ли более элегантные решения, чем использование $_SERVER['REQUEST_URI']
?

Используйте глобальную переменную $pagenow
, которая является общей глобальной переменной, устанавливаемой WordPress во время выполнения:
if ( $GLOBALS['pagenow'] === 'wp-login.php' ) {
// Мы на странице входа!
}
Вы также можете проверить тип страницы входа, например, регистрацию:
if ( $GLOBALS['pagenow'] === 'wp-login.php' && ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] === 'register' ) {
// Мы регистрируемся
}
Следующий код считается устаревшим и не должен использоваться (wp-register.php
был устаревшим и впоследствии удалён довольно давно):
if ( in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) ) )
run_my_funky_plugin();

Будет ли это работать, если пользователь изменит URL wp-login.php?

Хороший вопрос от @LucasBustamante, и я полагаю, его легко проверить. Просто очень важно отметить это, чтобы сэкономить чьё-то время.

@T.Todua предоставил более безопасный и надёжный ответ ниже.

Мой предпочтительный способ:
if( is_wplogin() ){
...
}
код:
function is_wplogin(){
$ABSPATH_MY = str_replace(array('\\','/'), DIRECTORY_SEPARATOR, ABSPATH);
return ((in_array($ABSPATH_MY.'wp-login.php', get_included_files()) || in_array($ABSPATH_MY.'wp-register.php', get_included_files()) ) || (isset($_GLOBALS['pagenow']) && $GLOBALS['pagenow'] === 'wp-login.php') || $_SERVER['PHP_SELF']== '/wp-login.php');
}
Почему это самый безопасный способ?
- Иногда, если вы попытаетесь проверить страницу входа с помощью
REQUEST_URI
(илиSCRIPT_PATH
), вы получите НЕКОРРЕКТНЫЕ ЗНАЧЕНИЯ, потому что многие плагины изменяют URL-адреса логина и админки.
2)$pagenow
также выдаст некорректное значение в этом случае!
Примечания:
- В некоторых случаях это может не работать, если вы выводите форму входа (например, через шорткод и т.д.) вручную на других шаблонах или страницах.
Обновление ядра:
Начиная с WordPress версии 6.1 (ноябрь 2022) в ядро добавлена дополнительная функция is_login
, которая проверяет wp_login_url
.

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

@RyanBayne спасибо, да, это редкий случай, когда get_included_files()
кажется наиболее точным решением (по крайней мере для меня).

У меня возвращается false, как будто это не страница wp-login... Даже $GLOBALS['pagenow'] возвращает index.php...

@trainoasis возможно, ты используешь ручную форму входа (например, через шорткод) на главной странице или что-то в этом роде?

Нет, обычный wp-login.php :) Но я использую Sage и WooCommerce, может это как-то влияет :)

В WordPress 6.1.0 появилась новая функция is_login()
, которая делает именно это.
https://developer.wordpress.org/reference/functions/is_login/

Я как раз собирался предложить это. Возможно, автору вопроса нужно разобрать результаты из wp_login_url() и сравнивать только веб-путь.

$GLOBALS['pagenow']
не работает, используйте $_SERVER['PHP_SELF']
.
if ( in_array( $_SERVER['PHP_SELF'], array( '/wp-login.php', '/wp-register.php' ) ) ){
// выполнить действие.
}
И если ваш WordPress установлен не в корневой папке веб-сайта, вам следует использовать параметры вида ВАШ_ПУТЬ_К_WP/wp-login.php
для замены элементов в массиве.

Вот более читаемая версия ответа @T.Todua. Я просто красиво отформатировал код, добавил самые дешевые проверки в начале и ранний возврат:
function isLoginPage()
{
// $_SERVER['PHP_SELF'] равен "/wp-login.php"?
if ($_SERVER['PHP_SELF'] == '/wp-login.php') {
return true;
}
// $GLOBALS['pagenow'] равен "wp-login.php"?
if (isset($GLOBALS['pagenow']) && $GLOBALS['pagenow'] === 'wp-login.php') {
return true;
}
$ABSPATH_MY = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, ABSPATH);
// Был ли wp-login.php или wp-register.php включен во время выполнения?
if (
in_array($ABSPATH_MY . 'wp-login.php', get_included_files()) ||
in_array($ABSPATH_MY . 'wp-register.php', get_included_files())
) {
return true;
}
return false;
}
Если вы хотите минимального влияния на производительность, оставьте только первые две проверки.
Также, если вы выполняете эту проверку после загрузки шаблона, можно просто использовать:
function isLogin() {
if (!did_action('wp_loaded')) {
return null;
}
return did_action('login_head');
}

Я реализовал это с использованием встроенного метода WordPress wp_login_url() следующим образом:
public static function is_wp_login() {
// Получаем путь к странице входа, удаляем закрывающий слэш и приводим к нижнему регистру
$login_path = rtrim( strtolower( parse_url( wp_login_url( '', true ), PHP_URL_PATH ) ), '/' );
// Сравниваем с текущим URL запроса (также обработанным)
return ( rtrim( strtolower( $_SERVER[ 'REQUEST_URI' ] ), '/' ) == $login_path );
}
Простое сравнение обоих путей (поскольку трудно быть абсолютно уверенным в использовании SSL, так как он может быть завершен на балансировщике нагрузки) должно быть достаточным... Однако это означает, что разработчик плагина или темы, изменяющий стандартную форму входа, должен был сделать это правильным способом...

Если вам нужно добавить код для страницы входа, вы можете использовать хук для этого
<?php add_action( 'login_head', 'login_head_add_css' );
function login_head_add_css() {
?>
<style>
body {
background-image: url('/background.png');
}
.login h1 a{
background-image: url('/logo.png');
background-size: 300px !important;
background-position: center top;
background-repeat: no-repeat;
color: #444;
height: 120px;
font-size: 20px;
font-weight: 400;
line-height: 1.3;
margin: 0 auto 25px;
padding: 0;
text-decoration: none;
width: 300px !important;
text-indent: -9999px;
outline: 0;
overflow: hidden;
display: block;
}
</style>
<?php
} ?>

В этом файле так много хуков действий. Спасибо разработчикам WordPress!
Вот список наиболее распространённых хуков в порядке их выполнения:
- login_enqueue_scripts
- login_head
- login_header
- login_init
- login_form_{$action}
- confirm_admin_email
- postpass
- logout
- lostpassword
- retrievepassword
- resetpass
- rp
- register
- login
- confirmaction
- login_form
- login_footer

Альтернативный метод:
/**
* Определяет, является ли текущая страница страницей входа.
* @return bool Возвращает true, если текущая страница - страница входа.
*/
final public static function isLoginPage(): bool
{
return function_exists('login_header');
}
Функция login_header
определена в файле wp-login.php. Мы предполагаем, что страница входа не включена, так как это отдельная страница WP, которая должна вызываться напрямую. Вероятно, одно из самых надежных решений.

Это мой предпочтительный метод, который работает с любым слагом, выбранным для страницы входа. Он также обрабатывает пользовательские формы входа, если вы решите не использовать стандартную форму входа WordPress, поскольку is_login() не будет работать, если вы не включите скрипт входа. Использует глобальную переменную $wp вместо массива $_SERVER.
global $wp;
if( trailingslashit( trailingslashit( site_url() ) . $wp->request ) !== wp_login_url() ) {
// Вы находитесь на странице входа
}

Меня интересует только страница регистрации, а не страница входа. Это может быть не нужно всем.
Для меня $GLOBALS['pagenow']
возвращает index.php
. Возможно, из-за BuddyPress или моей темы.
Поэтому я использовал:
is_page('register')
Если проверить body страницы регистрации, там также есть ID. Например, если указано page-id-4906, можно использовать так, если это работает лучше:
is_page('4906')

Всегда хорошая идея использовать нативную функцию WordPress is_login()
. Она была добавлена, начиная с версии 6.1.
Подробности можно найти здесь

Это уже упоминалось в https://wordpress.stackexchange.com/a/411320/3898 и https://wordpress.stackexchange.com/a/237285/3898. Избыточные ответы затрудняют использование сайта, поэтому я бы рекомендовал удалить этот.
