| | 4726 | |
| | 4727 | /** |
| | 4728 | * Resolves numeric slugs that collide with date permalinks. |
| | 4729 | * |
| | 4730 | * @since 4.2.0 |
| | 4731 | * @uses $wp_query |
| | 4732 | * |
| | 4733 | * @param object $query The WP_Query instance. |
| | 4734 | */ |
| | 4735 | function wp_resolve_numeric_slugs( $query ) { |
| | 4736 | |
| | 4737 | // Only attempt to resolve date queries for non administrative requests |
| | 4738 | if ( ! is_admin() && $query->is_date() ) { |
| | 4739 | |
| | 4740 | // Setup tokens |
| | 4741 | preg_match_all( '/%.+?%/', get_option( 'permalink_structure' ), $tokens ); |
| | 4742 | $token_index = 1; |
| | 4743 | |
| | 4744 | // Loop over the offending permalink structures and attempt to resolve them. |
| | 4745 | foreach ( (array) $tokens[0] as $token ) { |
| | 4746 | |
| | 4747 | // Only resolve the '%postname%' token |
| | 4748 | if ( '%postname%' == $token ) { |
| | 4749 | |
| | 4750 | // Boolean check for date tokens |
| | 4751 | $date_tokens = count( array_intersect( $tokens[0], array( '%year%', '%monthnum%', '%day%' ) ) ) > 0; |
| | 4752 | |
| | 4753 | /** |
| | 4754 | * Filter the post types that should resolve numeric slug date collisions. |
| | 4755 | * |
| | 4756 | * @since 4.2.0 |
| | 4757 | * |
| | 4758 | * @param string|array $post_type Post type or array of post types. Default 'post'. |
| | 4759 | */ |
| | 4760 | $post_type = apply_filters( 'wp_resolve_numeric_slugs', 'post' ); |
| | 4761 | |
| | 4762 | // Resolve '%day%' segment for '%monthnum%' |
| | 4763 | if ( $date_tokens && $token_index == 3 && $tokens[0][1] == '%monthnum%' ) { |
| | 4764 | |
| | 4765 | _wp_resolve_numeric_slug( $query, array( 'var' => 'day', 'condition' => 'is_day', 'post_type' => $post_type ) ); |
| | 4766 | |
| | 4767 | // Resolve '%monthnum%' segment for '%year%' |
| | 4768 | } else if ( $date_tokens && $token_index == 2 && $tokens[0][0] == '%year%' ) { |
| | 4769 | |
| | 4770 | _wp_resolve_numeric_slug( $query, array( 'var' => 'monthnum', 'condition' => 'is_month', 'post_type' => $post_type ) ); |
| | 4771 | |
| | 4772 | // Resolve the lone '%postname%' |
| | 4773 | } else if ( $token_index == 1 ) { |
| | 4774 | |
| | 4775 | _wp_resolve_numeric_slug( $query, array( 'post_type' => $post_type ) ); |
| | 4776 | |
| | 4777 | } |
| | 4778 | |
| | 4779 | } |
| | 4780 | |
| | 4781 | $token_index++; |
| | 4782 | |
| | 4783 | } |
| | 4784 | |
| | 4785 | } |
| | 4786 | |
| | 4787 | } |
| | 4788 | |
| | 4789 | /** |
| | 4790 | * Helper function to resolve specific numeric slug segments that collide with date permalinks. |
| | 4791 | * |
| | 4792 | * @since 4.2.0 |
| | 4793 | * @access private |
| | 4794 | * @uses $wp_query |
| | 4795 | * |
| | 4796 | * @param object $query The WP_Query instance. |
| | 4797 | * @param array $args { |
| | 4798 | * Optional. Array of query arguments. |
| | 4799 | * |
| | 4800 | * @type string $var The variable key to retrieve. Default 'year'. |
| | 4801 | * @type string $condition The query condition that should return false. Default 'is_year'. |
| | 4802 | * @type string|array $post_type Post type or array of post types. Default 'post'. |
| | 4803 | * } |
| | 4804 | */ |
| | 4805 | function _wp_resolve_numeric_slug( $query, $args = array() ) { |
| | 4806 | |
| | 4807 | // Defaults |
| | 4808 | $defaults = array( |
| | 4809 | 'var' => 'year', |
| | 4810 | 'condition' => 'is_year', |
| | 4811 | 'post_type' => 'post' |
| | 4812 | ); |
| | 4813 | |
| | 4814 | $args = wp_parse_args( $args, $defaults ); |
| | 4815 | extract( $args, EXTR_SKIP ); |
| | 4816 | |
| | 4817 | // Supported query vars |
| | 4818 | $supported = array( 'year', 'monthnum', 'day' ); |
| | 4819 | |
| | 4820 | /* |
| | 4821 | * If we have a WP_Query object and our condition is true or the var is supported, |
| | 4822 | * attempt to resolve the slug. |
| | 4823 | */ |
| | 4824 | if ( is_object( $query ) && is_a( $query, 'WP_Query' ) && ( $query->$condition() || in_array( $var, $supported ) ) ) { |
| | 4825 | |
| | 4826 | // Get the query var |
| | 4827 | $get = $query->get( $var ); |
| | 4828 | |
| | 4829 | // Maybe add a leading zero |
| | 4830 | if ( 'year' != $var ) { |
| | 4831 | $get = zeroise( $get, 2 ); |
| | 4832 | } |
| | 4833 | |
| | 4834 | // Look for a post using the numeric slug |
| | 4835 | $post = get_page_by_path( $get, OBJECT, 'post' ); |
| | 4836 | |
| | 4837 | // Didn't find a post so treat the slug var as an ID for posts without titles. |
| | 4838 | if ( null == $post ) { |
| | 4839 | $no_title_post = get_post( $get ); |
| | 4840 | if ( isset( $no_title_post->post_title ) && '' === $no_title_post->post_title ) { |
| | 4841 | $post = $no_title_post; |
| | 4842 | } |
| | 4843 | } |
| | 4844 | |
| | 4845 | // Check that we found a WP_Post object. |
| | 4846 | if ( is_object( $post ) && is_a( $post, 'WP_Post' ) ) { |
| | 4847 | |
| | 4848 | // Set the resolve flag |
| | 4849 | $resolve = true; |
| | 4850 | |
| | 4851 | // Set the page number search needle |
| | 4852 | $needle = '<!--nextpage-->'; |
| | 4853 | |
| | 4854 | // Set the page number search haystack |
| | 4855 | $haystack = $post->post_content; |
| | 4856 | |
| | 4857 | // Set page number args for years |
| | 4858 | if ( 'year' == $var ) { |
| | 4859 | |
| | 4860 | $page_args = array( 'var' => 'monthnum', 'condition' => 'is_month' ); |
| | 4861 | |
| | 4862 | // Set page number args for months |
| | 4863 | } else if ( 'monthnum' == $var ) { |
| | 4864 | |
| | 4865 | $page_args = array( 'var' => 'day', 'condition' => 'is_day' ); |
| | 4866 | |
| | 4867 | } |
| | 4868 | |
| | 4869 | // Attempt to resolve page numbers |
| | 4870 | if ( ! empty( $page_args ) && false !== strpos( $haystack, $needle ) ) { |
| | 4871 | |
| | 4872 | // Get the page query var |
| | 4873 | $page = $query->get( $page_args['var'] ); |
| | 4874 | |
| | 4875 | // Has pages to resolve |
| | 4876 | if ( '' !== $page && ( $page - 1 ) <= substr_count( $haystack, $needle ) ) { |
| | 4877 | |
| | 4878 | // Unset date var |
| | 4879 | unset($query->query[$page_args['var']]); |
| | 4880 | $query->set( $page_args['var'], '' ); |
| | 4881 | |
| | 4882 | // Update page var |
| | 4883 | $query->set( 'page', "$page" ); |
| | 4884 | $query->query['page'] = "$page"; |
| | 4885 | |
| | 4886 | // Set global |
| | 4887 | $query->$page_args['condition'] = false; |
| | 4888 | |
| | 4889 | // Don't resolve none existent pages |
| | 4890 | } else { |
| | 4891 | |
| | 4892 | $resolve = false; |
| | 4893 | |
| | 4894 | } |
| | 4895 | |
| | 4896 | // Don't resolve page numbers for posts that aren't using them |
| | 4897 | } else if ( ! empty( $page_args ) && $query->get( $page_args['var'] ) && $page_args['var'] ) { |
| | 4898 | |
| | 4899 | $resolve = false; |
| | 4900 | |
| | 4901 | } |
| | 4902 | |
| | 4903 | // Highjack the query args |
| | 4904 | if ( true === $resolve ) { |
| | 4905 | |
| | 4906 | // Remove old query var |
| | 4907 | unset($query->query[$var]); |
| | 4908 | $query->set( $var, '' ); |
| | 4909 | |
| | 4910 | // Update name query var |
| | 4911 | $query->set( 'name', $get ); |
| | 4912 | $query->query['name'] = $get; |
| | 4913 | |
| | 4914 | // Set globals |
| | 4915 | $query->is_date = false; |
| | 4916 | $query->$condition = false; |
| | 4917 | $query->is_archive = false; |
| | 4918 | $query->is_single = true; |
| | 4919 | $query->is_singular = true; |
| | 4920 | |
| | 4921 | } |
| | 4922 | |
| | 4923 | } |
| | 4924 | |
| | 4925 | } |
| | 4926 | |
| | 4927 | } |