Функция перенаправления внутри шорткода
Я разрабатываю бесплатный плагин для подключения внешней системы поддержки к WordPress, чтобы иметь возможность аутентифицировать пользователей в WordPress.
Для этого в настоящее время из внешней системы пользователь отправляется на страницу входа WordPress с таким окончанием URL:
?action=freshdesk-remote-login
Мой плагин затем проверяет, вошел ли пользователь в WP, если нет - показывает форму входа, а после успешного входа перенаправляет обратно на сторонний сайт.
Перенаправление выполняется примерно так: wp_redirect( $sso_url );
Сейчас это работает хорошо, но я планирую предложить шорткод, который можно будет добавить на страницу по выбору пользователя. Когда пользователь переходит на эту страницу, если он авторизован, его следует перенаправить на сторонний сайт, если нет - то на страницу входа.
Можете ли вы предложить способ, как заставить wp_redirect работать внутри шорткода?
Как объясняет @Rarst, шорткоды обычно выполняются слишком поздно, чтобы можно было сделать перенаправление изнутри них. Обычно они выполняются на хуке the_content
, который срабатывает уже после того, как контент отправлен в браузер. Если вам нужно перенаправить на основе наличия шорткода, необходимо проверить этот шорткод до того, как любой контент покинет сервер.
function pre_process_shortcode() {
if (!is_singular()) return;
global $post;
if (!empty($post->post_content)) {
$regex = get_shortcode_regex();
preg_match_all('/'.$regex.'/',$post->post_content,$matches);
if (!empty($matches[2]) && in_array('yourshortcodeslug',$matches[2]) && is_user_logged_in()) {
// перенаправление на сторонний сайт
} else {
// форма входа или перенаправление на страницу входа
}
}
}
add_action('template_redirect','pre_process_shortcode',1);
Это "доказательство концепции". Конкретные условия, которые вам нужны, скорее всего, будут отличаться. Обратите внимание, что это довольно "тяжелый" процесс. Я бы убедился, что он выполняется только там, где это абсолютно необходимо.

Огромное спасибо. Это именно то, что я искал, идеально подходит.

Привет, я добавил несколько проверок, чтобы убедиться, что этот код выполняется только на определенной странице, однако заметил, что размещение wp_redirect внутри шорткода тоже отлично работает. Я пробовал с javascript, а также с wp_redirect( $sso_url );
, и это просто сработало.

wp_redirect
не работает внутри шорткода при обычных условиях. Я только что проверил. Если у вас это работает, значит ваша тема или плагин делают что-то похожее на то, что я предложил для реализации этого функционала.

wp_redirect()
выполняет перенаправление через HTTP-заголовки, поэтому технически она не будет (или, по крайней мере, не должна) работать после начала вывода страницы. Таким образом, вы не можете просто использовать эту функцию в шорткоде.
Однако это не означает, что вы не можете использовать шорткод для управления перенаправлением. Вы можете проверить подходящие условия (например, является ли это страницей и содержит ли страница шорткод) до начала вывода (где-то на хуке template_redirect
) и затем выполнить перенаправление.
Другой вариант — условно выводить JavaScript, который выполнит перенаправление после загрузки страницы.

Привет, я нашел это:` function pippin_login_form_shortcode( $atts, $content = null ) {
extract( shortcode_atts( array( 'redirect' => '' ), $atts ) );
if (!is_user_logged_in()) { if($redirect) { $redirect_url = $redirect; } else { $redirect_url = get_permalink(); } $form = wp_login_form(array('echo' => false, 'redirect' => $redirect_url )); } return $form; } add_shortcode('loginform', 'pippin_login_form_shortcode');` Здесь, кажется, wp_redirect помещен внутрь шорткода.

Вот ссылка http://pippinsplugins.com/wordpress-login-form-short-code/

Простое решение на JavaScript:
Шорткод:
[js_logout]
functions.php:
add_shortcode('js_logout', 'js_logout');
function js_logout() {
// перенаправление на главную
$logout_url = html_entity_decode(wp_logout_url(home_url()));
return '<p>' . __('Если автоматическое перенаправление не сработало, нажмите здесь:') . ' <a href="' . $logout_url . '">Выйти</a></p><script>window.location.href = "' . $logout_url . '";</script>';
}

Вот однострочное решение.
Добавьте это в ваш файл functions.php
:
add_action( 'template_redirect', function () {
ob_start();
} );
ob_start()
начинает буферизацию вывода, когда действия template_redirect
завершены, и ничего еще не отправлено в браузер. Это означает, что wp_redirect()
будет работать из любого места:
wp_redirect( $url );
exit;
включая использование в шорткоде. Если скрипт завершается нормально, без вызова exit, буфер автоматически сбрасывается, и вся страница отправляется в этот момент.
Дерзко... но, кажется, работает у меня.
