| 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'] ) ) { |
| 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 | } |