Как сделать 301 редирект для приватных записей вместо 404?

8 мар. 2011 г., 02:56:53
Просмотры: 4.19K
Голосов: 5

Как сделать 301 редирект для приватных страниц вместо отображения ошибки 404? Если запись приватная, WordPress исключает её из SQL-запроса, поэтому нет доступа к переменным $post.

Хотелось бы, чтобы этот код работал, но он не работает:

add_action('wp','redirect_stuffs', 0);
function redirect_stuffs(){
global $post;
    if ( $post->post_status == "private" && !is_admin() ):
        wp_redirect("http://dangayle.com/",301);
        exit();
    endif;
}

Я не знаю, где это можно установить раньше, чем в wp, кроме того факта, что это проблема с ролями пользователей. Если бы я мог дать незалогиненным пользователям соответствующую возможность, это вероятно решило бы проблему:

$publicReader -> add_cap('read_private_posts');

Проблема с add_cap в том, что только авторизованные пользователи имеют возможности.

0
Все ответы на вопрос 3
0

Извините, ребята, я нашел ответ:

add_action('wp','redirect_stuffs', 0);
function redirect_stuffs(){
global $wpdb; 
    if ($wpdb->last_result[0]->post_status == "private" && !is_admin() ):
        wp_redirect( home_url(), 301 );
        exit();
    endif;
}

Записи/страницы удаляются из карты сайта, но страница по-прежнему отображается на сайте, чтобы можно было сделать 301 редирект.

14 мар. 2011 г. 21:58:17
1

Мне кажется, вы не должны возвращать ни 404, ни 301 — вы должны возвращать либо 401 (Unauthorized / требуется аутентификация, хотя вы не будете принимать никакую предложенную аутентификацию), либо 403 (Rejected, то есть "я знаю, что вы просите, но вы этого не получите").

Есть заброшенный плагин Private Page Forbidden, который может быть полезен для изучения, хотя на первый взгляд он пытается преобразовать 404 в 403, что кажется плохой идеей. К сожалению, несмотря на различные обсуждения вариантов (см. https://core.trac.wordpress.org/ticket/10551 и связанные с ним), сроки исправлений постепенно сдвигались до "Future Release".

8 мар. 2011 г. 06:33:21
Комментарии

Я только сейчас понял, что вы имели в виду. В целом, я мог бы с вами согласиться. В конце концов, коды возврата существуют не просто так. К сожалению, в данном случае у меня нет выбора, кроме как делать 301 редирект, так как это указание свыше.

Dan Gayle Dan Gayle
14 мар. 2011 г. 15:59:00
2

Во-первых, я должен согласиться с ответом @fencepost. Однако я не смог удержаться от публикации решения, так что вот оно!

function __intercept_private_page( $posts, &$wp_query )
{
    // удаляем фильтр сейчас, чтобы при последующих запросах к постам мы не участвовали!
    remove_filter( 'the_posts', '__intercept_private_page', 5, 2 );

    if ( !( $wp_query->is_page && empty($posts) ) )
        return $posts; // выходим, если это не страница без результатов

    // если вы хотите явно проверить, что страница *является* приватной, используйте блок кода ниже:   
    /*
        if ( !empty( $wp_query->query['page_id'] ) )
            $page = get_page( $wp_query->query['page_id'] );
        else
            $page = get_page_by_path( $wp_query->query['pagename'] );

        if ( $page && $page->post_status == 'private' ) {
            // редирект
        }
    */

    // в противном случае предполагаем, что если запрос был для страницы и страница не найдена, она была приватной
    wp_redirect( home_url(), 301 );
    exit;
}
is_admin() || add_filter( 'the_posts', '__intercept_private_page', 5, 2 );

Обновление: Пересмотренный код теперь использует фильтр the_posts вместо posts_results (который срабатывает до того, как WordPress проверит права доступа, поэтому $posts ещё не был 'опустошён').

13 мар. 2011 г. 22:34:35
Комментарии

Это всё ещё возвращает 404.

Dan Gayle Dan Gayle
14 мар. 2011 г. 21:44:46

Пересмотренный ответ.

TheDeadMedic TheDeadMedic
14 мар. 2011 г. 22:35:37