4064 | | $page_path = rawurlencode(urldecode($page_path)); |
4065 | | $page_path = str_replace('%2F', '/', $page_path); |
4066 | | $page_path = str_replace('%20', ' ', $page_path); |
4067 | | $parts = explode( '/', trim( $page_path, '/' ) ); |
4068 | | $parts = esc_sql( $parts ); |
4069 | | $parts = array_map( 'sanitize_title_for_query', $parts ); |
| 4063 | return get_post_by( 'path', $page_path, array( |
| 4064 | 'post_type' => $post_type, |
| 4065 | 'output' => $output, |
| 4066 | )); |
4079 | | $post_types = esc_sql( $post_types ); |
4080 | | $post_type_in_string = "'" . implode( "','", $post_types ) . "'"; |
4081 | | $sql = " |
4082 | | SELECT ID, post_name, post_parent, post_type |
4083 | | FROM $wpdb->posts |
4084 | | WHERE post_name IN ($in_string) |
4085 | | AND post_type IN ($post_type_in_string) |
4086 | | "; |
4087 | | |
4088 | | $pages = $wpdb->get_results( $sql, OBJECT_K ); |
4089 | | |
4090 | | $revparts = array_reverse( $parts ); |
4091 | | |
4092 | | $foundid = 0; |
4093 | | foreach ( (array) $pages as $page ) { |
4094 | | if ( $page->post_name == $revparts[0] ) { |
4095 | | $count = 0; |
4096 | | $p = $page; |
4097 | | while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) { |
4098 | | $count++; |
4099 | | $parent = $pages[ $p->post_parent ]; |
4100 | | if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) |
4101 | | break; |
4102 | | $p = $parent; |
4103 | | } |
4104 | | |
4105 | | if ( $p->post_parent == 0 && $count+1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) { |
4106 | | $foundid = $page->ID; |
4107 | | if ( $page->post_type == $post_type ) |
4108 | | break; |
4109 | | } |
4110 | | } |
4111 | | } |
4112 | | |
4113 | | if ( $foundid ) { |
4114 | | return get_post( $foundid, $output ); |
4115 | | } |
4116 | | } |
4117 | | |
| 5793 | } |
| 5794 | |
| 5795 | /** |
| 5796 | * Retrieves post data by a given field. |
| 5797 | * |
| 5798 | * See {@link &get_post()} for optional filter and output arguments values. |
| 5799 | * |
| 5800 | * @since 4.4.0 |
| 5801 | * |
| 5802 | * @param string $field The field to retrieve the post with. id | title | path |
| 5803 | * @param int|string $value A value for $field. A post ID, title, or path. |
| 5804 | * @param string|array $args { |
| 5805 | * Arguments to modify behavior of get_post_by(). |
| 5806 | * |
| 5807 | * @type string $post_type The post type to constrain the result by. Defaults to 'post' |
| 5808 | * @type string $output Optional. Either OBJECT, ARRAY_N, or ARRAY_A constant |
| 5809 | * @type string $filter Optional. Type of filter to apply. Accepts 'raw', 'edit', 'db', or 'display'. Default 'raw'. |
| 5810 | * @type bool $use_like Optional. If true then uses a LIKE query for post_title and post_name. Defaults to false. |
| 5811 | * } |
| 5812 | * @return WP_Post|null |
| 5813 | */ |
| 5814 | function get_post_by( $field, $value, $args = array() ) { |
| 5815 | |
| 5816 | global $wpdb; |
| 5817 | |
| 5818 | $args = wp_parse_args( $args, array( |
| 5819 | 'post_type' => 'post', |
| 5820 | 'output' => 'OBJECT', |
| 5821 | 'filter' => 'raw', |
| 5822 | 'use_like' => false, |
| 5823 | )); |
| 5824 | |
| 5825 | $post_type = $args['post_type']; |
| 5826 | |
| 5827 | switch ( $field ) { |
| 5828 | case 'id': |
| 5829 | $post = get_post( $value, $args['output'], $args['filter'] ); |
| 5830 | break; |
| 5831 | |
| 5832 | case 'title': |
| 5833 | $sql = $args['use_like'] ? 'post_title LIKE %s' : '%s=post_title'; |
| 5834 | $post = $wpdb->get_var( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE {$sql} AND %s=post_type", $value, $post_type ) ); |
| 5835 | break; |
| 5836 | |
| 5837 | case 'path': |
| 5838 | $page_path = rawurlencode( urldecode( $value ) ); |
| 5839 | $page_path = str_replace( '%2F', '/', $page_path ); |
| 5840 | $page_path = str_replace( '%20', ' ', $page_path ); |
| 5841 | $page_paths = '/' . trim( $page_path, '/' ); |
| 5842 | $leaf_path = sanitize_title( basename( $page_paths ) ); |
| 5843 | $page_paths = explode( '/', $page_paths ); |
| 5844 | $full_path = ''; |
| 5845 | foreach ( (array) $page_paths as $pathdir ) { |
| 5846 | $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title( $pathdir ); |
| 5847 | } |
| 5848 | |
| 5849 | $sql = $args['use_like'] ? 'post_name LIKE %s' : '%s=post_name'; |
| 5850 | $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID,post_name,post_parent FROM {$wpdb->posts} WHERE {$sql} AND (%s=post_type OR 'attachment'=post_type)", |
| 5851 | $leaf_path, $post_type ) ); |
| 5852 | |
| 5853 | if ( empty( $pages ) ) { |
| 5854 | $post = null; |
| 5855 | break; |
| 5856 | } |
| 5857 | |
| 5858 | foreach ( $pages as $page ) { |
| 5859 | $path = "/{$leaf_path}"; |
| 5860 | $curpage = $page; |
| 5861 | while ( 0 !== intval( $curpage->post_parent ) ) { |
| 5862 | $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID,post_name,post_parent FROM {$wpdb->posts} WHERE ID=%d and %s=post_type", $curpage->post_parent, $post_type ) ); |
| 5863 | $path = "/{$curpage->post_name}{$path}"; |
| 5864 | } |
| 5865 | |
| 5866 | if ( $path === $full_path ) { |
| 5867 | $post = get_post( $page->ID, $args['output'], $args['filter'] ); |
| 5868 | break; |
| 5869 | } |
| 5870 | } |
| 5871 | break; |
| 5872 | |
| 5873 | default: |
| 5874 | $post = null; |
| 5875 | } |
| 5876 | |
| 5877 | /* |
| 5878 | * Check to make sure that the post is what we expected. Set to null if not. |
| 5879 | */ |
| 5880 | if ( ! is_object( $post ) || ! property_exists( $post, 'post_type' ) || $post_type !== $post->post_type ) { |
| 5881 | $post = null; |
| 5882 | } |
| 5883 | |
| 5884 | return $post; |
| 5885 | |