WordPress.org

Make WordPress Core

Ticket #49380: 49380.diff

File 49380.diff, 10.2 KB (added by peterwilsoncc, 3 months ago)
  • src/wp-includes/post.php

    diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
    index d7f7b25652..e1997e24b8 100644
    a b function is_post_type_viewable( $post_type ) { 
    20192019                }
    20202020        }
    20212021
     2022        if ( ! is_object( $post_type ) ) {
     2023                return false;
     2024        }
     2025
    20222026        return $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
    20232027}
    20242028
     2029/**
     2030 * Determine whether a post status is considered "viewable".
     2031 *
     2032 * For built-in post statuses such as publish and private, the 'public' value will be evaluted.
     2033 * For all others, the 'publicly_queryable' value will be used.
     2034 *
     2035 * @since 5.7.0
     2036 *
     2037 * @param string|stdClass $post_status Post status name or object.
     2038 * @return bool Whether the post status should be considered viewable.
     2039 */
     2040function is_post_status_viewable( $post_status ) {
     2041        if ( is_scalar( $post_status ) ) {
     2042                $post_status = get_post_status_object( $post_status );
     2043                if ( ! $post_status ) {
     2044                        return false;
     2045                }
     2046        }
     2047
     2048        if (
     2049                ! is_object( $post_status ) ||
     2050                $post_status->internal ||
     2051                $post_status->protected
     2052        ) {
     2053                return false;
     2054        }
     2055
     2056        return $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public );
     2057}
     2058
     2059/**
     2060 * Determine whether a post is publicly viewable.
     2061 *
     2062 * Posts are considered publicly viewable if both the post status and post type
     2063 * are viewable.
     2064 *
     2065 * @since 5.7.0
     2066 *
     2067 * @param int|WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
     2068 * @return bool Whether the post is publicly viewable.
     2069 */
     2070function is_post_publicly_viewable( $post = null ) {
     2071        $post = get_post( $post );
     2072
     2073        if ( ! $post ) {
     2074                return false;
     2075        }
     2076
     2077        $post_type   = get_post_type( $post );
     2078        $post_status = get_post_status( $post );
     2079
     2080        return is_post_type_viewable( $post_type ) && is_post_status_viewable( $post_status );
     2081}
     2082
    20252083/**
    20262084 * Retrieves an array of the latest posts, or posts matching the given criteria.
    20272085 *
  • new file tests/phpunit/tests/post/isPostPubliclyViewable.php

    diff --git a/tests/phpunit/tests/post/isPostPubliclyViewable.php b/tests/phpunit/tests/post/isPostPubliclyViewable.php
    new file mode 100644
    index 0000000000..9d5d781e88
    - +  
     1<?php
     2
     3/**
     4 * @group post
     5 */
     6class Tests_Post_IsPostPubliclyViewable extends WP_UnitTestCase {
     7
     8        /**
     9         * Array of post IDs to use as parents.
     10         *
     11         * @var array
     12         */
     13        public static $parent_post_ids = array();
     14
     15        public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
     16                $post_statuses = array( 'publish', 'private', 'future', 'trash', 'delete' );
     17                foreach ( $post_statuses as $post_status ) {
     18                        $date          = '';
     19                        $actual_status = $post_status;
     20                        if ( 'future' === $post_status ) {
     21                                $date = strftime( '%Y-%m-%d %H:%M:%S', strtotime( '+1 year' ) );
     22                        } elseif ( in_array( $post_status, array( 'trash', 'delete' ), true ) ) {
     23                                $actual_status = 'publish';
     24                        }
     25
     26                        self::$parent_post_ids[ $post_status ] = $factory->post->create(
     27                                array(
     28                                        'post_status' => $actual_status,
     29                                        'post_name'   => "$post_status-post",
     30                                        'post_date'   => $date,
     31                                        'post_type'   => 'page',
     32                                )
     33                        );
     34                }
     35
     36                wp_trash_post( self::$parent_post_ids['trash'] );
     37                wp_delete_post( self::$parent_post_ids['delete'], true );
     38        }
     39
     40        /**
     41         * Unit tests for is_post_publicly_viewable().
     42         *
     43         * @dataProvider data_is_post_publicly_viewable
     44         * @ticket 49380
     45         *
     46         * @param string $post_type   The post type.
     47         * @param string $post_status The post status.
     48         * @param bool   $expected    The expected result of the function call.
     49         * @param string $parent_key  The parent key as set up in shared fixtures.
     50         */
     51        public function test_is_post_publicly_viewable( $post_type, $post_status, $expected, $parent_key = '' ) {
     52                $date = '';
     53                if ( 'future' === $post_status ) {
     54                        $date = strftime( '%Y-%m-%d %H:%M:%S', strtotime( '+1 year' ) );
     55                }
     56
     57                $post_id = $this->factory()->post->create(
     58                        array(
     59                                'post_type'   => $post_type,
     60                                'post_status' => $post_status,
     61                                'post_parent' => $parent_key ? self::$parent_post_ids[ $parent_key ] : 0,
     62                                'post_date'   => $date,
     63                        )
     64                );
     65
     66                $this->assertSame( $expected, is_post_publicly_viewable( $post_id ) );
     67        }
     68
     69        /**
     70         * Data provider for test_is_post_publicly_viewable().
     71         *
     72         * return array[] {
     73         *     @type string $post_type   The post type.
     74         *     @type string $post_status The post status.
     75         *     @type bool   $expected    The expected result of the function call.
     76         *     @type string $parent_key  The parent key as set up in shared fixtures.
     77         * }
     78         */
     79        public function data_is_post_publicly_viewable() {
     80                return array(
     81                        array( 'post', 'publish', true ),
     82                        array( 'post', 'private', false ),
     83                        array( 'post', 'future', false ),
     84
     85                        array( 'page', 'publish', true ),
     86                        array( 'page', 'private', false ),
     87                        array( 'page', 'future', false ),
     88
     89                        array( 'unregistered_cpt', 'publish', false ),
     90                        array( 'unregistered_cpt', 'private', false ),
     91
     92                        array( 'post', 'unregistered_cps', false ),
     93                        array( 'page', 'unregistered_cps', false ),
     94
     95                        array( 'attachment', 'inherit', true, 'publish' ),
     96                        array( 'attachment', 'inherit', false, 'private' ),
     97                        array( 'attachment', 'inherit', false, 'future' ),
     98                        array( 'attachment', 'inherit', true, 'trash' ),
     99                        array( 'attachment', 'inherit', true, 'delete' ),
     100
     101                        array( 'page', 'publish', true, 'publish' ),
     102                        array( 'page', 'publish', true, 'private' ),
     103                        array( 'page', 'publish', true, 'future' ),
     104                        array( 'page', 'publish', true, 'trash' ),
     105                        array( 'page', 'publish', true, 'delete' ),
     106                );
     107        }
     108}
  • new file tests/phpunit/tests/post/isPostStatusViewable.php

    diff --git a/tests/phpunit/tests/post/isPostStatusViewable.php b/tests/phpunit/tests/post/isPostStatusViewable.php
    new file mode 100644
    index 0000000000..9658ca2066
    - +  
     1<?php
     2
     3/**
     4 * @group post
     5 */
     6class Tests_Post_IsPostStatusViewable extends WP_UnitTestCase {
     7
     8        /**
     9         * Remove the test status from the global when finished.
     10         *
     11         * @global $wp_post_statuses
     12         */
     13        static function wpTearDownAfterClass() {
     14                global $wp_post_statuses;
     15                unset( $wp_post_statuses['wp_tests_ps'] );
     16        }
     17
     18        /**
     19         * Test custom post status.
     20         *
     21         * This may include emulations of built in (_builtin) statuses.
     22         *
     23         * @ticket 49380
     24         * @dataProvider data_custom_post_statuses
     25         *
     26         * @param array $cps_args Registration arguments.
     27         * @param bool  $expected Expected result.
     28         */
     29        public function test_custom_post_statuses( $cps_args, $expected ) {
     30                register_post_status(
     31                        'wp_tests_ps',
     32                        $cps_args
     33                );
     34
     35                // Test status passed as string.
     36                $this->assertSame( $expected, is_post_status_viewable( 'wp_tests_ps' ) );
     37                // Test status passed as object.
     38                $this->assertSame( $expected, is_post_status_viewable( get_post_status_object( 'wp_tests_ps' ) ) );
     39        }
     40
     41        /**
     42         * Data provider for custom post status tests.
     43         *
     44         * @return array[] {
     45         *     array CPS registration args.
     46         *     bool  Expected result.
     47         * }
     48         */
     49        public function data_custom_post_statuses() {
     50                return array(
     51                        // 0. False for non-publically queryable types.
     52                        array(
     53                                array(
     54                                        'publicly_queryable' => false,
     55                                        '_builtin'           => false,
     56                                        'public'             => true,
     57                                ),
     58                                false,
     59                        ),
     60                        // 1. True for publically queryable types.
     61                        array(
     62                                array(
     63                                        'publicly_queryable' => true,
     64                                        '_builtin'           => false,
     65                                        'public'             => false,
     66                                ),
     67                                true,
     68                        ),
     69                        // 2. False for built-in non-public types.
     70                        array(
     71                                array(
     72                                        'publicly_queryable' => false,
     73                                        '_builtin'           => true,
     74                                        'public'             => false,
     75                                ),
     76                                false,
     77                        ),
     78                        // 3. False for non-built-in public types.
     79                        array(
     80                                array(
     81                                        'publicly_queryable' => false,
     82                                        '_builtin'           => false,
     83                                        'public'             => true,
     84                                ),
     85                                false,
     86                        ),
     87                        // 4. True for built-in public types.
     88                        array(
     89                                array(
     90                                        'publicly_queryable' => false,
     91                                        '_builtin'           => true,
     92                                        'public'             => true,
     93                                ),
     94                                true,
     95                        ),
     96                );
     97        }
     98
     99        /**
     100         * Test built-in and unregistered post status.
     101         *
     102         * @dataProvider data_built_unregistered_in_status_types
     103         * @ticket 49380
     104         *
     105         * @param mixed $status   Post status to check.
     106         * @param bool  $expected Expected viewable status.
     107         */
     108        function test_built_unregistered_in_status_types( $status, $expected ) {
     109                // Test status passed as string.
     110                $this->assertSame( $expected, is_post_status_viewable( $status ) );
     111                // Test status passed as object.
     112                $this->assertSame( $expected, is_post_status_viewable( get_post_status_object( $status ) ) );
     113        }
     114
     115        /**
     116         * Data provider for built-in and unregistered post status tests.
     117         *
     118         * @return array[] {
     119         *     @type mixed $status   Post status to check.
     120         *     @type bool  $expected Expected viewable status.
     121         * }
     122         */
     123        public function data_built_unregistered_in_status_types() {
     124                return array(
     125                        array( 'publish', true ),
     126                        array( 'future', false ),
     127                        array( 'draft', false ),
     128                        array( 'pending', false ),
     129                        array( 'private', false ),
     130                        array( 'trash', false ),
     131                        array( 'auto-draft', false ),
     132                        array( 'inherit', false ),
     133                        array( 'request-pending', false ),
     134                        array( 'request-confirmed', false ),
     135                        array( 'request-failed', false ),
     136                        array( 'request-completed', false ),
     137
     138                        // Various unregistered statuses.
     139                        array( 'unregistered-status', false ),
     140                        array( false, false ),
     141                        array( true, false ),
     142                        array( 20, false ),
     143                        array( null, false ),
     144                        array( '', false ),
     145                );
     146        }
     147
     148        /**
     149         * Sanitize key should not be run when testing.
     150         *
     151         * @ticket 49380
     152         */
     153        public function test_sanitize_key_not_run() {
     154                register_post_status(
     155                        'WP_Tests_ps',
     156                        array(
     157                                'publicly_queryable' => true,
     158                                '_builtin'           => false,
     159                                'public'             => true,
     160                        )
     161                );
     162
     163                // Sanitized key should return true.
     164                $this->assertTrue( is_post_status_viewable( 'wp_tests_ps' ) );
     165                $this->assertTrue( is_post_status_viewable( get_post_status_object( 'wp_tests_ps' ) ) );
     166
     167                // Unsanitized key should return false.
     168                $this->assertFalse( is_post_status_viewable( 'WP_tests_ps' ) );
     169                $this->assertFalse( is_post_status_viewable( get_post_status_object( 'WP_tests_ps' ) ) );
     170        }
     171}