Making WordPress.org

Changeset 6084


Ignore:
Timestamp:
11/07/2017 10:33:38 PM (7 years ago)
Author:
coffee2code
Message:

Handbook plugin: Fix post navigation when using widget.

  • Use parent page as first child's 'previous' adjacent page.
  • Use page's first child as its 'next' adjacent page.
  • For last leaf node, recursively check ancestors for their 'next' sibling.
  • Fix to properly order by menu_order then by post_title, when ordering by menu_order.
  • Fix navigation for pages with lots of siblings.
  • Enable navigation to work to/from/on private pages.

See #2871.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/navigation.php

    r2566 r6084  
    4949     */
    5050    public static function show_nav_links( $menu_name = 'Table of Contents' ) {
     51        $prev = $next = false;
     52
    5153        if ( self::$using_pages_widget ) {
    52             self::navigate_via_handbook_pages_widget();
     54            $adjacent = self::get_adjacent_posts_via_handbook_pages_widget();
    5355        } else {
    54             self::navigate_via_menu( $menu_name );
    55         }
     56            $adjacent = self::get_adjacent_posts_via_menu( $menu_name );
     57        }
     58
     59        if ( is_array( $adjacent ) ) {
     60            list( $prev, $next ) = $adjacent;
     61        }
     62
     63        self::output_navigation( $prev, $next );
    5664    }
    5765
     
    6169     *
    6270     * @access protected
    63      */
    64     protected static function navigate_via_handbook_pages_widget() {
     71     *
     72     * @param int|WP_Post $post        Optional. The post object or ID. Default is
     73     *                                 global post.
     74     * @param string      $type        Optional. The type of adjacent post(s) to
     75     *                                 return. One of 'prev', 'next', or 'both'.
     76     *                                 Default 'both'.
     77     * @param int|WP_Post $source_post Optional. The post requesting an adjacent
     78     *                                 post, if not $post itself. Default ''.
     79     * @return null|array {
     80     *    The previous and next post.
     81     *
     82     *    @type false|object $prev Object containing 'title' and 'url' for previous post.
     83     *    @type false|object $prev Object containing 'title' and 'url' for next post.
     84     * }
     85     */
     86    protected static function get_adjacent_posts_via_handbook_pages_widget( $post = '', $type = 'both', $source_post = '' ) {
    6587        // Get current post.
    66         if ( ! $post = get_post() ) {
     88        if ( ! $post = get_post( $post ) ) {
    6789            return;
    6890        }
    6991
    7092        // Bail unless a handbook page.
    71         if ( ! in_array( get_post_type(), WPorg_Handbook_Init::get_post_types() ) ) {
    72             return;
     93        if ( ! wporg_is_handbook_post_type( get_post_type( $post ) ) ) {
     94            return;
     95        }
     96
     97        // Determine which adjacent post(s) to find.
     98        if ( in_array( $type, array( 'prev', 'next' ) ) ) {
     99            if ( 'prev' === $type ) {
     100                $get_prev = true;
     101                $get_next = false;
     102            } else {
     103                $get_prev = false;
     104                $get_next = true;
     105            }
     106        } else {
     107            $get_prev = $get_next = true;
    73108        }
    74109
     
    86121
    87122        // Cache key format is pages:{post type}:{sort column}(:{excluded})?.
    88         $cache_key = 'pages:' . get_post_type() . ':' . $sort_column;
     123        $cache_key = 'pages:' . get_post_type( $post ) . ':' . $sort_column;
    89124        if ( $exclude ) {
    90125            $cache_key .= ':' . str_replace( ' ', '', $exclude );
    91126        }
    92127        $cache_group = 'wporg_handbook:' . get_current_blog_id();
     128
     129        $post_status = array( 'publish' );
     130        if ( current_user_can( get_post_type_object( get_post_type( $post ) )->cap->read_private_posts ) ) {
     131            $post_status[] = 'private';
     132        }
    93133
    94134        // Get the hierarchically and menu_order ordered list of handbook pages.
     
    96136        if ( false === $handbook_pages ) {
    97137            if ( 'menu_order' === $sort_column ) {
    98                 $sort_column = 'menu_order, post_title';
    99             }
    100 
    101             $handbook_pages = get_pages( array(
    102                 'echo'        => 0,
    103                 'exclude'     => $exclude,
    104                 'post_type'   => get_post_type(),
    105                 'sort_column' => $sort_column,
    106                 'sort_order'  => 'asc',
     138                $sort_column = array( 'menu_order' => 'ASC', 'post_title' => 'ASC' );
     139            }
     140
     141            $parent_id = wp_get_post_parent_id( $post );
     142
     143            $handbook_pages = get_posts( array(
     144                'exclude'        => $exclude,
     145                'post_parent'    => $parent_id,
     146                'post_status'    => $post_status,
     147                'post_type'      => get_post_type( $post ),
     148                'orderby'        => $sort_column,
     149                'order'          => 'ASC',
     150                'posts_per_page' => -1,
    107151            ) );
    108152
     
    112156        }
    113157
     158        $prev = $next = false;
     159
    114160        // Determine the previous and next handbook pages.
    115161        if ( $handbook_pages ) {
    116             $current_page  = wp_list_filter( $handbook_pages, array( 'ID' => get_the_ID() ) );
     162            $current_page  = wp_list_filter( $handbook_pages, array( 'ID' => $post->ID ) );
    117163            $current_index = array_keys( $current_page );
    118164
    119             if ( $current_index ) {
     165            if ( false !== $current_index ) {
    120166                $current_index = $current_index[0];
    121167                $current_page  = $current_page[ $current_index ];
    122168
    123                 $prev = $next = false;
    124 
    125                 if ( array_key_exists( $current_index - 1, $handbook_pages ) ) {
     169                // The previous post is the post's immediate sibling.
     170                // It's debatable if it should be the last leaf node of the previous
     171                // sibling's last child (since if you are on that leaf node, the next
     172                // post is the current post). That's what the custom menu-based
     173                // navigation does, but it is easier to do there than here.
     174                if ( $get_prev && array_key_exists( $current_index - 1, $handbook_pages ) ) {
    126175                    $prev = $handbook_pages[ $current_index - 1 ];
    127176                    $prev = (object) array(
    128177                        'url'   => get_the_permalink( $prev->ID ),
    129                         'title' => get_the_title( $prev->ID )
     178                        'title' => get_the_title( $prev->ID ),
    130179                    );
    131180                }
    132181
    133                 if ( array_key_exists( $current_index + 1, $handbook_pages ) ) {
     182                // If no previous yet, then it's the parent, if there is one.
     183                if ( $get_prev && ! $prev && $parent_id ) {
     184                    $prev = (object) array(
     185                        'url'   => get_the_permalink( $parent_id ),
     186                        'title' => get_the_title( $parent_id ),
     187                    );
     188                }
     189
     190                // The next post may be this post's first child.
     191                if ( $get_next && ! $source_post ) {
     192                    $children = get_posts( array(
     193                        'exclude'        => $exclude,
     194                        'post_parent'    => $post->ID,
     195                        'post_status'    => $post_status,
     196                        'post_type'      => get_post_type( $post ),
     197                        'orderby'        => $sort_column,
     198                        'order'          => 'ASC',
     199                        'posts_per_page' => 1,
     200                    ) );
     201                    if ( $children ) {
     202                        $next = (object) array(
     203                            'url'   => get_the_permalink( $children[0]->ID ),
     204                            'title' => get_the_title( $children[0]->ID ),
     205                        );
     206                    }
     207                }
     208
     209                // If no next yet, get next sibling.
     210                if ( $get_next && ! $next && array_key_exists( $current_index + 1, $handbook_pages ) ) {
    134211                    $next = $handbook_pages[ $current_index + 1 ];
    135212                    $next = (object) array(
    136213                        'url'   => get_the_permalink( $next->ID ),
    137                         'title' => get_the_title( $next->ID )
     214                        'title' => get_the_title( $next->ID ),
    138215                    );
    139216                }
    140217
    141                 self::output_navigation( $prev, $next );
    142             }
    143         }
     218                // If no next yet, recursively check for a next ancestor.
     219                if ( $get_next && ! $next && $parent_id ) {
     220                    $parent_next = self::get_adjacent_posts_via_handbook_pages_widget( $parent_id, 'next', $post->ID );
     221                    if ( is_array( $parent_next ) ) {
     222                        $next = $parent_next[1];
     223                    }
     224                }
     225
     226            }
     227        }
     228
     229        return array( $prev, $next );
    144230    }
    145231
     
    151237     *
    152238     * @param string $menu_name The name of the menu to use for nav ordering.
    153      */
    154     protected static function navigate_via_menu( $menu_name ) {
     239     * @param int|WP_Post $post Optional. The post object or ID. Default is global
     240     *                          post.
     241     * @return null|array {
     242     *    The previous and next post.
     243     *
     244     *    @type false|object $prev Object containing 'title' and 'url' for previous post.
     245     *    @type false|object $prev Object containing 'title' and 'url' for next post.
     246     * }
     247     */
     248    protected static function get_adjacent_posts_via_menu( $menu_name, $post = '' ) {
    155249        // Get current post.
    156         if ( ! $post = get_post() ) {
     250        if ( ! $post = get_post( $post ) ) {
    157251            return;
    158252        }
     
    172266        }
    173267
    174         // Find the previous post (note: preview menu item may not be a post).
     268        // Find the previous post (note: previous menu item may not be a post).
    175269        $previous = null;
    176270        for ( $n = $i-1; $n >= 0; $n-- ) {
     
    191285        }
    192286
    193         self::output_navigation( $previous, $next );
     287        return array( $previous, $next );
    194288    }
    195289
     
    240334
    241335WPorg_Handbook_Navigation::init();
    242 
Note: See TracChangeset for help on using the changeset viewer.