Функция GET_PAGE_BY_PATH для получения страницы по пути │ WP 2.1.0

Функция GET_PAGE_BY_PATH() │ WP 2.1.0

Эта функция позволяет получить страницу по заданному пути.

Время выполнения — 0.000868 сек (медленно) | 50000 раз — 0.59 сек (очень быстро) | PHP 7.1.2, WP 4.7.3

Без хуков.

Возврат

Функция возвращает объект WP_Post, массив или null. Если операция прошла успешно, вы получите WP_Post (или массив); в случае неудачи — null.

Применение

get_page_by_path( $page_path, $output, $post_type );
  • $page_path (string) (обязательно) — Путь к странице.
  • $output (string) — Тип возвращаемого значения. Один из объектов: OBJECT, ARRAY_A или ARRAY_N. Они соответствуют объекту WP_Post, ассоциативному массиву или числовому массиву соответственно. По умолчанию: OBJECT.
  • $post_type (string|array) — Тип поста или массив типов постов. По умолчанию: 'page'.

Примеры использования

Пример 1: Получение страницы по её пути

Предположим, у нас есть дочерняя страница, доступная по URL example.com/parent-page/sub-page: parent-page/sub-page — это путь к странице. Теперь мы можем получить эту страницу в коде:

$page = get_page_by_path( 'parent-page/sub-page' );

// Или так
$page = get_page_by_path( '/parent-page/sub-page/' );

print_r( $page );

Важно: Если вы укажете только имя страницы, функция не в��рнёт ничего:

$page = get_page_by_path( 'sub-page' ); // > NULL

Однако, если страница не является дочерней, нужно указать только имя страницы — это "slug":

$page = get_page_by_path( 'page-name' ); // > WP_Post{ ... }

Пример 2: Использование с пользовательскими типами постов

Если у вас есть новый тип поста, то путь к такому типу поста обычно формируется по его имени. Например, если тип поста называется car, URL конкретного поста будет example.com/car/lada. Чтобы получить такой пост, нужно использовать только его короткое имя:

// Правильный вариант
$page = get_page_by_path( 'lada', OBJECT, 'car' );

// Неправильный вариант (не вернёт ничего)
$page = get_page_by_path( 'car/lada', OBJECT, 'car' );

Автоматическое добавление типа вложения

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

if ( is_array( $post_type ) ) {
    $post_types = $post_type;
} else {
    $post_types = array( $post_type, 'attachment' );
}

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

// Запрос будет: post_type IN ( 'car' )
$page = get_page_by_path( 'lada', OBJECT, ['car'] );

// Запрос будет: post_type IN ( 'car', 'attachment' )
$page = get_page_by_path( 'lada', OBJECT, 'car' );

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

Получение последней части пути

Вы можете использовать функции basename() и untrailingslashit(), чтобы получить последнюю часть пути:

$page_path = 'car/lada/';
$post_name = basename( untrailingslashit( $page_path ) );

$page = get_page_by_path( $post_name , OBJECT, 'car');

Заметки

  • Глобальный объект базы данных WordPress: $wpdb — является объектом абстракции базы данных.

Изменения

С версии 2.1.0 — внедрена функция.

Код функции GET_PAGE_BY_PATH()

Функция находится в файле wp-includes/post.php.

function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
    global $wpdb;

    $last_changed = wp_cache_get_last_changed( 'posts' );

    $hash      = md5( $page_path . serialize( $post_type ) );
    $cache_key = "get_page_by_path:$hash:$last_changed";
    $cached    = wp_cache_get( $cache_key, 'post-queries' );
    if ( false !== $cached ) {
        if ( '0' === $cached || 0 === $cached ) {
            return;
        } else {
            return get_post( $cached, $output );
        }
    }

    $page_path     = rawurlencode( urldecode( $page_path ) );
    $page_path     = str_replace( '%2F', '/', $page_path );
    $page_path     = str_replace( '%20', ' ', $page_path );
    $parts         = explode( '/', trim( $page_path, '/' ) );
    $parts         = array_map( 'sanitize_title_for_query', $parts );
    $escaped_parts = esc_sql( $parts );

    $in_string = "'" . implode( "','", $escaped_parts ) . "'";

    if ( is_array( $post_type ) ) {
        $post_types = $post_type;
    } else {
        $post_types = array( $post_type, 'attachment' );
    }

    $post_types          = esc_sql( $post_types );
    $post_type_in_string = "'" . implode( "','", $post_types ) . "'";
    $sql                 = "
        SELECT ID, post_name, post_parent, post_type
        FROM $wpdb->posts
        WHERE post_name IN ($in_string)
        AND post_type IN ($post_type_in_string)
    ";

    $pages = $wpdb->get_results( $sql, OBJECT_K );

    $revparts = array_reverse( $parts );

    $foundid = 0;
    foreach ( (array) $pages as $page ) {
        if ( $page->post_name == $revparts[0] ) {
            $count = 0;
            $p     = $page;

            while ( 0 != $p->post_parent && isset( $pages[ $p->post_parent ] ) ) {
                ++$count;
                $parent = $pages[ $p->post_parent ];
                if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) {
                    break;
                }
                $p = $parent;
            }

            if ( 0 == $p->post_parent && count( $revparts ) === $count + 1 && $p->post_name == $revparts[ $count ] ) {
                $foundid = $page->ID;
                if ( $page->post_type == $post_type ) {
                    break;
                }
            }
        }
    }

    wp_cache_set( $cache_key, $foundid, 'post-queries' );

    if ( $foundid ) {
        return get_post( $foundid, $output );
    }

    return null;
}

Связанные функции

  • get_page_by_title() — получение страницы по заголовку.
  • get_all_page_ids() — получение всех идентификаторов страниц.
  • get_page_children() — получение дочерних страниц.
  • get_page_link() — получение ссылки на страницу.
  • get_page_template_slug() — получение шаблона страницы.
  • get_page_uri() — получение URI страницы.
  • get_pages() — получение страниц.
  • get_post_ancestors() — получение предков поста.
  • page_template_dropdown() — выпадающий список шаблонов страниц.
  • parent_dropdown() — выпадающий список родительских страниц.
  • wp_dropdown_pages() — выпадающий список страниц.
  • wp_link_pages() — навигация по страницам.
  • wp_list_pages() — список страниц.
  • wp_page_menu() — меню страниц.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *