Make WordPress Core

Ticket #37782: 37782.14.diff

File 37782.14.diff, 12.7 KB (added by garrett-eclipse, 6 years ago)

Additional Cleanup as suggested by @Birgire.

  • src/wp-admin/css/nav-menus.css

     
    413413        margin-top: -4px;
    414414}
    415415
     416.menu-item-title .post-state {
     417        font-weight: 600;
     418}
     419
    416420/* Nav Menu */
    417421#menu-container .inside {
    418422        padding-bottom: 10px;
  • src/wp-admin/includes/class-walker-nav-menu-checklist.php

     
    9494                } elseif ( isset( $item->post_type ) ) {
    9595                        /** This filter is documented in wp-includes/post-template.php */
    9696                        $title = apply_filters( 'the_title', $item->post_title, $item->ID );
    97                         if ( ! empty( $item->front_or_home ) && _x( 'Home', 'nav menu home label' ) !== $title ) {
    98                                 /* translators: %s: front page title */
    99                                 $title = sprintf( _x( 'Home: %s', 'nav menu front page title' ), $title );
    100                         }
    10197                }
    10298
    10399                $output .= isset( $title ) ? esc_html( $title ) : esc_html( $item->title );
     100
     101                if ( empty( $item->label ) && isset( $item->post_type ) && 'page' === $item->post_type ) {
     102                        // Append post states.
     103                        $output .= _post_states( $item, false );
     104                }
     105
    104106                $output .= '</label>';
    105107
    106108                // Menu item hidden fields
  • src/wp-admin/includes/nav-menu.php

     
    354354                $args = array_merge( $args, (array) $box['args']->_default_query );
    355355        }
    356356
     357        /*
     358         * If we're dealing with pages, let's prioritize the Front Page,
     359         * Posts Page and Privacy Policy Page at the top of the list.
     360         */
     361        $important_pages = array();
     362        if ( 'page' == $post_type_name ) {
     363                $suppress_page_ids = array();
     364
     365                // Insert Front Page or custom Home link.
     366                $front_page = 'page' == get_option( 'show_on_front' ) ? (int) get_option( 'page_on_front' ) : 0;
     367
     368                $front_page_obj = null;
     369                if ( ! empty( $front_page ) ) {
     370                        $front_page_obj                = get_post( $front_page );
     371                        $front_page_obj->front_or_home = true;
     372
     373                        $important_pages[]   = $front_page_obj;
     374                        $suppress_page_ids[] = $front_page_obj->ID;
     375                } else {
     376                        $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval( $_nav_menu_placeholder ) - 1 : -1;
     377                        $front_page_obj        = (object) array(
     378                                'front_or_home' => true,
     379                                'ID'            => 0,
     380                                'object_id'     => $_nav_menu_placeholder,
     381                                'post_content'  => '',
     382                                'post_excerpt'  => '',
     383                                'post_parent'   => '',
     384                                'post_title'    => _x( 'Home', 'nav menu home label' ),
     385                                'post_type'     => 'nav_menu_item',
     386                                'type'          => 'custom',
     387                                'url'           => home_url( '/' ),
     388                        );
     389
     390                        $important_pages[] = $front_page_obj;
     391                }
     392
     393                // Insert Posts Page.
     394                $posts_page = 'page' == get_option( 'show_on_front' ) ? (int) get_option( 'page_for_posts' ) : 0;
     395
     396                if ( ! empty( $posts_page ) ) {
     397                        $posts_page_obj             = get_post( $posts_page );
     398                        $posts_page_obj->posts_page = true;
     399
     400                        $important_pages[]   = $posts_page_obj;
     401                        $suppress_page_ids[] = $posts_page_obj->ID;
     402                }
     403
     404                // Insert Privacy Policy Page.
     405                $privacy_policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' );
     406
     407                if ( ! empty( $privacy_policy_page_id ) ) {
     408                        $privacy_policy_page           = get_post( $privacy_policy_page_id );
     409                        if ( $privacy_policy_page instanceof WP_Post && 'publish' === $privacy_policy_page->post_status ) {
     410                                $privacy_policy_page->privacy_policy_page = true;
     411
     412                                $important_pages[]   = $privacy_policy_page;
     413                                $suppress_page_ids[] = $privacy_policy_page->ID;
     414                        }
     415                }
     416
     417                // Add suppression array to arguments for WP_Query.
     418                if ( ! empty( $suppress_page_ids ) ) {
     419                        $args['post__not_in'] = $suppress_page_ids;
     420                }
     421        }
     422
    357423        // @todo transient caching of these results with proper invalidation on updating of a post of this type
    358424        $get_posts = new WP_Query;
    359425        $posts     = $get_posts->query( $args );
     426
     427        // Only suppress and insert when more than just suppression pages available.
    360428        if ( ! $get_posts->post_count ) {
    361                 echo '<p>' . __( 'No items.' ) . '</p>';
    362                 return;
     429                if ( ! empty( $suppress_page_ids ) ) {
     430                        unset( $args['post__not_in'] );
     431                        $get_posts = new WP_Query;
     432                        $posts     = $get_posts->query( $args );
     433                } else {
     434                        echo '<p>' . __( 'No items.' ) . '</p>';
     435                        return;
     436                }
     437        } elseif ( ! empty( $important_pages ) ) {
     438                $posts = array_merge( $important_pages, $posts );
    363439        }
    364440
    365441        $num_pages = $get_posts->max_num_pages;
     
    520596                                <?php
    521597                                $args['walker'] = $walker;
    522598
    523                                 /*
    524                                  * If we're dealing with pages, let's put a checkbox for the front
    525                                  * page at the top of the list.
    526                                  */
    527                                 if ( 'page' == $post_type_name ) {
    528                                         $front_page = 'page' == get_option( 'show_on_front' ) ? (int) get_option( 'page_on_front' ) : 0;
    529                                         if ( ! empty( $front_page ) ) {
    530                                                 $front_page_obj                = get_post( $front_page );
    531                                                 $front_page_obj->front_or_home = true;
    532                                                 array_unshift( $posts, $front_page_obj );
    533                                         } else {
    534                                                 $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval( $_nav_menu_placeholder ) - 1 : -1;
    535                                                 array_unshift(
    536                                                         $posts,
    537                                                         (object) array(
    538                                                                 'front_or_home' => true,
    539                                                                 'ID'            => 0,
    540                                                                 'object_id'     => $_nav_menu_placeholder,
    541                                                                 'post_content'  => '',
    542                                                                 'post_excerpt'  => '',
    543                                                                 'post_parent'   => '',
    544                                                                 'post_title'    => _x( 'Home', 'nav menu home label' ),
    545                                                                 'post_type'     => 'nav_menu_item',
    546                                                                 'type'          => 'custom',
    547                                                                 'url'           => home_url( '/' ),
    548                                                         )
    549                                                 );
    550                                         }
    551                                 }
    552 
    553599                                $post_type = get_post_type_object( $post_type_name );
    554600
    555601                                if ( $post_type->has_archive ) {
  • src/wp-admin/includes/template.php

     
    20092009}
    20102010
    20112011/**
    2012  * @param WP_Post $post
     2012 * Function to echo or return the Post States as HTML.
     2013 *
     2014 * @since 2.8.0
     2015 *
     2016 * @param WP_Post $post The post to retrieve states for.
     2017 * @param boolean $echo Optional. Whether to echo or return the Post States as an HTML string. Default true for echo.
     2018 *
     2019 * @return string|void Post States string when echo is false.
    20132020 */
    2014 function _post_states( $post ) {
     2021function _post_states( $post, $echo = true ) {
     2022        $post_states        = get_post_states( $post );
     2023        $post_states_string = '';
     2024
     2025        if ( ! empty( $post_states ) ) {
     2026                $state_count = count( $post_states );
     2027                $i           = 0;
     2028
     2029                $post_states_string .= ' &mdash; ';
     2030                foreach ( $post_states as $state ) {
     2031                        ++$i;
     2032                        ( $i == $state_count ) ? $sep = '' : $sep = ', ';
     2033                        $post_states_string          .= "<span class='post-state'>$state$sep</span>";
     2034                }
     2035        }
     2036
     2037        if ( $echo ) {
     2038                echo $post_states_string;
     2039        }
     2040
     2041        return $post_states_string;
     2042}
     2043
     2044/**
     2045 * Function to retrieve an array of Post States from a Post.
     2046 *
     2047 * @since 5.2.0
     2048 *
     2049 * @param WP_Post $post The post to retrieve states for.
     2050 *
     2051 * @return array $post_states The array of translated post states.
     2052 *
     2053 */
     2054function get_post_states( $post ) {
    20152055        $post_states = array();
    20162056        if ( isset( $_REQUEST['post_status'] ) ) {
    20172057                $post_status = $_REQUEST['post_status'];
     
    20222062        if ( ! empty( $post->post_password ) ) {
    20232063                $post_states['protected'] = __( 'Password protected' );
    20242064        }
     2065
    20252066        if ( 'private' == $post->post_status && 'private' != $post_status ) {
    20262067                $post_states['private'] = __( 'Private' );
    20272068        }
     2069
    20282070        if ( 'draft' === $post->post_status ) {
    20292071                if ( get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) {
    20302072                        $post_states[] = __( 'Customization Draft' );
     
    20342076        } elseif ( 'trash' === $post->post_status && get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) {
    20352077                $post_states[] = __( 'Customization Draft' );
    20362078        }
     2079
    20372080        if ( 'pending' == $post->post_status && 'pending' != $post_status ) {
    20382081                $post_states['pending'] = _x( 'Pending', 'post status' );
    20392082        }
     2083
    20402084        if ( is_sticky( $post->ID ) ) {
    20412085                $post_states['sticky'] = __( 'Sticky' );
    20422086        }
     
    20682112         * @param string[] $post_states An array of post display states.
    20692113         * @param WP_Post  $post        The current post object.
    20702114         */
    2071         $post_states = apply_filters( 'display_post_states', $post_states, $post );
    2072 
    2073         if ( ! empty( $post_states ) ) {
    2074                 $state_count = count( $post_states );
    2075                 $i           = 0;
    2076                 echo ' &mdash; ';
    2077                 foreach ( $post_states as $state ) {
    2078                         ++$i;
    2079                         ( $i == $state_count ) ? $sep = '' : $sep = ', ';
    2080                         echo "<span class='post-state'>$state$sep</span>";
    2081                 }
    2082         }
    2083 
     2115        return apply_filters( 'display_post_states', $post_states, $post );
    20842116}
    20852117
    20862118/**
  • tests/phpunit/tests/menu/wpNavMenuItemPostTypeMetaBox.php

     
     1<?php
     2/**
     3 * Test cases for the `wp_nav_menu_item_post_type_meta_box()` function.
     4 *
     5 * @package WordPress
     6 * @subpackage UnitTests
     7 * @since 5.2.0
     8 */
     9
     10require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
     11
     12/**
     13 * Tests_Menu_WpNavMenuItemPostTypeMetaBox class.
     14 *
     15 * @group navmenus
     16 * @covers ::wp_nav_menu_item_post_type_meta_box()
     17 *
     18 * @since 5.2.0
     19 */
     20class Tests_Menu_WpNavMenuItemPostTypeMetaBox extends WP_UnitTestCase {
     21
     22        /**
     23         * The function should contain no items without pages.
     24         *
     25         * @ticket 37782
     26         */
     27        public function test_should_contain_no_items_without_pages() {
     28
     29                $item = apply_filters( 'nav_menu_meta_box_object', get_post_type_object( 'page' ) );
     30
     31                $box = array(
     32                        'id'       => 'add-' . $item->name,
     33                        'title'    => $item->labels->name,
     34                        'callback' => 'wp_nav_menu_item_post_type_meta_box',
     35                        'args'     => $item,
     36                );
     37
     38                $output = get_echo( 'wp_nav_menu_item_post_type_meta_box', array( null, $box ) );
     39               
     40                $this->assertContains( 'No items', $output );
     41                $this->assertSame( 0, substr_count( $output, '<li>' ) );
     42        }
     43
     44        /**
     45         * The function should include a page only once, when viewing all pages.
     46         *
     47         * @ticket 37782
     48         */
     49        public function test_should_contain_page_only_once_when_viewing_all() {
     50                $page = $this->factory()->post->create_and_get(
     51                        array(
     52                                'post_title' => 'My Test Page',
     53                                'post_type'  => 'page',
     54                        )
     55                );
     56
     57                $item = apply_filters( 'nav_menu_meta_box_object', get_post_type_object( 'page' ) );
     58
     59                $box = array(
     60                        'id'       => 'add-' . $item->name,
     61                        'title'    => $item->labels->name,
     62                        'callback' => 'wp_nav_menu_item_post_type_meta_box',
     63                        'args'     => $item,
     64                );
     65
     66                $output = get_echo( 'wp_nav_menu_item_post_type_meta_box', array( null, $box ) );
     67
     68                // Clean up.
     69                wp_delete_post( $page->ID );
     70
     71                // Extract the "View All" part.
     72                preg_match( '~<div id="page-all"[^>]*>.*?</div>~i', str_replace( "\n", '', $output ), $matches );
     73
     74                $this->assertTrue( isset( $matches[0] ) );
     75                $this->assertSame( 2, substr_count( $matches[0], '<li>' ) );
     76                $this->assertContains( sprintf( '> %s</label>', $page->post_title ), $matches[0] );
     77                $this->assertContains( '> Home</label>', $matches[0] );
     78        }
     79
     80        /**
     81         * The function should include the front page only once, when viewing all pages.
     82         *
     83         * @ticket 37782
     84         */
     85        public function test_should_contain_front_page_only_once_when_viewing_all() {
     86                $page = $this->factory()->post->create_and_get(
     87                        array(
     88                                'post_title' => 'My Test Page',
     89                                'post_type'  => 'page',
     90                        )
     91                );
     92
     93                $item = apply_filters( 'nav_menu_meta_box_object', get_post_type_object( 'page' ) );
     94
     95                $box = array(
     96                        'id'       => 'add-' . $item->name,
     97                        'title'    => $item->labels->name,
     98                        'callback' => 'wp_nav_menu_item_post_type_meta_box',
     99                        'args'     => $item,
     100                );
     101
     102                // Front page setup.
     103                update_option( 'show_on_front', 'page' );
     104                update_option( 'page_on_front', $page->ID );
     105
     106                $output = get_echo( 'wp_nav_menu_item_post_type_meta_box', array( null, $box ) );
     107
     108                // Clean up.
     109                delete_option( 'show_on_front' );
     110                delete_option( 'page_on_front' );
     111                wp_delete_post( $page->ID );
     112
     113                // Extract the "View All" part.
     114                preg_match( '~<div id="page-all"[^>]*>.*?</div>~i', str_replace( "\n", '', $output ), $matches );
     115
     116                $this->assertTrue( isset( $matches[0] ) );
     117                $this->assertSame( 1, substr_count( $matches[0], '<li>' ) );
     118                $this->assertContains( sprintf( "> %s &mdash; <span class='post-state'>Front Page</span></label>", $page->post_title ), $matches[0] );
     119                $this->assertNotContains( sprintf( "> %s</label>", $page->post_title ), $matches[0] );
     120        }
     121}